57571c0b4938a1df36e81d5ed54331920f094a7b
[sdc.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  *  Copyright (C) 2021 Nordix Foundation. All rights reserved.
6  *  ================================================================================
7  *  Licensed under the Apache License, Version 2.0 (the "License");
8  *  you may not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.zone-instance.component.ts
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  *  SPDX-License-Identifier: Apache-2.0
19  *  ============LICENSE_END=========================================================
20  */
21 package org.openecomp.sdc.be.components.impl;
22
23 import fj.data.Either;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Optional;
29 import org.apache.commons.collections.CollectionUtils;
30 import org.apache.commons.collections.MapUtils;
31 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
32 import org.openecomp.sdc.be.components.validation.ComponentValidations;
33 import org.openecomp.sdc.be.dao.api.ActionStatus;
34 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
35 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
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.ComponentInstanceInterface;
40 import org.openecomp.sdc.be.model.ComponentParametersView;
41 import org.openecomp.sdc.be.model.InterfaceDefinition;
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.operations.api.IElementOperation;
46 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
47 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
48 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
49 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
50 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
51 import org.openecomp.sdc.be.user.Role;
52 import org.openecomp.sdc.common.datastructure.Wrapper;
53 import org.openecomp.sdc.exception.ResponseFormat;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56 import org.springframework.beans.factory.annotation.Autowired;
57
58 @org.springframework.stereotype.Component("componentInterfaceOperationBusinessLogic")
59 public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic {
60
61     private static final Logger LOGGER = LoggerFactory.getLogger(ComponentInterfaceOperationBusinessLogic.class);
62     private final ComponentValidations componentValidations;
63
64     @Autowired
65     public ComponentInterfaceOperationBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation,
66                                                     final IGroupInstanceOperation groupInstanceOperation,
67                                                     final IGroupTypeOperation groupTypeOperation, final InterfaceOperation interfaceOperation,
68                                                     final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
69                                                     final ArtifactsOperations artifactToscaOperation,
70                                                     final ComponentValidations componentValidations) {
71         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
72             artifactToscaOperation);
73         this.componentValidations = componentValidations;
74     }
75
76     public Optional<ComponentInstance> updateComponentInstanceInterfaceOperation(final String componentId, final String componentInstanceId,
77                                                                                  final InterfaceDefinition interfaceDefinition,
78                                                                                  final ComponentTypeEnum componentTypeEnum,
79                                                                                  final Wrapper<ResponseFormat> errorWrapper, final boolean shouldLock)
80         throws BusinessLogicException {
81         final Component component = getComponent(componentId);
82         final Optional<ComponentInstance> componentInstanceOptional = componentValidations.getComponentInstance(component, componentInstanceId);
83         ResponseFormat responseFormat;
84         if (componentInstanceOptional.isEmpty()) {
85             responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND);
86             LOGGER.debug("Failed to found component instance with id {}, error: {}", componentInstanceId, responseFormat);
87             errorWrapper.setInnerElement(responseFormat);
88             return Optional.empty();
89         }
90         Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaceMap = component.getComponentInstancesInterfaces();
91         if (MapUtils.isEmpty(componentInstancesInterfaceMap)) {
92             componentInstancesInterfaceMap = new HashMap<>();
93             component.setComponentInstancesInterfaces(componentInstancesInterfaceMap);
94         }
95         final List<ComponentInstanceInterface> componentInstanceInterfaceList = componentInstancesInterfaceMap.get(componentInstanceId);
96         if (CollectionUtils.isEmpty(componentInstanceInterfaceList)) {
97             responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND);
98             LOGGER.debug("Failed to found component instance with id {}, error: {}", componentInstanceId, responseFormat);
99             errorWrapper.setInnerElement(responseFormat);
100             return Optional.empty();
101         }
102         final Optional<OperationDataDefinition> optionalOperationDataDefinition = interfaceDefinition.getOperations().values().stream().findFirst();
103         if (optionalOperationDataDefinition.isEmpty()) {
104             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
105             LOGGER.debug("Failed to found interface operation on component instance with id {}, error: {}", componentInstanceId, responseFormat);
106             errorWrapper.setInnerElement(responseFormat);
107             return Optional.empty();
108         }
109         final OperationDataDefinition updatedOperationDataDefinition = optionalOperationDataDefinition.get();
110         final Optional<ComponentInstanceInterface> optionalComponentInstanceInterface = componentInstanceInterfaceList.stream().filter(
111                 ci -> ci.getOperations().values().stream().anyMatch(
112                     operationDataDefinition -> operationDataDefinition.getUniqueId().equalsIgnoreCase(updatedOperationDataDefinition.getUniqueId())))
113             .findFirst();
114         if (optionalComponentInstanceInterface.isEmpty()) {
115             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT);
116             LOGGER
117                 .debug("Failed to found ComponentInstanceInterface on component instance with id {}, error: {}", componentInstanceId, responseFormat);
118             errorWrapper.setInnerElement(responseFormat);
119             return Optional.empty();
120         }
121         updateOperationDefinitionImplementation(updatedOperationDataDefinition);
122         optionalComponentInstanceInterface.get().getOperations().replace(updatedOperationDataDefinition.getName(), updatedOperationDataDefinition);
123         boolean wasLocked = false;
124         try {
125             if (shouldLock) {
126                 lockComponent(componentId, component, "Update Interface Operation on Component instance");
127                 wasLocked = true;
128             }
129             final StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(component, componentInstanceId);
130             if (status != StorageOperationStatus.OK) {
131                 janusGraphDao.rollback();
132                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
133                 LOGGER.error("Exception occurred when updating Component Instance Interfaces {}", responseFormat);
134                 errorWrapper.setInnerElement(responseFormat);
135                 return Optional.empty();
136             }
137             final ComponentParametersView componentFilter = new ComponentParametersView();
138             componentFilter.disableAll();
139             componentFilter.setIgnoreUsers(false);
140             componentFilter.setIgnoreComponentInstances(false);
141             componentFilter.setIgnoreInterfaces(false);
142             componentFilter.setIgnoreComponentInstancesInterfaces(false);
143             final Either<Component, StorageOperationStatus> operationStatusEither = toscaOperationFacade
144                 .updateComponentInstanceMetadataOfTopologyTemplate(component, componentFilter);
145             if (operationStatusEither.isRight()) {
146                 janusGraphDao.rollback();
147                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
148                 LOGGER.error("Exception occurred when updating Component Instance Topology template {}", responseFormat);
149                 errorWrapper.setInnerElement(responseFormat);
150                 return Optional.empty();
151             }
152             janusGraphDao.commit();
153         } catch (final Exception e) {
154             janusGraphDao.rollback();
155             LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: {}", e.getMessage(), e);
156             responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
157             errorWrapper.setInnerElement(responseFormat);
158             throw new BusinessLogicException(responseFormat);
159         } finally {
160             if (wasLocked) {
161                 unlockComponent(component.getUniqueId(), componentTypeEnum);
162             }
163         }
164         return componentInstanceOptional;
165     }
166
167     public Optional<Component> updateResourceInterfaceOperation(final String componentId,
168                                                                 final InterfaceDefinition interfaceDefinition,
169                                                                 final ComponentTypeEnum componentTypeEnum,
170                                                                 final Wrapper<ResponseFormat> errorWrapper,
171                                                                 final boolean shouldLock) throws BusinessLogicException {
172         final var component = getComponent(componentId);
173         ResponseFormat responseFormat;
174
175         Map<String, InterfaceDefinition> componentInterfaceMap = component.getInterfaces();
176         final String interfaceDefinitionType = interfaceDefinition.getType();
177         if (MapUtils.isEmpty(componentInterfaceMap)) {
178             componentInterfaceMap = new HashMap<>();
179             componentInterfaceMap.put(interfaceDefinitionType, interfaceDefinition);
180             component.setInterfaces(componentInterfaceMap);
181         } else {
182             InterfaceDefinition componentInterfaceDefinition = componentInterfaceMap.get(interfaceDefinitionType);
183             if (componentInterfaceDefinition == null) {
184                 componentInterfaceDefinition = interfaceDefinition;
185                 componentInterfaceMap.put(interfaceDefinitionType, interfaceDefinition);
186             }
187
188             final Map<String, OperationDataDefinition> interfaceDefinitionOperations = interfaceDefinition.getOperations();
189             final Optional<OperationDataDefinition> optionalOperationDataDefinition = interfaceDefinitionOperations.values().stream().findFirst();
190             if (optionalOperationDataDefinition.isEmpty()) {
191                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
192                 LOGGER.debug("Failed to found interface operation on provided InterfaceDefinition {}, error: {}",
193                     interfaceDefinitionType, responseFormat);
194                 errorWrapper.setInnerElement(responseFormat);
195                 return Optional.empty();
196             }
197             final var updatedOperationDataDefinition = optionalOperationDataDefinition.get();
198             updateOperationDefinitionImplementation(updatedOperationDataDefinition);
199             Map<String, OperationDataDefinition> componentOperationDataDefinitionMap = componentInterfaceDefinition.getOperations();
200             if (MapUtils.isEmpty(componentOperationDataDefinitionMap)) {
201                 componentOperationDataDefinitionMap = new HashMap<>();
202                 componentInterfaceDefinition.setOperations(componentOperationDataDefinitionMap);
203             }
204             componentOperationDataDefinitionMap.replace(updatedOperationDataDefinition.getName(), updatedOperationDataDefinition);
205         }
206         boolean wasLocked = false;
207         try {
208             if (shouldLock) {
209                 lockComponent(componentId, component, "Update Interface Operation on Component instance");
210                 wasLocked = true;
211             }
212             final StorageOperationStatus status =
213                 toscaOperationFacade.updateComponentInterfaces(component.getUniqueId(), component.getInterfaces(), interfaceDefinitionType);
214             if (status != StorageOperationStatus.OK) {
215                 janusGraphDao.rollback();
216                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
217                 LOGGER.error("Exception occurred when updating Component Instance Interfaces {}", responseFormat);
218                 errorWrapper.setInnerElement(responseFormat);
219                 return Optional.empty();
220             }
221             janusGraphDao.commit();
222         } catch (final Exception e) {
223             janusGraphDao.rollback();
224             LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: ", e);
225             responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
226             errorWrapper.setInnerElement(responseFormat);
227             throw new BusinessLogicException(responseFormat);
228         } finally {
229             if (wasLocked) {
230                 unlockComponent(component.getUniqueId(), componentTypeEnum);
231             }
232         }
233         return Optional.of(component);
234     }
235
236     public User validateUser(final String userId) {
237         final User user = userValidations.validateUserExists(userId);
238         userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
239         return user;
240     }
241
242     private void unlockComponent(final String componentUniqueId, final ComponentTypeEnum componentType) {
243         graphLockOperation.unlockComponent(componentUniqueId, componentType.getNodeType());
244     }
245
246     private void updateOperationDefinitionImplementation(final OperationDataDefinition updatedOperationDataDefinition) {
247         final ArtifactDataDefinition artifactInfo = new ArtifactDataDefinition(updatedOperationDataDefinition.getImplementation());
248         artifactInfo.setArtifactName(String.format("'%s'", updatedOperationDataDefinition.getImplementation().getArtifactName()));
249         updatedOperationDataDefinition.setImplementation(artifactInfo);
250     }
251 }