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