Fix for substitution filter properties
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ComponentSubstitutionFilterBusinessLogic.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.be.dao.api.ActionStatus.SUBSTITUTION_FILTER_NOT_FOUND;
23 import static org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR;
24
25 import fj.data.Either;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.Optional;
30 import java.util.stream.Collectors;
31 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
32 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
33 import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
34 import org.openecomp.sdc.be.dao.api.ActionStatus;
35 import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
37 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
38 import org.openecomp.sdc.be.model.Component;
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.SubstitutionFilterOperation;
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("componentSubstitutionFilterBusinessLogic")
55 public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic {
56
57     private static final Logger LOGGER = Logger.getLogger(ComponentSubstitutionFilterBusinessLogic.class);
58
59     private final SubstitutionFilterOperation substitutionFilterOperation;
60     private final NodeFilterValidator nodeFilterValidator;
61
62     @Autowired
63     public ComponentSubstitutionFilterBusinessLogic(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 SubstitutionFilterOperation substitutionFilterOperation,
71                                                     NodeFilterValidator nodeFilterValidator)
72                                                      {
73         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation,
74             interfaceLifecycleTypeOperation, artifactToscaOperation);
75         this.substitutionFilterOperation = substitutionFilterOperation;
76         this.nodeFilterValidator = nodeFilterValidator;
77     }
78
79     public Optional<SubstitutionFilterDataDefinition> createSubstitutionFilterIfNotExist(final String componentId,
80                                                                                          final boolean shouldLock,
81                                                                                          final ComponentTypeEnum componentTypeEnum)
82             throws BusinessLogicException {
83
84         final Component component = getComponent(componentId);
85         Optional<SubstitutionFilterDataDefinition> substitutionFilterDataDefinition = Optional.ofNullable(component.getSubstitutionFilter());
86         if (substitutionFilterDataDefinition.isPresent()) {
87             return substitutionFilterDataDefinition;
88         }
89         boolean wasLocked = false;
90         try {
91             if (shouldLock) {
92                 lockComponent(component.getUniqueId(), component, "Create Substitution Filter on component");
93                 wasLocked = true;
94             }
95             final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> result = substitutionFilterOperation
96                     .createSubstitutionFilter(componentId);
97             if (result.isRight()) {
98                 janusGraphDao.rollback();
99                 LOGGER.error(BUSINESS_PROCESS_ERROR,
100                         "Failed to Create Substitution filter on component with id {}", componentId);
101                 throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils
102                         .convertFromStorageResponse(result.right().value()), component.getSystemName()));
103             }
104             substitutionFilterDataDefinition = Optional.ofNullable(result.left().value());
105             component.setSubstitutionFilter(substitutionFilterDataDefinition.get());
106             janusGraphDao.commit();
107             LOGGER.debug("Substitution filter successfully created in component {} . ", component.getSystemName());
108         } catch (final Exception e) {
109             janusGraphDao.rollback();
110             LOGGER.error(BUSINESS_PROCESS_ERROR,
111                     "Exception occurred during add Component Substitution filter property values: {}", e.getMessage(), e);
112             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
113
114         } finally {
115             if (wasLocked) {
116                 unlockComponent(component.getUniqueId(), componentTypeEnum);
117             }
118         }
119
120         return substitutionFilterDataDefinition;
121     }
122
123     public Optional<SubstitutionFilterDataDefinition> addSubstitutionFilter(final String componentId,
124                                                                             final String propertyName,
125                                                                             final String constraint,
126                                                                             final boolean shouldLock,
127                                                                             final ComponentTypeEnum componentTypeEnum)
128         throws BusinessLogicException {
129
130         final Component component = getComponent(componentId);
131
132         final Either<Boolean, ResponseFormat> response = nodeFilterValidator
133                 .validateComponentFilter(component, Collections.singletonList(constraint), NodeFilterConstraintAction.ADD);
134         if (response.isRight()) {
135             throw new BusinessLogicException(componentsUtils
136                     .getResponseFormat(ActionStatus.SUBSTITUTION_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
137         }
138
139         boolean wasLocked = false;
140         try {
141             if (shouldLock) {
142                 lockComponent(component.getUniqueId(), component, "Add Substitution Filter on Component");
143                 wasLocked = true;
144             }
145             final RequirementSubstitutionFilterPropertyDataDefinition newProperty =
146                 new RequirementSubstitutionFilterPropertyDataDefinition();
147             newProperty.setName(propertyName);
148             newProperty.setConstraints(Collections.singletonList(constraint));
149             final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> resultEither =
150                 substitutionFilterOperation
151                     .addPropertyFilter(componentId, component.getSubstitutionFilter(), newProperty);
152
153             if (resultEither.isRight()) {
154                 janusGraphDao.rollback();
155                 throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils
156                     .convertFromStorageResponse(resultEither.right().value()), component.getSystemName()));
157             }
158
159             janusGraphDao.commit();
160             LOGGER.debug("Substitution filter successfully created in component {} . ", component.getSystemName());
161             return Optional.ofNullable(resultEither.left().value());
162         } catch (final Exception e) {
163             janusGraphDao.rollback();
164             LOGGER.error(BUSINESS_PROCESS_ERROR,
165                 "Exception occurred during add component substitution filter property values: {}", e.getMessage(), e);
166             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
167
168         } finally {
169             if (wasLocked) {
170                 unlockComponent(component.getUniqueId(), componentTypeEnum);
171             }
172         }
173
174     }
175
176     public Optional<SubstitutionFilterDataDefinition> updateSubstitutionFilter(final String componentId,
177                                                                                final List<String> constraints,
178                                                                                final boolean shouldLock,
179                                                                                final ComponentTypeEnum componentTypeEnum)
180         throws BusinessLogicException {
181
182         final Component component = getComponent(componentId);
183
184         final Either<Boolean, ResponseFormat> response = nodeFilterValidator
185                 .validateComponentFilter(component, constraints, NodeFilterConstraintAction.UPDATE);
186         if (response.isRight()) {
187             throw new BusinessLogicException(componentsUtils
188                     .getResponseFormat(ActionStatus.SUBSTITUTION_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
189         }
190
191         SubstitutionFilterDataDefinition substitutionFilterDataDefinition = component.getSubstitutionFilter();
192         if (substitutionFilterDataDefinition == null) {
193             throw new BusinessLogicException(componentsUtils.getResponseFormat(SUBSTITUTION_FILTER_NOT_FOUND));
194         }
195         boolean wasLocked = false;
196         try {
197             if (shouldLock) {
198                 lockComponent(component.getUniqueId(), component, "Update Substitution Filter on Component");
199                 wasLocked = true;
200             }
201             final List<RequirementSubstitutionFilterPropertyDataDefinition> properties = constraints.stream()
202                     .map(this::getRequirementSubstitutionFilterPropertyDataDefinition).collect(Collectors.toList());
203             final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> result = substitutionFilterOperation
204                     .updateProperties(componentId, substitutionFilterDataDefinition, properties);
205
206             if (result.isRight()) {
207                 janusGraphDao.rollback();
208                 throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils
209                     .convertFromStorageResponse(result.right().value()), component.getSystemName()));
210             } else {
211                 substitutionFilterDataDefinition = result.left().value();
212             }
213             janusGraphDao.commit();
214             LOGGER.debug("Substitution filter successfully updated in component {} . ", component.getSystemName());
215
216         } catch (final Exception e) {
217             janusGraphDao.rollback();
218             LOGGER.error(BUSINESS_PROCESS_ERROR, this.getClass().getName(),
219                 "Exception occurred during update component substitution filter property values: {}", e);
220             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
221
222         } finally {
223             if (wasLocked) {
224                 unlockComponent(component.getUniqueId(), componentTypeEnum);
225             }
226         }
227         return Optional.ofNullable(substitutionFilterDataDefinition);
228     }
229
230     public Optional<SubstitutionFilterDataDefinition> deleteSubstitutionFilter(final String componentId,
231                                                                                final int position,
232                                                                                final boolean shouldLock,
233                                                                                final ComponentTypeEnum componentTypeEnum)
234         throws BusinessLogicException {
235
236         final Component component = getComponent(componentId);
237         SubstitutionFilterDataDefinition substitutionFilterDataDefinition = component.getSubstitutionFilter();
238         boolean wasLocked = false;
239         try {
240             if (shouldLock) {
241                 lockComponent(component.getUniqueId(), component,"Add Node Filter on Component");
242                 wasLocked = true;
243             }
244             final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> result = substitutionFilterOperation
245                 .deleteConstraint(componentId, substitutionFilterDataDefinition, position);
246             if (result.isRight()) {
247                 janusGraphDao.rollback();
248                 throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils
249                     .convertFromStorageResponse(result.right().value()), component.getSystemName()));
250             } else {
251                 substitutionFilterDataDefinition = result.left().value();
252             }
253             janusGraphDao.commit();
254             LOGGER.debug("Substitution filter successfully deleted in component {} . ", component.getSystemName());
255
256         } catch (final Exception e) {
257             janusGraphDao.rollback();
258             LOGGER.error(BUSINESS_PROCESS_ERROR,
259                 "Exception occurred during delete component substitution filter property values: {}",
260                 e.getMessage(), e);
261             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
262
263         } finally {
264             if (wasLocked) {
265                 unlockComponent(component.getUniqueId(), componentTypeEnum);
266             }
267         }
268         return Optional.ofNullable(substitutionFilterDataDefinition);
269     }
270
271     private void unlockComponent(final String componentUniqueId,
272                                  final ComponentTypeEnum componentType) {
273         graphLockOperation.unlockComponent(componentUniqueId, componentType.getNodeType());
274     }
275
276     public User validateUser(final String userId) {
277         final User user = userValidations.validateUserExists(userId);
278         userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
279         return user;
280     }
281
282     private RequirementSubstitutionFilterPropertyDataDefinition getRequirementSubstitutionFilterPropertyDataDefinition(
283         final String constraint) {
284
285         final RequirementSubstitutionFilterPropertyDataDefinition requirementSubstitutionFilterPropertyDataDefinition =
286             new RequirementSubstitutionFilterPropertyDataDefinition();
287         requirementSubstitutionFilterPropertyDataDefinition.setConstraints(Arrays.asList(constraint));
288         return requirementSubstitutionFilterPropertyDataDefinition;
289     }
290 }