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.apache.commons.lang3.StringUtils;
32 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
33 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
34 import org.openecomp.sdc.be.components.impl.utils.CINodeFilterUtils;
35 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
36 import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
37 import org.openecomp.sdc.be.dao.api.ActionStatus;
38 import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
39 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
40 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
41 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
42 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
43 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
44 import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType;
45 import org.openecomp.sdc.be.model.Component;
46 import org.openecomp.sdc.be.model.ComponentInstance;
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 public Optional<CINodeFilterDataDefinition> addNodeFilter(final String componentId, final String componentInstanceId,
160 final NodeFilterConstraintAction action, final String propertyName,
161 final String constraint, final boolean shouldLock,
162 final ComponentTypeEnum componentTypeEnum,
163 final NodeFilterConstraintType nodeFilterConstraintType, final String capabilityName)
164 throws BusinessLogicException {
165 final Component component = getComponent(componentId);
166 CINodeFilterDataDefinition nodeFilterDataDefinition = validateAndReturnNodeFilterDefinition(componentInstanceId, action, constraint,
167 component, nodeFilterConstraintType);
168 boolean wasLocked = false;
171 lockComponent(component.getUniqueId(), component, "Add Node Filter on Component");
174 final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition();
175 requirementNodeFilterPropertyDataDefinition.setName(propertyName);
176 requirementNodeFilterPropertyDataDefinition.setConstraints(Collections.singletonList(constraint));
177 final Either<CINodeFilterDataDefinition, StorageOperationStatus> result = addNewNodeFilter(componentId, componentInstanceId,
178 nodeFilterConstraintType, nodeFilterDataDefinition, requirementNodeFilterPropertyDataDefinition, capabilityName);
179 if (result.isRight()) {
180 janusGraphDao.rollback();
181 throw new BusinessLogicException(componentsUtils
182 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()));
184 nodeFilterDataDefinition = result.left().value();
186 janusGraphDao.commit();
187 LOGGER.debug("Node filter successfully created in component {} . ", component.getSystemName());
188 } catch (final Exception e) {
189 janusGraphDao.rollback();
190 LOGGER.error(BUSINESS_PROCESS_ERROR, "Exception occurred during add component node filter property values: {}", e.getMessage(), e);
191 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
194 unlockComponent(component.getUniqueId(), componentTypeEnum);
197 return Optional.ofNullable(nodeFilterDataDefinition);
200 public Optional<CINodeFilterDataDefinition> deleteNodeFilter(final String componentId, final String componentInstanceId,
201 final NodeFilterConstraintAction action, final String constraint, final int position,
202 final boolean shouldLock, final ComponentTypeEnum componentTypeEnum,
203 final NodeFilterConstraintType nodeFilterConstraintType)
204 throws BusinessLogicException {
205 final Component component = getComponent(componentId);
206 CINodeFilterDataDefinition nodeFilterDataDefinition = validateAndReturnNodeFilterDefinition(componentInstanceId, action, constraint,
207 component, nodeFilterConstraintType);
208 boolean wasLocked = false;
211 lockComponent(component.getUniqueId(), component, "Add Node Filter on Component");
214 final Either<CINodeFilterDataDefinition, StorageOperationStatus> result = nodeFilterOperation
215 .deleteConstraint(componentId, componentInstanceId, nodeFilterDataDefinition, position, nodeFilterConstraintType);
216 if (result.isRight()) {
217 janusGraphDao.rollback();
218 throw new BusinessLogicException(componentsUtils
219 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()));
221 nodeFilterDataDefinition = result.left().value();
223 janusGraphDao.commit();
224 LOGGER.debug("Node filter successfully deleted in component {} . ", component.getSystemName());
225 } catch (final Exception e) {
226 janusGraphDao.rollback();
227 LOGGER.error(BUSINESS_PROCESS_ERROR, "Exception occurred during delete component node filter property values: {}", e.getMessage(), e);
228 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
231 unlockComponent(component.getUniqueId(), componentTypeEnum);
234 return Optional.ofNullable(nodeFilterDataDefinition);
237 private Either<CINodeFilterDataDefinition, StorageOperationStatus> addNewNodeFilter(final String componentId, final String componentInstanceId,
238 final NodeFilterConstraintType nodeFilterConstraintType,
239 final CINodeFilterDataDefinition nodeFilterDataDefinition,
240 final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition,
241 final String capabilityName) {
242 if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) {
243 return nodeFilterOperation
244 .addNewProperty(componentId, componentInstanceId, nodeFilterDataDefinition, requirementNodeFilterPropertyDataDefinition);
246 final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition = new RequirementNodeFilterCapabilityDataDefinition();
247 requirementNodeFilterCapabilityDataDefinition.setName(capabilityName);
248 final ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> propertyDataDefinitionListDataDefinition = new ListDataDefinition<>();
249 propertyDataDefinitionListDataDefinition.getListToscaDataDefinition()
250 .addAll(Collections.singleton(requirementNodeFilterPropertyDataDefinition));
251 requirementNodeFilterCapabilityDataDefinition.setProperties(propertyDataDefinitionListDataDefinition);
252 return nodeFilterOperation
253 .addNewCapabilities(componentId, componentInstanceId, nodeFilterDataDefinition, requirementNodeFilterCapabilityDataDefinition);
256 private void unlockComponent(final String componentUniqueId, final ComponentTypeEnum componentType) {
257 graphLockOperation.unlockComponent(componentUniqueId, componentType.getNodeType());
260 public User validateUser(final String userId) {
261 final User user = userValidations.validateUserExists(userId);
262 userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
266 private Optional<ComponentInstance> getComponentInstance(final String componentInstanceId, final Component component) {
267 return component.getComponentInstanceById(componentInstanceId);
270 private Optional<CINodeFilterDataDefinition> getCiNodeFilterDataDefinition(final Optional<ComponentInstance> componentInstance) {
271 if (componentInstance.isPresent()) {
272 return Optional.ofNullable(componentInstance.get().getNodeFilter());
274 return Optional.empty();
277 private Optional<CINodeFilterDataDefinition> getCiNodeFilterDataDefinition(final String componentInstanceId, final Component component)
278 throws BusinessLogicException {
279 final Either<Boolean, ResponseFormat> response = nodeFilterValidator.validateComponentInstanceExist(component, componentInstanceId);
280 if (response.isRight()) {
281 throw new BusinessLogicException(
282 componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
284 final Optional<ComponentInstance> componentInstance = getComponentInstance(componentInstanceId, component);
285 if (componentInstance.isPresent()) {
286 return Optional.ofNullable(componentInstance.get().getNodeFilter());
288 return Optional.empty();
291 private CINodeFilterDataDefinition validateAndReturnNodeFilterDefinition(final String componentInstanceId,
292 final NodeFilterConstraintAction action, final String constraint,
293 final Component component,
294 final NodeFilterConstraintType nodeFilterConstraintType)
295 throws BusinessLogicException {
296 validateNodeFilter(component, componentInstanceId, action, constraint, nodeFilterConstraintType);
297 final Optional<CINodeFilterDataDefinition> cINodeFilterDataDefinition = getCiNodeFilterDataDefinition(componentInstanceId, component);
298 if (!cINodeFilterDataDefinition.isPresent()) {
299 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
301 return cINodeFilterDataDefinition.get();
304 private void validateNodeFilter(final Component component, final String componentInstanceId, final NodeFilterConstraintAction action,
305 final String constraint, final NodeFilterConstraintType nodeFilterConstraintType) throws BusinessLogicException {
306 final Either<Boolean, ResponseFormat> response = nodeFilterValidator
307 .validateFilter(component, componentInstanceId, Collections.singletonList(constraint), action, nodeFilterConstraintType);
308 if (response.isRight()) {
309 throw new BusinessLogicException(
310 componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
314 public Optional<CINodeFilterDataDefinition> updateNodeFilter(final String componentId, final String componentInstanceId,
315 final UIConstraint uiConstraint, final ComponentTypeEnum componentTypeEnum,
316 final NodeFilterConstraintType nodeFilterConstraintType, final int index)
317 throws BusinessLogicException {
318 final Optional<CINodeFilterDataDefinition> deleteActionResponse = deleteNodeFilter(componentId, componentInstanceId,
319 NodeFilterConstraintAction.DELETE, null, index, true, componentTypeEnum, nodeFilterConstraintType);
320 if (!deleteActionResponse.isPresent()) {
321 throw new BusinessLogicException(
322 componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, "Failed to delete node filter capabilities"));
324 return addNodeFilter(componentId.toLowerCase(), componentInstanceId, NodeFilterConstraintAction.ADD, uiConstraint.getServicePropertyName(),
325 new ConstraintConvertor().convert(uiConstraint), true, componentTypeEnum, nodeFilterConstraintType,
326 StringUtils.isEmpty(uiConstraint.getCapabilityName()) ? "" : uiConstraint.getCapabilityName());
329 public StorageOperationStatus associateNodeFilterToComponentInstance(final String componentId,
330 final Map<String, UploadNodeFilterInfo> instNodeFilter) {
331 for (Entry<String, UploadNodeFilterInfo> filter : instNodeFilter.entrySet()) {
332 String componentInstanceId = filter.getKey();
333 CINodeFilterDataDefinition ciNodeFilterDataDefinition = new CINodeFilterUtils()
334 .getNodeFilterDataDefinition(filter.getValue(), componentInstanceId);
335 Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilter = nodeFilterOperation.createNodeFilter(componentId,
336 componentInstanceId);
337 if (nodeFilter.isRight()) {
338 LOGGER.error(BUSINESS_PROCESS_ERROR, "Failed to Create Node filter on component instance with id {}",
340 return nodeFilter.right().value();
343 //associate node filter properties to component instance
344 List<RequirementNodeFilterPropertyDataDefinition> properties = ciNodeFilterDataDefinition.getProperties()
345 .getListToscaDataDefinition();
346 if (!properties.isEmpty()) {
347 properties.forEach(property -> {
348 RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition =
349 getRequirementNodeFilterPropertyDataDefinition(property);
350 Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilterProperty = nodeFilterOperation
351 .addNewProperty(componentId, componentInstanceId, nodeFilter.left().value(), requirementNodeFilterPropertyDataDefinition);
352 if (nodeFilterProperty.isRight()) {
353 throw new ComponentException(
354 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nodeFilterProperty.right().value()),
355 componentInstanceId));
360 //associate node filter capabilities to component instance
361 List<RequirementNodeFilterCapabilityDataDefinition> capabilities = ciNodeFilterDataDefinition.getCapabilities()
362 .getListToscaDataDefinition();
363 if (!capabilities.isEmpty()) {
364 capabilities.forEach(capability -> {
365 RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition =
366 new RequirementNodeFilterCapabilityDataDefinition();
367 requirementNodeFilterCapabilityDataDefinition.setName(capability.getName());
368 requirementNodeFilterCapabilityDataDefinition.setProperties(getProperties(capability.getProperties()));
369 Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilterCapability = nodeFilterOperation
370 .addNewCapabilities(componentId, componentInstanceId, nodeFilter.left().value(),
371 requirementNodeFilterCapabilityDataDefinition);
372 if (nodeFilterCapability.isRight()) {
373 throw new ComponentException(
374 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nodeFilterCapability.right().value()),
375 componentInstanceId));
380 return StorageOperationStatus.OK;
383 private List<String> getNodeFilterConstraints(String name, List<String> value) {
384 List<String> constraints = new ArrayList<>();
385 String values = value.get(0).split("\n")[0];
386 constraints.add(name + ": {" + values + "}");
390 private ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> getProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties) {
391 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> updatedProperties = new ListDataDefinition<>();
392 properties.getListToscaDataDefinition().forEach(property -> {
393 RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = getRequirementNodeFilterPropertyDataDefinition(
395 updatedProperties.add(requirementNodeFilterPropertyDataDefinition);
397 return updatedProperties;
400 private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(
401 RequirementNodeFilterPropertyDataDefinition property) {
402 RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition();
403 requirementNodeFilterPropertyDataDefinition.setName(property.getName());
404 requirementNodeFilterPropertyDataDefinition.setConstraints(getNodeFilterConstraints(property.getName(), property.getConstraints()));
405 return requirementNodeFilterPropertyDataDefinition;