Consider model in generic substitution type query
[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.List;
27 import java.util.Optional;
28 import java.util.stream.Collectors;
29 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
30 import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
31 import org.openecomp.sdc.be.dao.api.ActionStatus;
32 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
33 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition;
34 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
35 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
36 import org.openecomp.sdc.be.model.Component;
37 import org.openecomp.sdc.be.model.User;
38 import org.openecomp.sdc.be.model.dto.FilterConstraintDto;
39 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
40 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
41 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.SubstitutionFilterOperation;
42 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
43 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
44 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
45 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
46 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
47 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
48 import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper;
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,
115                                                                             final FilterConstraintDto filterConstraint, final boolean shouldLock,
116                                                                             final ComponentTypeEnum componentTypeEnum) throws BusinessLogicException {
117         final Component component = getComponent(componentId);
118         final Either<Boolean, ResponseFormat> response = nodeFilterValidator.validateSubstitutionFilter(component, filterConstraint);
119         if (response.isRight()) {
120             throw new BusinessLogicException(
121                 componentsUtils.getResponseFormat(ActionStatus.SUBSTITUTION_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
122         }
123         boolean wasLocked = false;
124         try {
125             if (shouldLock) {
126                 lockComponent(component.getUniqueId(), component, "Add Substitution Filter on Component");
127                 wasLocked = true;
128             }
129             final SubstitutionFilterPropertyDataDefinition newProperty = new SubstitutionFilterPropertyDataDefinition();
130             newProperty.setName(filterConstraint.getPropertyName());
131             newProperty.setConstraints(List.of(new FilterConstraintMapper().mapTo(filterConstraint)));
132             final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> resultEither = substitutionFilterOperation
133                 .addPropertyFilter(componentId, component.getSubstitutionFilter(), newProperty);
134             if (resultEither.isRight()) {
135                 janusGraphDao.rollback();
136                 throw new BusinessLogicException(componentsUtils
137                     .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(resultEither.right().value()),
138                         component.getSystemName()));
139             }
140             janusGraphDao.commit();
141             LOGGER.debug("Substitution filter successfully created in component {} . ", component.getSystemName());
142             return Optional.ofNullable(resultEither.left().value());
143         } catch (final Exception e) {
144             janusGraphDao.rollback();
145             LOGGER
146                 .error(BUSINESS_PROCESS_ERROR, "Exception occurred during add component substitution filter property values: {}", e.getMessage(), e);
147             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
148         } finally {
149             if (wasLocked) {
150                 unlockComponent(component.getUniqueId(), componentTypeEnum);
151             }
152         }
153     }
154
155     public Optional<SubstitutionFilterDataDefinition> updateSubstitutionFilter(final String componentId, final List<FilterConstraintDto> constraints,
156                                                                                final boolean shouldLock,
157                                                                                final ComponentTypeEnum componentTypeEnum) throws BusinessLogicException {
158         final Component component = getComponent(componentId);
159         final Either<Boolean, ResponseFormat> response = nodeFilterValidator.validateSubstitutionFilter(component, constraints);
160         if (response.isRight()) {
161             throw new BusinessLogicException(
162                 componentsUtils.getResponseFormat(ActionStatus.SUBSTITUTION_FILTER_NOT_FOUND, response.right().value().getFormattedMessage()));
163         }
164         SubstitutionFilterDataDefinition substitutionFilterDataDefinition = component.getSubstitutionFilter();
165         if (substitutionFilterDataDefinition == null) {
166             throw new BusinessLogicException(componentsUtils.getResponseFormat(SUBSTITUTION_FILTER_NOT_FOUND));
167         }
168         boolean wasLocked = false;
169         try {
170             if (shouldLock) {
171                 lockComponent(component.getUniqueId(), component, "Update Substitution Filter on Component");
172                 wasLocked = true;
173             }
174             final List<SubstitutionFilterPropertyDataDefinition> properties = constraints.stream()
175                 .map(this::buildSubstitutionFilterPropertyDataDefinition).collect(Collectors.toList());
176             final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> result = substitutionFilterOperation
177                 .updatePropertyFilters(componentId, substitutionFilterDataDefinition, properties);
178             if (result.isRight()) {
179                 janusGraphDao.rollback();
180                 throw new BusinessLogicException(componentsUtils
181                     .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()));
182             } else {
183                 substitutionFilterDataDefinition = result.left().value();
184             }
185             janusGraphDao.commit();
186             LOGGER.debug("Substitution filter successfully updated in component {} . ", component.getSystemName());
187         } catch (final Exception e) {
188             janusGraphDao.rollback();
189             LOGGER.error(BUSINESS_PROCESS_ERROR, this.getClass().getName(),
190                 "Exception occurred during update component substitution filter property values: {}", e);
191             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
192         } finally {
193             if (wasLocked) {
194                 unlockComponent(component.getUniqueId(), componentTypeEnum);
195             }
196         }
197         return Optional.ofNullable(substitutionFilterDataDefinition);
198     }
199
200     public Optional<SubstitutionFilterDataDefinition> updateSubstitutionFilter(final String componentId, final FilterConstraintDto filterConstraint,
201                                                                                final int index,
202                                                                                final boolean shouldLock) throws BusinessLogicException {
203         final Component component = getComponent(componentId);
204         final Either<Boolean, ResponseFormat> validationResponse = nodeFilterValidator.validateSubstitutionFilter(component, filterConstraint);
205         if (validationResponse.isRight()) {
206             throw new BusinessLogicException(validationResponse.right().value());
207         }
208         final SubstitutionFilterDataDefinition substitutionFilterDataDefinition = component.getSubstitutionFilter();
209         if (substitutionFilterDataDefinition == null) {
210             throw new BusinessLogicException(componentsUtils.getResponseFormat(SUBSTITUTION_FILTER_NOT_FOUND, component.getName()));
211         }
212         boolean wasLocked = false;
213         try {
214             if (shouldLock) {
215                 lockComponent(component.getUniqueId(), component, "Update Substitution Filter on Component");
216                 wasLocked = true;
217             }
218             final SubstitutionFilterPropertyDataDefinition substitutionFilterProperty =
219                 buildSubstitutionFilterPropertyDataDefinition(filterConstraint);
220             final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> result =
221                 substitutionFilterOperation.updatePropertyFilter(componentId, substitutionFilterDataDefinition, substitutionFilterProperty, index);
222             if (result.isRight()) {
223                 janusGraphDao.rollback();
224                 throw new BusinessLogicException(
225                     componentsUtils.getResponseFormatByResource(
226                         componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()
227                     )
228                 );
229             }
230             janusGraphDao.commit();
231             LOGGER.debug("Substitution filter successfully updated in component {} . ", component.getSystemName());
232             return Optional.ofNullable(result.left().value());
233         } catch (final Exception e) {
234             janusGraphDao.rollback();
235             LOGGER.error(BUSINESS_PROCESS_ERROR, this.getClass().getName(),
236                 "Exception occurred during update component substitution filter property values: {}", e);
237             throw e;
238         } finally {
239             if (wasLocked) {
240                 unlockComponent(component.getUniqueId(), component.getComponentType());
241             }
242         }
243     }
244
245     public Optional<SubstitutionFilterDataDefinition> deleteSubstitutionFilter(final String componentId, final int position, final boolean shouldLock,
246                                                                                final ComponentTypeEnum componentTypeEnum)
247         throws BusinessLogicException {
248         final Component component = getComponent(componentId);
249         SubstitutionFilterDataDefinition substitutionFilterDataDefinition = component.getSubstitutionFilter();
250         boolean wasLocked = false;
251         try {
252             if (shouldLock) {
253                 lockComponent(component.getUniqueId(), component, "Delete substitution Filter on Component");
254                 wasLocked = true;
255             }
256             final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> result = substitutionFilterOperation
257                 .deleteConstraint(componentId, substitutionFilterDataDefinition, position);
258             if (result.isRight()) {
259                 janusGraphDao.rollback();
260                 throw new BusinessLogicException(componentsUtils
261                     .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName()));
262             } else {
263                 substitutionFilterDataDefinition = result.left().value();
264             }
265             janusGraphDao.commit();
266             LOGGER.debug("Substitution filter successfully deleted in component {} . ", component.getSystemName());
267         } catch (final Exception e) {
268             janusGraphDao.rollback();
269             LOGGER.error(BUSINESS_PROCESS_ERROR, "Exception occurred during delete component substitution filter property values: {}", e.getMessage(),
270                 e);
271             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
272         } finally {
273             if (wasLocked) {
274                 unlockComponent(component.getUniqueId(), componentTypeEnum);
275             }
276         }
277         return Optional.ofNullable(substitutionFilterDataDefinition);
278     }
279
280     private void unlockComponent(final String componentUniqueId, final ComponentTypeEnum componentType) {
281         graphLockOperation.unlockComponent(componentUniqueId, componentType.getNodeType());
282     }
283
284     public User validateUser(final String userId) {
285         final User user = userValidations.validateUserExists(userId);
286         userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
287         return user;
288     }
289
290     private SubstitutionFilterPropertyDataDefinition buildSubstitutionFilterPropertyDataDefinition(final FilterConstraintDto filterConstraint) {
291         final var substitutionFilterProperty = new SubstitutionFilterPropertyDataDefinition();
292         substitutionFilterProperty.setName(filterConstraint.getPropertyName());
293         substitutionFilterProperty.setConstraints(List.of(new FilterConstraintMapper().mapTo(filterConstraint)));
294         return substitutionFilterProperty;
295     }
296
297     public void addSubstitutionFilterInGraph(String componentId,
298                                              ListDataDefinition<SubstitutionFilterPropertyDataDefinition> substitutionFilterProperties)
299         throws BusinessLogicException {
300         Either<SubstitutionFilterDataDefinition, StorageOperationStatus> updateSubstitutionFilter;
301         Optional<SubstitutionFilterDataDefinition> substitutionFilter = createSubstitutionFilterIfNotExist(componentId, true,
302             ComponentTypeEnum.SERVICE);
303         if (substitutionFilter.isPresent()) {
304             for (SubstitutionFilterPropertyDataDefinition filter : substitutionFilterProperties.getListToscaDataDefinition()) {
305                 updateSubstitutionFilter = substitutionFilterOperation.addPropertyFilter(componentId, substitutionFilter.get(), filter);
306                 if (updateSubstitutionFilter.isRight()) {
307                     throw new BusinessLogicException(componentsUtils
308                         .getResponseFormat(componentsUtils.convertFromStorageResponse(updateSubstitutionFilter.right().value())));
309                 }
310             }
311         }
312     }
313
314 }