Delete node_filter capabilities
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ComponentNodeFilterBusinessLogic.java
1 /*
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
8  *
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.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.openecomp.sdc.be.components.impl;
21
22 import static org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR;
23
24 import fj.data.Either;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Optional;
29 import java.util.stream.Collectors;
30 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
31 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
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.RequirementNodeFilterCapabilityDataDefinition;
37 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
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.User;
43 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
44 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
45 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeFilterOperation;
46 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
47 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
48 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
49 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
50 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
51 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
52 import org.openecomp.sdc.be.user.Role;
53 import org.openecomp.sdc.common.log.wrappers.Logger;
54 import org.openecomp.sdc.exception.ResponseFormat;
55 import org.springframework.beans.factory.annotation.Autowired;
56
57 @org.springframework.stereotype.Component("componentNodeFilterBusinessLogic")
58 public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic {
59
60     private static final Logger LOGGER = Logger.getLogger(ComponentNodeFilterBusinessLogic.class.getName());
61
62     private final NodeFilterOperation nodeFilterOperation;
63     private final NodeFilterValidator nodeFilterValidator;
64
65     @Autowired
66     public ComponentNodeFilterBusinessLogic(final IElementOperation elementDao,
67                                             final IGroupOperation groupOperation,
68                                             final IGroupInstanceOperation groupInstanceOperation,
69                                             final IGroupTypeOperation groupTypeOperation,
70                                             final InterfaceOperation interfaceOperation,
71                                             final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
72                                             final ArtifactsOperations artifactToscaOperation,
73                                             final NodeFilterOperation nodeFilterOperation,
74                                             final NodeFilterValidator nodeFilterValidator) {
75         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation,
76             interfaceLifecycleTypeOperation, artifactToscaOperation);
77         this.nodeFilterOperation = nodeFilterOperation;
78         this.nodeFilterValidator = nodeFilterValidator;
79     }
80
81     public Optional<CINodeFilterDataDefinition> createNodeFilterIfNotExist(final String componentId,
82                                                                            final String componentInstanceId,
83                                                                            final boolean shouldLock,
84                                                                            final ComponentTypeEnum componentTypeEnum)
85         throws BusinessLogicException {
86
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;
92         }
93         final Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
94         boolean wasLocked = false;
95         try {
96             if (shouldLock) {
97                 lockComponent(component.getUniqueId(), component,"Create Node Filter on component");
98                 wasLocked = true;
99             }
100             result = nodeFilterOperation.createNodeFilter(componentId, componentInstanceId);
101             if (result.isRight()) {
102                 janusGraphDao.rollback();
103                 LOGGER.error(BUSINESS_PROCESS_ERROR,
104                     "Failed to Create Node filter on component with id {}", componentId);
105                 throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils
106                     .convertFromStorageResponse(result.right().value()), component.getSystemName()));
107             } else {
108                 filterDataDefinition = Optional.ofNullable(result.left().value());
109             }
110             janusGraphDao.commit();
111             LOGGER.debug("Node filter successfully created in component {} . ", component.getSystemName());
112
113         } catch (final Exception e) {
114             janusGraphDao.rollback();
115             LOGGER.error(BUSINESS_PROCESS_ERROR,
116                 "Exception occurred during add Component node filter property values: {}", e.getMessage(), e);
117             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
118
119         } finally {
120             if (wasLocked) {
121                 unlockComponent(component.getUniqueId(), componentTypeEnum);
122             }
123         }
124         return filterDataDefinition;
125     }
126
127     public Optional<String> deleteNodeFilterIfExists(final String componentId,
128                                                      final String componentInstanceId,
129                                                      final boolean shouldLock,
130                                                      final ComponentTypeEnum componentTypeEnum)
131         throws BusinessLogicException {
132
133         final Component component = getComponent(componentId);
134         final Optional<CINodeFilterDataDefinition> nodeFilterDataDefinition =
135             getCiNodeFilterDataDefinition(componentInstanceId, component);
136         if (!nodeFilterDataDefinition.isPresent()) {
137             return Optional.ofNullable(componentInstanceId);
138         }
139
140         final Either<String, StorageOperationStatus> result;
141         boolean wasLocked = false;
142         try {
143             if (shouldLock) {
144                 lockComponent(component.getUniqueId(), component,"Delete Node Filter from component");
145                 wasLocked = true;
146             }
147             result = nodeFilterOperation.deleteNodeFilter(component, componentInstanceId);
148             if (result.isRight()) {
149                 LOGGER.error(BUSINESS_PROCESS_ERROR,
150                     "Failed to delete node filter in component {}. Response is {}. ", component.getName(),
151                     result.right().value());
152                 janusGraphDao.rollback();
153                 throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils
154                     .convertFromStorageResponse(result.right().value()), component.getSystemName()));
155             }
156             janusGraphDao.commit();
157             LOGGER.debug("Node filter successfully deleted in component {} . ", component.getSystemName());
158
159         } catch (final Exception e) {
160             LOGGER.error(BUSINESS_PROCESS_ERROR,"Exception occurred during delete deleting node filter: {}",
161                 e.getMessage(), e);
162             janusGraphDao.rollback();
163             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
164         } finally {
165             if (wasLocked) {
166                 unlockComponent(component.getUniqueId(), componentTypeEnum);
167             }
168         }
169         return Optional.ofNullable(result.left().value());
170     }
171
172     public Optional<CINodeFilterDataDefinition> addNodeFilter(final String componentId,
173                                                               final String componentInstanceId,
174                                                               final NodeFilterConstraintAction action,
175                                                               final String propertyName,
176                                                               final String constraint,
177                                                               final boolean shouldLock,
178                                                               final ComponentTypeEnum componentTypeEnum,
179                                                               final NodeFilterConstraintType nodeFilterConstraintType)
180         throws BusinessLogicException {
181
182         final Component component = getComponent(componentId);
183         CINodeFilterDataDefinition nodeFilterDataDefinition = validateAndReturnNodeFilterDefinition(componentInstanceId,
184             action, constraint, component);
185         boolean wasLocked = false;
186         try {
187             if (shouldLock) {
188                 lockComponent(component.getUniqueId(), component,"Add Node Filter on Component");
189                 wasLocked = true;
190             }
191             final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition =
192                 new RequirementNodeFilterPropertyDataDefinition();
193             requirementNodeFilterPropertyDataDefinition.setName(propertyName);
194             requirementNodeFilterPropertyDataDefinition.setConstraints(Collections.singletonList(constraint));
195             final Either<CINodeFilterDataDefinition, StorageOperationStatus> result = addNewNodeFilter(componentId,
196                 componentInstanceId, propertyName, nodeFilterConstraintType, nodeFilterDataDefinition,
197                 requirementNodeFilterPropertyDataDefinition);
198             if (result.isRight()) {
199                 janusGraphDao.rollback();
200                 throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils
201                     .convertFromStorageResponse(result.right().value()), component.getSystemName()));
202             } else {
203                 nodeFilterDataDefinition = result.left().value();
204             }
205             janusGraphDao.commit();
206             LOGGER.debug("Node filter successfully created in component {} . ", component.getSystemName());
207
208         } catch (final Exception e) {
209             janusGraphDao.rollback();
210             LOGGER.error(BUSINESS_PROCESS_ERROR,
211                 "Exception occurred during add component node filter property values: {}", e.getMessage(), e);
212             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
213
214         } finally {
215             if (wasLocked) {
216                 unlockComponent(component.getUniqueId(), componentTypeEnum);
217             }
218         }
219         return Optional.ofNullable(nodeFilterDataDefinition);
220     }
221
222     public Optional<CINodeFilterDataDefinition> deleteNodeFilter(final String componentId,
223                                                                  final String componentInstanceId,
224                                                                  final NodeFilterConstraintAction action,
225                                                                  final String constraint,
226                                                                  final int position,
227                                                                  final boolean shouldLock,
228                                                                  final ComponentTypeEnum componentTypeEnum,
229                                                                  final NodeFilterConstraintType nodeFilterConstraintType)
230         throws BusinessLogicException {
231
232         final Component component = getComponent(componentId);
233         CINodeFilterDataDefinition nodeFilterDataDefinition =
234             validateAndReturnNodeFilterDefinition(componentInstanceId, action, constraint, component);
235         boolean wasLocked = false;
236         try {
237             if (shouldLock) {
238                 lockComponent(component.getUniqueId(), component,"Add Node Filter on Component");
239                 wasLocked = true;
240             }
241             final Either<CINodeFilterDataDefinition, StorageOperationStatus> result = nodeFilterOperation
242                 .deleteConstraint(componentId, componentInstanceId, nodeFilterDataDefinition, position,
243                     nodeFilterConstraintType);
244             if (result.isRight()) {
245                 janusGraphDao.rollback();
246                 throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils
247                     .convertFromStorageResponse(result.right().value()), component.getSystemName()));
248             } else {
249                 nodeFilterDataDefinition = result.left().value();
250             }
251             janusGraphDao.commit();
252             LOGGER.debug("Node filter successfully deleted in component {} . ", component.getSystemName());
253
254         } catch (final Exception e) {
255             janusGraphDao.rollback();
256             LOGGER.error(BUSINESS_PROCESS_ERROR,
257                 "Exception occurred during delete component node filter property values: {}", e.getMessage(), e);
258             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
259
260         } finally {
261             if (wasLocked) {
262                 unlockComponent(component.getUniqueId(), componentTypeEnum);
263             }
264         }
265         return Optional.ofNullable(nodeFilterDataDefinition);
266     }
267
268     public Optional<CINodeFilterDataDefinition> updateNodeFilter(final String componentId,
269                                                                  final String componentInstanceId,
270                                                                  final List<String> constraints,
271                                                                  final boolean shouldLock,
272                                                                  final ComponentTypeEnum componentTypeEnum)
273         throws BusinessLogicException {
274
275         final Component component = getComponent(componentId);
276
277         final Either<Boolean, ResponseFormat> response = nodeFilterValidator
278             .validateFilter(component, componentInstanceId, constraints, NodeFilterConstraintAction.UPDATE);
279         if (response.isRight()) {
280             throw new BusinessLogicException(componentsUtils
281                 .getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
282         }
283         final Optional<ComponentInstance> componentInstance = getComponentInstance(componentInstanceId,
284             component);
285         if (!componentInstance.isPresent()) {
286             throw new BusinessLogicException(ResponseFormatManager.getInstance()
287                 .getResponseFormat(ActionStatus.GENERAL_ERROR));
288         }
289         CINodeFilterDataDefinition nodeFilterDataDefinition = componentInstance.get().getNodeFilter();
290         if (nodeFilterDataDefinition == null) {
291             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
292         }
293         boolean wasLocked = false;
294         try {
295             if (shouldLock) {
296                 lockComponent(component.getUniqueId(), component,"Update Node Filter on Component");
297                 wasLocked = true;
298             }
299             final List<RequirementNodeFilterPropertyDataDefinition> properties = constraints.stream()
300                 .map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList());
301             final Either<CINodeFilterDataDefinition, StorageOperationStatus> result = nodeFilterOperation
302                 .updateProperties(componentId, componentInstanceId, nodeFilterDataDefinition, properties);
303
304             if (result.isRight()) {
305                 janusGraphDao.rollback();
306                 throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils
307                     .convertFromStorageResponse(result.right().value()), component.getSystemName()));
308             } else {
309                 nodeFilterDataDefinition = result.left().value();
310             }
311             janusGraphDao.commit();
312             LOGGER.debug("Node filter successfully updated in component {} . ", component.getSystemName());
313
314         } catch (final Exception e) {
315             janusGraphDao.rollback();
316             LOGGER.error(BUSINESS_PROCESS_ERROR,
317                 "Exception occurred during update component node filter property values: {}",
318                 e.getMessage(), e);
319             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
320
321         } finally {
322             if (wasLocked) {
323                 unlockComponent(component.getUniqueId(), componentTypeEnum);
324             }
325         }
326         return Optional.ofNullable(nodeFilterDataDefinition);
327     }
328
329     private Either<CINodeFilterDataDefinition, StorageOperationStatus> addNewNodeFilter(
330         final String componentId,
331         final String componentInstanceId,
332         final String propertyName,
333         final NodeFilterConstraintType nodeFilterConstraintType,
334         final CINodeFilterDataDefinition nodeFilterDataDefinition,
335         final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition) {
336
337         if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) {
338             return nodeFilterOperation.addNewProperty(componentId, componentInstanceId, nodeFilterDataDefinition,
339                 requirementNodeFilterPropertyDataDefinition);
340         }
341         final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition =
342             new RequirementNodeFilterCapabilityDataDefinition();
343         requirementNodeFilterCapabilityDataDefinition.setName(propertyName);
344         final ListDataDefinition<RequirementNodeFilterPropertyDataDefinition>
345             propertyDataDefinitionListDataDefinition = new ListDataDefinition<>();
346         propertyDataDefinitionListDataDefinition.getListToscaDataDefinition().addAll(
347             Collections.singleton(requirementNodeFilterPropertyDataDefinition));
348         requirementNodeFilterCapabilityDataDefinition.setProperties(propertyDataDefinitionListDataDefinition);
349         return nodeFilterOperation.addNewCapabilities(componentId, componentInstanceId, nodeFilterDataDefinition,
350             requirementNodeFilterCapabilityDataDefinition);
351     }
352
353     private void unlockComponent(final String componentUniqueId,
354                                  final ComponentTypeEnum componentType) {
355         graphLockOperation.unlockComponent(componentUniqueId, componentType.getNodeType());
356     }
357
358     public User validateUser(final String userId) {
359         final User user = userValidations.validateUserExists(userId);
360         userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
361         return user;
362     }
363
364     private Optional<ComponentInstance> getComponentInstance(final String componentInstanceId,
365                                                              final Component component) {
366         return component.getComponentInstanceById(componentInstanceId);
367     }
368
369     private Optional<CINodeFilterDataDefinition> getCiNodeFilterDataDefinition(
370         final Optional<ComponentInstance> componentInstance) {
371
372         if (componentInstance.isPresent()) {
373             return Optional.ofNullable(componentInstance.get().getNodeFilter());
374         }
375         return Optional.empty();
376     }
377
378     private Optional<CINodeFilterDataDefinition> getCiNodeFilterDataDefinition(final String componentInstanceId,
379                                                                                final Component component)
380         throws BusinessLogicException {
381
382         final Either<Boolean, ResponseFormat> response = nodeFilterValidator
383             .validateComponentInstanceExist(component, componentInstanceId);
384         if (response.isRight()) {
385             throw new BusinessLogicException(componentsUtils
386                 .getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
387         }
388         final Optional<ComponentInstance> componentInstance = getComponentInstance(componentInstanceId, component);
389         if (componentInstance.isPresent()) {
390             return Optional.ofNullable(componentInstance.get().getNodeFilter());
391         }
392         return Optional.empty();
393     }
394
395     private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(
396         final String constraint) {
397
398         final RequirementNodeFilterPropertyDataDefinition pdd = new RequirementNodeFilterPropertyDataDefinition();
399         pdd.setConstraints(Arrays.asList(constraint));
400         return pdd;
401     }
402
403     private CINodeFilterDataDefinition validateAndReturnNodeFilterDefinition(final String componentInstanceId,
404                                                                              final NodeFilterConstraintAction action,
405                                                                              final String constraint,
406                                                                              final Component component)
407         throws BusinessLogicException {
408
409         validateNodeFilter(component, componentInstanceId, action, constraint);
410         final Optional<CINodeFilterDataDefinition> cINodeFilterDataDefinition = getCiNodeFilterDataDefinition(
411             componentInstanceId, component);
412         if (!cINodeFilterDataDefinition.isPresent()) {
413             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
414         }
415         return cINodeFilterDataDefinition.get();
416     }
417
418     private void validateNodeFilter(final Component component,
419                                     final String componentInstanceId,
420                                     final NodeFilterConstraintAction action,
421                                     final String constraint) throws BusinessLogicException {
422         final Either<Boolean, ResponseFormat> response = nodeFilterValidator
423             .validateFilter(component, componentInstanceId, Collections.singletonList(constraint), action);
424         if (response.isRight()) {
425             throw new BusinessLogicException(componentsUtils
426                 .getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
427         }
428     }
429 }