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