2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2020 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
19 package org.openecomp.sdc.be.components.impl;
21 import static org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR;
23 import fj.data.Either;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.List;
29 import java.util.Map.Entry;
30 import java.util.Optional;
31 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
32 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
33 import org.openecomp.sdc.be.components.impl.utils.CINodeFilterUtils;
34 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
35 import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
36 import org.openecomp.sdc.be.dao.api.ActionStatus;
37 import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
38 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
39 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
40 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
41 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
42 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
43 import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType;
44 import org.openecomp.sdc.be.model.Component;
45 import org.openecomp.sdc.be.model.ComponentInstance;
46 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
47 import org.openecomp.sdc.be.model.UploadNodeFilterInfo;
48 import org.openecomp.sdc.be.model.User;
49 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
50 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
51 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeFilterOperation;
52 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
53 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
54 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
55 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
56 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
57 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
58 import org.openecomp.sdc.be.ui.model.UIConstraint;
59 import org.openecomp.sdc.be.user.Role;
60 import org.openecomp.sdc.common.log.wrappers.Logger;
61 import org.openecomp.sdc.exception.ResponseFormat;
62 import org.springframework.beans.factory.annotation.Autowired;
64 @org.springframework.stereotype.Component("componentNodeFilterBusinessLogic")
65 public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic {
67 private static final Logger LOGGER = Logger.getLogger(ComponentNodeFilterBusinessLogic.class.getName());
68 private final NodeFilterOperation nodeFilterOperation;
69 private final NodeFilterValidator nodeFilterValidator;
72 public ComponentNodeFilterBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation,
73 final IGroupInstanceOperation groupInstanceOperation, final IGroupTypeOperation groupTypeOperation,
74 final InterfaceOperation interfaceOperation,
75 final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
76 final ArtifactsOperations artifactToscaOperation, final NodeFilterOperation nodeFilterOperation,
77 final NodeFilterValidator nodeFilterValidator) {
78 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
79 artifactToscaOperation);
80 this.nodeFilterOperation = nodeFilterOperation;
81 this.nodeFilterValidator = nodeFilterValidator;
84 public Optional<CINodeFilterDataDefinition> createNodeFilterIfNotExist(final String componentId, final String componentInstanceId,
85 final boolean shouldLock, final ComponentTypeEnum componentTypeEnum)
86 throws BusinessLogicException {
87 final Component component = getComponent(componentId);
88 final Optional<ComponentInstance> componentInstance = getComponentInstance(componentInstanceId, component);
89 Optional<CINodeFilterDataDefinition> filterDataDefinition = getCiNodeFilterDataDefinition(componentInstance);
90 if (filterDataDefinition.isPresent()) {
91 return filterDataDefinition;
93 final Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
94 boolean wasLocked = false;
97 lockComponent(component.getUniqueId(), component, "Create Node Filter on component");
100 result = nodeFilterOperation.createNodeFilter(componentId, componentInstanceId);
101 if (result.isRight()) {
102 janusGraphDao.rollback();
103 LOGGER.error(BUSINESS_PROCESS_ERROR, "Failed to Create Node filter on component with id {}", componentId);
104 throw new BusinessLogicException(componentsUtils
105 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()));
107 filterDataDefinition = Optional.ofNullable(result.left().value());
109 janusGraphDao.commit();
110 LOGGER.debug("Node filter successfully created in component {} . ", component.getSystemName());
111 } catch (final Exception e) {
112 janusGraphDao.rollback();
113 LOGGER.error(BUSINESS_PROCESS_ERROR, "Exception occurred during add Component node filter property values: {}", e.getMessage(), e);
114 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
117 unlockComponent(component.getUniqueId(), componentTypeEnum);
120 return filterDataDefinition;
123 public Optional<String> deleteNodeFilterIfExists(final String componentId, final String componentInstanceId, final boolean shouldLock,
124 final ComponentTypeEnum componentTypeEnum) throws BusinessLogicException {
125 final Component component = getComponent(componentId);
126 final Optional<CINodeFilterDataDefinition> nodeFilterDataDefinition = getCiNodeFilterDataDefinition(componentInstanceId, component);
127 if (!nodeFilterDataDefinition.isPresent()) {
128 return Optional.ofNullable(componentInstanceId);
130 final Either<String, StorageOperationStatus> result;
131 boolean wasLocked = false;
134 lockComponent(component.getUniqueId(), component, "Delete Node Filter from component");
137 result = nodeFilterOperation.deleteNodeFilter(component, componentInstanceId);
138 if (result.isRight()) {
139 LOGGER.error(BUSINESS_PROCESS_ERROR, "Failed to delete node filter in component {}. Response is {}. ", component.getName(),
140 result.right().value());
141 janusGraphDao.rollback();
142 throw new BusinessLogicException(componentsUtils
143 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()));
145 janusGraphDao.commit();
146 LOGGER.debug("Node filter successfully deleted in component {} . ", component.getSystemName());
147 } catch (final Exception e) {
148 LOGGER.error(BUSINESS_PROCESS_ERROR, "Exception occurred during delete deleting node filter: {}", e.getMessage(), e);
149 janusGraphDao.rollback();
150 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
153 unlockComponent(component.getUniqueId(), componentTypeEnum);
156 return Optional.ofNullable(result.left().value());
159 private String getComponentInstancePropertyType(Component component, String componentInstanceId, String propertyName) {
160 List<ComponentInstanceProperty> componentInstanceProperties = component.getComponentInstancesProperties().get(componentInstanceId);
161 if (!componentInstanceProperties.isEmpty()) {
162 for (ComponentInstanceProperty componentInstanceProperty : componentInstanceProperties) {
163 if (componentInstanceProperty.getName().equals(propertyName)) {
164 return componentInstanceProperty.getType();
171 public Optional<CINodeFilterDataDefinition> addNodeFilter(final String componentId, final String componentInstanceId,
172 final NodeFilterConstraintAction action, final String propertyName,
173 final String constraint, final boolean shouldLock,
174 final ComponentTypeEnum componentTypeEnum,
175 final NodeFilterConstraintType nodeFilterConstraintType, final String capabilityName)
176 throws BusinessLogicException {
177 final Component component = getComponent(componentId);
178 CINodeFilterDataDefinition nodeFilterDataDefinition = validateAndReturnNodeFilterDefinition(componentInstanceId, action, constraint,
179 component, nodeFilterConstraintType, capabilityName);
180 boolean wasLocked = false;
183 lockComponent(component.getUniqueId(), component, "Add Node Filter on Component");
186 final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition();
187 requirementNodeFilterPropertyDataDefinition.setName(propertyName);
188 requirementNodeFilterPropertyDataDefinition.setConstraints(Collections.singletonList(constraint));
189 requirementNodeFilterPropertyDataDefinition.setType(getComponentInstancePropertyType(component, componentInstanceId, propertyName));
190 final Either<CINodeFilterDataDefinition, StorageOperationStatus> result = addNewNodeFilter(componentId, componentInstanceId,
191 nodeFilterConstraintType, nodeFilterDataDefinition, requirementNodeFilterPropertyDataDefinition, capabilityName);
192 if (result.isRight()) {
193 janusGraphDao.rollback();
194 throw new BusinessLogicException(componentsUtils
195 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()));
197 nodeFilterDataDefinition = result.left().value();
199 janusGraphDao.commit();
200 LOGGER.debug("Node filter successfully created in component {} . ", component.getSystemName());
201 } catch (final Exception e) {
202 janusGraphDao.rollback();
203 LOGGER.error(BUSINESS_PROCESS_ERROR, "Exception occurred during add component node filter property values: {}", e.getMessage(), e);
204 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
207 unlockComponent(component.getUniqueId(), componentTypeEnum);
210 return Optional.ofNullable(nodeFilterDataDefinition);
213 public Optional<CINodeFilterDataDefinition> deleteNodeFilter(final String componentId, final String componentInstanceId,
214 final NodeFilterConstraintAction action, final String constraint, final int position,
215 final boolean shouldLock, final ComponentTypeEnum componentTypeEnum,
216 final NodeFilterConstraintType nodeFilterConstraintType)
217 throws BusinessLogicException {
218 final Component component = getComponent(componentId);
219 CINodeFilterDataDefinition nodeFilterDataDefinition = validateAndReturnNodeFilterDefinition(componentInstanceId, action, constraint,
220 component, nodeFilterConstraintType, "");
221 boolean wasLocked = false;
224 lockComponent(component.getUniqueId(), component, "Add Node Filter on Component");
227 final Either<CINodeFilterDataDefinition, StorageOperationStatus> result = nodeFilterOperation
228 .deleteConstraint(componentId, componentInstanceId, nodeFilterDataDefinition, position, nodeFilterConstraintType);
229 if (result.isRight()) {
230 janusGraphDao.rollback();
231 throw new BusinessLogicException(componentsUtils
232 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()));
234 nodeFilterDataDefinition = result.left().value();
236 janusGraphDao.commit();
237 LOGGER.debug("Node filter successfully deleted in component {} . ", component.getSystemName());
238 } catch (final Exception e) {
239 janusGraphDao.rollback();
240 LOGGER.error(BUSINESS_PROCESS_ERROR, "Exception occurred during delete component node filter property values: {}", e.getMessage(), e);
241 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
244 unlockComponent(component.getUniqueId(), componentTypeEnum);
247 return Optional.ofNullable(nodeFilterDataDefinition);
250 private Either<CINodeFilterDataDefinition, StorageOperationStatus> addNewNodeFilter(final String componentId, final String componentInstanceId,
251 final NodeFilterConstraintType nodeFilterConstraintType,
252 final CINodeFilterDataDefinition nodeFilterDataDefinition,
253 final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition,
254 final String capabilityName) {
255 if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) {
256 return nodeFilterOperation
257 .addNewProperty(componentId, componentInstanceId, nodeFilterDataDefinition, requirementNodeFilterPropertyDataDefinition);
259 final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition = new RequirementNodeFilterCapabilityDataDefinition();
260 requirementNodeFilterCapabilityDataDefinition.setName(capabilityName);
261 final ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> propertyDataDefinitionListDataDefinition = new ListDataDefinition<>();
262 propertyDataDefinitionListDataDefinition.getListToscaDataDefinition()
263 .addAll(Collections.singleton(requirementNodeFilterPropertyDataDefinition));
264 requirementNodeFilterCapabilityDataDefinition.setProperties(propertyDataDefinitionListDataDefinition);
265 return nodeFilterOperation
266 .addNewCapabilities(componentId, componentInstanceId, nodeFilterDataDefinition, requirementNodeFilterCapabilityDataDefinition);
269 private void unlockComponent(final String componentUniqueId, final ComponentTypeEnum componentType) {
270 graphLockOperation.unlockComponent(componentUniqueId, componentType.getNodeType());
273 public User validateUser(final String userId) {
274 final User user = userValidations.validateUserExists(userId);
275 userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
279 private Optional<ComponentInstance> getComponentInstance(final String componentInstanceId, final Component component) {
280 return component.getComponentInstanceById(componentInstanceId);
283 private Optional<CINodeFilterDataDefinition> getCiNodeFilterDataDefinition(final Optional<ComponentInstance> componentInstance) {
284 if (componentInstance.isPresent()) {
285 return Optional.ofNullable(componentInstance.get().getNodeFilter());
287 return Optional.empty();
290 private Optional<CINodeFilterDataDefinition> getCiNodeFilterDataDefinition(final String componentInstanceId, final Component component)
291 throws BusinessLogicException {
292 final Either<Boolean, ResponseFormat> response = nodeFilterValidator.validateComponentInstanceExist(component, componentInstanceId);
293 if (response.isRight()) {
294 throw new BusinessLogicException(
295 componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
297 final Optional<ComponentInstance> componentInstance = getComponentInstance(componentInstanceId, component);
298 if (componentInstance.isPresent()) {
299 return Optional.ofNullable(componentInstance.get().getNodeFilter());
301 return Optional.empty();
304 private CINodeFilterDataDefinition validateAndReturnNodeFilterDefinition(final String componentInstanceId,
305 final NodeFilterConstraintAction action, final String constraint,
306 final Component component,
307 final NodeFilterConstraintType nodeFilterConstraintType,
308 final String capabilityName)
309 throws BusinessLogicException {
310 validateNodeFilter(component, componentInstanceId, action, constraint, nodeFilterConstraintType, capabilityName);
311 final Optional<CINodeFilterDataDefinition> cINodeFilterDataDefinition = getCiNodeFilterDataDefinition(componentInstanceId, component);
312 if (!cINodeFilterDataDefinition.isPresent()) {
313 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
315 return cINodeFilterDataDefinition.get();
318 private void validateNodeFilter(final Component component, final String componentInstanceId, final NodeFilterConstraintAction action,
319 final String constraint, final NodeFilterConstraintType nodeFilterConstraintType, final String capabilityName) throws BusinessLogicException {
320 final Either<Boolean, ResponseFormat> response = nodeFilterValidator
321 .validateFilter(component, componentInstanceId, Collections.singletonList(constraint), action, nodeFilterConstraintType, capabilityName);
322 if (response.isRight()) {
323 throw new BusinessLogicException(
324 componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
328 public Optional<CINodeFilterDataDefinition> updateNodeFilter(final String componentId, final String componentInstanceId,
329 final UIConstraint uiConstraint, final ComponentTypeEnum componentTypeEnum,
330 final NodeFilterConstraintType nodeFilterConstraintType, final int index)
331 throws BusinessLogicException {
332 final Optional<CINodeFilterDataDefinition> deleteActionResponse = deleteNodeFilter(componentId, componentInstanceId,
333 NodeFilterConstraintAction.DELETE, null, index, true, componentTypeEnum, nodeFilterConstraintType);
334 if (!deleteActionResponse.isPresent()) {
335 throw new BusinessLogicException(
336 componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, "Failed to delete node filter capabilities"));
338 return addNodeFilter(componentId.toLowerCase(), componentInstanceId, NodeFilterConstraintAction.ADD, uiConstraint.getServicePropertyName(),
339 new ConstraintConvertor().convert(uiConstraint), true, componentTypeEnum, nodeFilterConstraintType,
340 uiConstraint.getCapabilityName());
343 public StorageOperationStatus associateNodeFilterToComponentInstance(final String componentId,
344 final Map<String, UploadNodeFilterInfo> instNodeFilter) {
345 for (Entry<String, UploadNodeFilterInfo> filter : instNodeFilter.entrySet()) {
346 String componentInstanceId = filter.getKey();
347 CINodeFilterDataDefinition ciNodeFilterDataDefinition = new CINodeFilterUtils()
348 .getNodeFilterDataDefinition(filter.getValue(), componentInstanceId);
349 Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilter = nodeFilterOperation.createNodeFilter(componentId,
350 componentInstanceId);
351 if (nodeFilter.isRight()) {
352 LOGGER.error(BUSINESS_PROCESS_ERROR, "Failed to Create Node filter on component instance with id {}",
354 return nodeFilter.right().value();
357 //associate node filter properties to component instance
358 List<RequirementNodeFilterPropertyDataDefinition> properties = ciNodeFilterDataDefinition.getProperties()
359 .getListToscaDataDefinition();
360 if (!properties.isEmpty()) {
361 properties.forEach(property -> {
362 RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition =
363 getRequirementNodeFilterPropertyDataDefinition(property);
364 Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilterProperty = nodeFilterOperation
365 .addNewProperty(componentId, componentInstanceId, nodeFilter.left().value(), requirementNodeFilterPropertyDataDefinition);
366 if (nodeFilterProperty.isRight()) {
367 throw new ComponentException(
368 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nodeFilterProperty.right().value()),
369 componentInstanceId));
374 //associate node filter capabilities to component instance
375 List<RequirementNodeFilterCapabilityDataDefinition> capabilities = ciNodeFilterDataDefinition.getCapabilities()
376 .getListToscaDataDefinition();
377 if (!capabilities.isEmpty()) {
378 capabilities.forEach(capability -> {
379 RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition =
380 new RequirementNodeFilterCapabilityDataDefinition();
381 requirementNodeFilterCapabilityDataDefinition.setName(capability.getName());
382 requirementNodeFilterCapabilityDataDefinition.setProperties(getProperties(capability.getProperties()));
383 Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilterCapability = nodeFilterOperation
384 .addNewCapabilities(componentId, componentInstanceId, nodeFilter.left().value(),
385 requirementNodeFilterCapabilityDataDefinition);
386 if (nodeFilterCapability.isRight()) {
387 throw new ComponentException(
388 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nodeFilterCapability.right().value()),
389 componentInstanceId));
394 return StorageOperationStatus.OK;
397 private List<String> getNodeFilterConstraints(String name, List<String> value) {
398 List<String> constraints = new ArrayList<>();
399 String values = value.get(0).split("\n")[0];
400 constraints.add(name + ": {" + values + "}");
404 private ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> getProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties) {
405 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> updatedProperties = new ListDataDefinition<>();
406 properties.getListToscaDataDefinition().forEach(property -> {
407 RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = getRequirementNodeFilterPropertyDataDefinition(
409 updatedProperties.add(requirementNodeFilterPropertyDataDefinition);
411 return updatedProperties;
414 private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(
415 RequirementNodeFilterPropertyDataDefinition property) {
416 RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition();
417 requirementNodeFilterPropertyDataDefinition.setName(property.getName());
418 requirementNodeFilterPropertyDataDefinition.setConstraints(getNodeFilterConstraints(property.getName(), property.getConstraints()));
419 return requirementNodeFilterPropertyDataDefinition;