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.Arrays;
25 import java.util.List;
27 import java.util.Map.Entry;
28 import java.util.Optional;
29 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
30 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
31 import org.openecomp.sdc.be.components.impl.utils.CINodeFilterUtils;
32 import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
33 import org.openecomp.sdc.be.dao.api.ActionStatus;
34 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
35 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition;
37 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
38 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
39 import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType;
40 import org.openecomp.sdc.be.model.Component;
41 import org.openecomp.sdc.be.model.ComponentInstance;
42 import org.openecomp.sdc.be.model.UploadNodeFilterInfo;
43 import org.openecomp.sdc.be.model.User;
44 import org.openecomp.sdc.be.model.dto.FilterConstraintDto;
45 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
46 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
47 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeFilterOperation;
48 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
49 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
50 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
51 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
52 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
53 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
54 import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper;
55 import org.openecomp.sdc.be.ui.model.UIConstraint;
56 import org.openecomp.sdc.be.user.Role;
57 import org.openecomp.sdc.common.log.wrappers.Logger;
58 import org.openecomp.sdc.exception.ResponseFormat;
59 import org.springframework.beans.factory.annotation.Autowired;
61 @org.springframework.stereotype.Component("componentNodeFilterBusinessLogic")
62 public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic {
64 private static final Logger LOGGER = Logger.getLogger(ComponentNodeFilterBusinessLogic.class.getName());
65 private final NodeFilterOperation nodeFilterOperation;
66 private final NodeFilterValidator nodeFilterValidator;
69 public ComponentNodeFilterBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation,
70 final IGroupInstanceOperation groupInstanceOperation, final IGroupTypeOperation groupTypeOperation,
71 final InterfaceOperation interfaceOperation,
72 final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
73 final ArtifactsOperations artifactToscaOperation, final NodeFilterOperation nodeFilterOperation,
74 final NodeFilterValidator nodeFilterValidator) {
75 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
76 artifactToscaOperation);
77 this.nodeFilterOperation = nodeFilterOperation;
78 this.nodeFilterValidator = nodeFilterValidator;
81 public Optional<CINodeFilterDataDefinition> createNodeFilterIfNotExist(final String componentId, final String componentInstanceId,
82 final boolean shouldLock, final ComponentTypeEnum componentTypeEnum)
83 throws BusinessLogicException {
84 final Component component = getComponent(componentId);
85 Optional<CINodeFilterDataDefinition> filterDataDefinition =
86 component.getComponentInstanceById(componentInstanceId).map(ComponentInstance::getNodeFilter);
87 if (filterDataDefinition.isPresent()) {
88 return filterDataDefinition;
90 final Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
91 boolean wasLocked = false;
94 lockComponent(component.getUniqueId(), component, "Create Node Filter on component");
97 result = nodeFilterOperation.createNodeFilter(componentId, componentInstanceId);
98 if (result.isRight()) {
99 janusGraphDao.rollback();
100 LOGGER.error(BUSINESS_PROCESS_ERROR, "Failed to Create Node filter on component with id {}", componentId);
101 throw new BusinessLogicException(componentsUtils
102 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()));
104 filterDataDefinition = Optional.ofNullable(result.left().value());
106 janusGraphDao.commit();
107 LOGGER.debug("Node filter successfully created in component {} . ", component.getSystemName());
108 } catch (final Exception e) {
109 janusGraphDao.rollback();
110 LOGGER.error(BUSINESS_PROCESS_ERROR, "Exception occurred during add Component node filter property values: {}", e.getMessage(), e);
111 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
114 unlockComponent(component.getUniqueId(), componentTypeEnum);
117 return filterDataDefinition;
120 public Optional<String> deleteNodeFilterIfExists(final String componentId, final String componentInstanceId, final boolean shouldLock,
121 final ComponentTypeEnum componentTypeEnum) throws BusinessLogicException {
122 final Component component = getComponent(componentId);
123 final Optional<CINodeFilterDataDefinition> nodeFilterDataDefinition = getComponentInstanceNodeFilter(componentInstanceId, component);
124 if (nodeFilterDataDefinition.isEmpty()) {
125 return Optional.ofNullable(componentInstanceId);
127 final Either<String, StorageOperationStatus> result;
128 boolean wasLocked = false;
131 lockComponent(component.getUniqueId(), component, "Delete Node Filter from component");
134 result = nodeFilterOperation.deleteNodeFilter(component, componentInstanceId);
135 if (result.isRight()) {
136 LOGGER.error(BUSINESS_PROCESS_ERROR, "Failed to delete node filter in component {}. Response is {}. ", component.getName(),
137 result.right().value());
138 janusGraphDao.rollback();
139 throw new BusinessLogicException(componentsUtils
140 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()));
142 janusGraphDao.commit();
143 LOGGER.debug("Node filter successfully deleted in component {} . ", component.getSystemName());
144 } catch (final Exception e) {
145 LOGGER.error(BUSINESS_PROCESS_ERROR, "Exception occurred during delete deleting node filter: {}", e.getMessage(), e);
146 janusGraphDao.rollback();
147 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
150 unlockComponent(component.getUniqueId(), componentTypeEnum);
153 return Optional.ofNullable(result.left().value());
156 public Optional<CINodeFilterDataDefinition> addNodeFilter(final String componentId, final String componentInstanceId,
157 final FilterConstraintDto filterConstraint, final boolean shouldLock,
158 final ComponentTypeEnum componentTypeEnum,
159 final NodeFilterConstraintType nodeFilterConstraintType,
160 final String capabilityName) throws BusinessLogicException {
161 final Component component = getComponent(componentId);
162 validateNodeFilter(component, componentInstanceId, filterConstraint);
163 CINodeFilterDataDefinition nodeFilterDataDefinition = getComponentInstanceNodeFilterOrThrow(componentInstanceId, component);
164 boolean wasLocked = false;
167 lockComponent(component.getUniqueId(), component, "Add Node Filter on Component");
170 final PropertyFilterDataDefinition filterPropertyDataDefinition = new PropertyFilterDataDefinition();
171 filterPropertyDataDefinition.setName(filterConstraint.getPropertyName());
172 filterPropertyDataDefinition.setConstraints(List.of(new FilterConstraintMapper().mapTo(filterConstraint)));
173 final Either<CINodeFilterDataDefinition, StorageOperationStatus> result = addNodeFilter(componentId, componentInstanceId,
174 nodeFilterConstraintType, nodeFilterDataDefinition, filterPropertyDataDefinition, capabilityName);
175 if (result.isRight()) {
176 throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(
177 componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()
180 nodeFilterDataDefinition = result.left().value();
182 janusGraphDao.commit();
183 LOGGER.debug("Node filter successfully created in component {} . ", component.getSystemName());
184 } catch (final Exception e) {
185 janusGraphDao.rollback();
186 LOGGER.error(BUSINESS_PROCESS_ERROR, "Exception occurred during add component node filter property values: {}", e.getMessage(), e);
187 if (e instanceof BusinessLogicException) {
190 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
193 unlockComponent(component.getUniqueId(), componentTypeEnum);
196 return Optional.ofNullable(nodeFilterDataDefinition);
199 public Optional<CINodeFilterDataDefinition> deleteNodeFilter(final String componentId, final String componentInstanceId, final int position,
200 final boolean shouldLock, final ComponentTypeEnum componentTypeEnum,
201 final NodeFilterConstraintType nodeFilterConstraintType)
202 throws BusinessLogicException {
204 final Component component = getComponent(componentId);
205 CINodeFilterDataDefinition nodeFilterDataDefinition = getComponentInstanceNodeFilterOrThrow(componentInstanceId, component);
206 boolean wasLocked = false;
209 lockComponent(component.getUniqueId(), component, "Add Node Filter on Component");
212 final Either<CINodeFilterDataDefinition, StorageOperationStatus> result = nodeFilterOperation
213 .deleteConstraint(componentId, componentInstanceId, nodeFilterDataDefinition, position, nodeFilterConstraintType);
214 if (result.isRight()) {
215 janusGraphDao.rollback();
216 throw new BusinessLogicException(componentsUtils
217 .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()));
219 nodeFilterDataDefinition = result.left().value();
221 janusGraphDao.commit();
222 LOGGER.debug("Node filter successfully deleted in component {} . ", component.getSystemName());
223 } catch (final Exception e) {
224 janusGraphDao.rollback();
225 LOGGER.error(BUSINESS_PROCESS_ERROR, "Exception occurred during delete component node filter property values: {}", e.getMessage(), e);
226 throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
229 unlockComponent(component.getUniqueId(), componentTypeEnum);
232 return Optional.ofNullable(nodeFilterDataDefinition);
235 private Either<CINodeFilterDataDefinition, StorageOperationStatus> addNodeFilter(final String componentId, final String componentInstanceId,
236 final NodeFilterConstraintType nodeFilterConstraintType,
237 final CINodeFilterDataDefinition nodeFilterDataDefinition,
238 final PropertyFilterDataDefinition propertyFilterDataDefinition,
239 final String capabilityName) {
240 if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) {
241 return nodeFilterOperation
242 .addPropertyFilter(componentId, componentInstanceId, nodeFilterDataDefinition, propertyFilterDataDefinition);
244 final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition = new RequirementNodeFilterCapabilityDataDefinition();
245 requirementNodeFilterCapabilityDataDefinition.setName(capabilityName);
246 final ListDataDefinition<PropertyFilterDataDefinition> propertyDataDefinitionListDataDefinition = new ListDataDefinition<>();
247 propertyDataDefinitionListDataDefinition.getListToscaDataDefinition()
248 .add(propertyFilterDataDefinition);
249 requirementNodeFilterCapabilityDataDefinition.setProperties(propertyDataDefinitionListDataDefinition);
250 return nodeFilterOperation
251 .addCapabilities(componentId, componentInstanceId, nodeFilterDataDefinition, requirementNodeFilterCapabilityDataDefinition);
254 private void unlockComponent(final String componentUniqueId, final ComponentTypeEnum componentType) {
255 graphLockOperation.unlockComponent(componentUniqueId, componentType.getNodeType());
258 public User validateUser(final String userId) {
259 final User user = userValidations.validateUserExists(userId);
260 userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
264 private Optional<ComponentInstance> getComponentInstance(final String componentInstanceId, final Component component) {
265 return component.getComponentInstanceById(componentInstanceId);
268 private Optional<CINodeFilterDataDefinition> getComponentInstanceNodeFilter(final String componentInstanceId, final Component component)
269 throws BusinessLogicException {
270 final Either<Boolean, ResponseFormat> response = nodeFilterValidator.validateComponentInstanceExist(component, componentInstanceId);
271 if (response.isRight()) {
272 throw new BusinessLogicException(
273 componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
275 return getComponentInstance(componentInstanceId, component).map(ComponentInstance::getNodeFilter);
278 private CINodeFilterDataDefinition getComponentInstanceNodeFilterOrThrow(final String componentInstanceId,
279 final Component component) throws BusinessLogicException {
280 return getComponentInstanceNodeFilter(componentInstanceId, component).orElseThrow(
281 () -> new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND)));
284 private void validateNodeFilter(final Component component, final String componentInstanceId,
285 final FilterConstraintDto constraint) throws BusinessLogicException {
286 final Either<Boolean, ResponseFormat> response = nodeFilterValidator.validateFilter(component, componentInstanceId, constraint);
287 if (response.isRight()) {
288 throw new BusinessLogicException(response.right().value());
292 public Optional<CINodeFilterDataDefinition> updateNodeFilter(final String componentId, final String componentInstanceId,
293 final UIConstraint uiConstraint, final ComponentTypeEnum componentTypeEnum,
294 final NodeFilterConstraintType nodeFilterConstraintType,
295 final int index) throws BusinessLogicException {
296 final Optional<CINodeFilterDataDefinition> deleteActionResponse =
297 deleteNodeFilter(componentId, componentInstanceId, index, true, componentTypeEnum, nodeFilterConstraintType);
298 if (deleteActionResponse.isEmpty()) {
299 throw new BusinessLogicException(
300 componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, "Failed to delete node filter capabilities"));
302 return addNodeFilter(componentId.toLowerCase(), componentInstanceId, new FilterConstraintMapper().mapFrom(uiConstraint), true,
303 componentTypeEnum, nodeFilterConstraintType, uiConstraint.getCapabilityName());
306 public StorageOperationStatus associateNodeFilterToComponentInstance(final String componentId,
307 final Map<String, UploadNodeFilterInfo> instNodeFilter) {
308 for (Entry<String, UploadNodeFilterInfo> filter : instNodeFilter.entrySet()) {
309 String componentInstanceId = filter.getKey();
310 CINodeFilterDataDefinition ciNodeFilterDataDefinition = new CINodeFilterUtils()
311 .getNodeFilterDataDefinition(filter.getValue(), componentInstanceId);
312 Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilter = nodeFilterOperation.createNodeFilter(componentId,
313 componentInstanceId);
314 if (nodeFilter.isRight()) {
315 LOGGER.error(BUSINESS_PROCESS_ERROR, "Failed to Create Node filter on component instance with id {}",
317 return nodeFilter.right().value();
320 //associate node filter properties to component instance
321 List<PropertyFilterDataDefinition> properties = ciNodeFilterDataDefinition.getProperties()
322 .getListToscaDataDefinition();
323 if (!properties.isEmpty()) {
324 properties.forEach(property -> {
325 Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilterProperty = nodeFilterOperation
326 .addPropertyFilter(componentId, componentInstanceId, nodeFilter.left().value(), property);
327 if (nodeFilterProperty.isRight()) {
328 throw new ComponentException(
329 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nodeFilterProperty.right().value()),
330 componentInstanceId));
335 //associate node filter capabilities to component instance
336 List<RequirementNodeFilterCapabilityDataDefinition> capabilities = ciNodeFilterDataDefinition.getCapabilities()
337 .getListToscaDataDefinition();
338 if (!capabilities.isEmpty()) {
339 capabilities.forEach(capability -> {
340 RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition =
341 new RequirementNodeFilterCapabilityDataDefinition();
342 requirementNodeFilterCapabilityDataDefinition.setName(capability.getName());
343 requirementNodeFilterCapabilityDataDefinition.setProperties(getProperties(capability.getProperties()));
344 Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilterCapability = nodeFilterOperation
345 .addCapabilities(componentId, componentInstanceId, nodeFilter.left().value(),
346 requirementNodeFilterCapabilityDataDefinition);
347 if (nodeFilterCapability.isRight()) {
348 throw new ComponentException(
349 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nodeFilterCapability.right().value()),
350 componentInstanceId));
355 return StorageOperationStatus.OK;
358 private ListDataDefinition<PropertyFilterDataDefinition> getProperties(ListDataDefinition<PropertyFilterDataDefinition> properties) {
359 ListDataDefinition<PropertyFilterDataDefinition> updatedProperties = new ListDataDefinition<>();
360 properties.getListToscaDataDefinition().forEach(updatedProperties::add);
361 return updatedProperties;