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, capabilityName);
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 final String capabilityName)
296 throws BusinessLogicException {
297 validateNodeFilter(component, componentInstanceId, action, constraint, nodeFilterConstraintType, capabilityName);
298 final Optional<CINodeFilterDataDefinition> cINodeFilterDataDefinition = getCiNodeFilterDataDefinition(componentInstanceId, component);
299 if (!cINodeFilterDataDefinition.isPresent()) {
300 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
302 return cINodeFilterDataDefinition.get();
305 private void validateNodeFilter(final Component component, final String componentInstanceId, final NodeFilterConstraintAction action,
306 final String constraint, final NodeFilterConstraintType nodeFilterConstraintType, final String capabilityName) throws BusinessLogicException {
307 final Either<Boolean, ResponseFormat> response = nodeFilterValidator
308 .validateFilter(component, componentInstanceId, Collections.singletonList(constraint), action, nodeFilterConstraintType, capabilityName);
309 if (response.isRight()) {
310 throw new BusinessLogicException(
311 componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
315 public Optional<CINodeFilterDataDefinition> updateNodeFilter(final String componentId, final String componentInstanceId,
316 final UIConstraint uiConstraint, final ComponentTypeEnum componentTypeEnum,
317 final NodeFilterConstraintType nodeFilterConstraintType, final int index)
318 throws BusinessLogicException {
319 final Optional<CINodeFilterDataDefinition> deleteActionResponse = deleteNodeFilter(componentId, componentInstanceId,
320 NodeFilterConstraintAction.DELETE, null, index, true, componentTypeEnum, nodeFilterConstraintType);
321 if (!deleteActionResponse.isPresent()) {
322 throw new BusinessLogicException(
323 componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, "Failed to delete node filter capabilities"));
325 return addNodeFilter(componentId.toLowerCase(), componentInstanceId, NodeFilterConstraintAction.ADD, uiConstraint.getServicePropertyName(),
326 new ConstraintConvertor().convert(uiConstraint), true, componentTypeEnum, nodeFilterConstraintType,
327 uiConstraint.getCapabilityName());
330 public StorageOperationStatus associateNodeFilterToComponentInstance(final String componentId,
331 final Map<String, UploadNodeFilterInfo> instNodeFilter) {
332 for (Entry<String, UploadNodeFilterInfo> filter : instNodeFilter.entrySet()) {
333 String componentInstanceId = filter.getKey();
334 CINodeFilterDataDefinition ciNodeFilterDataDefinition = new CINodeFilterUtils()
335 .getNodeFilterDataDefinition(filter.getValue(), componentInstanceId);
336 Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilter = nodeFilterOperation.createNodeFilter(componentId,
337 componentInstanceId);
338 if (nodeFilter.isRight()) {
339 LOGGER.error(BUSINESS_PROCESS_ERROR, "Failed to Create Node filter on component instance with id {}",
341 return nodeFilter.right().value();
344 //associate node filter properties to component instance
345 List<RequirementNodeFilterPropertyDataDefinition> properties = ciNodeFilterDataDefinition.getProperties()
346 .getListToscaDataDefinition();
347 if (!properties.isEmpty()) {
348 properties.forEach(property -> {
349 RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition =
350 getRequirementNodeFilterPropertyDataDefinition(property);
351 Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilterProperty = nodeFilterOperation
352 .addNewProperty(componentId, componentInstanceId, nodeFilter.left().value(), requirementNodeFilterPropertyDataDefinition);
353 if (nodeFilterProperty.isRight()) {
354 throw new ComponentException(
355 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nodeFilterProperty.right().value()),
356 componentInstanceId));
361 //associate node filter capabilities to component instance
362 List<RequirementNodeFilterCapabilityDataDefinition> capabilities = ciNodeFilterDataDefinition.getCapabilities()
363 .getListToscaDataDefinition();
364 if (!capabilities.isEmpty()) {
365 capabilities.forEach(capability -> {
366 RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition =
367 new RequirementNodeFilterCapabilityDataDefinition();
368 requirementNodeFilterCapabilityDataDefinition.setName(capability.getName());
369 requirementNodeFilterCapabilityDataDefinition.setProperties(getProperties(capability.getProperties()));
370 Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilterCapability = nodeFilterOperation
371 .addNewCapabilities(componentId, componentInstanceId, nodeFilter.left().value(),
372 requirementNodeFilterCapabilityDataDefinition);
373 if (nodeFilterCapability.isRight()) {
374 throw new ComponentException(
375 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nodeFilterCapability.right().value()),
376 componentInstanceId));
381 return StorageOperationStatus.OK;
384 private List<String> getNodeFilterConstraints(String name, List<String> value) {
385 List<String> constraints = new ArrayList<>();
386 String values = value.get(0).split("\n")[0];
387 constraints.add(name + ": {" + values + "}");
391 private ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> getProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties) {
392 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> updatedProperties = new ListDataDefinition<>();
393 properties.getListToscaDataDefinition().forEach(property -> {
394 RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = getRequirementNodeFilterPropertyDataDefinition(
396 updatedProperties.add(requirementNodeFilterPropertyDataDefinition);
398 return updatedProperties;
401 private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(
402 RequirementNodeFilterPropertyDataDefinition property) {
403 RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition();
404 requirementNodeFilterPropertyDataDefinition.setName(property.getName());
405 requirementNodeFilterPropertyDataDefinition.setConstraints(getNodeFilterConstraints(property.getName(), property.getConstraints()));
406 return requirementNodeFilterPropertyDataDefinition;