2 * ============LICENSE_START=======================================================
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
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.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.components.impl;
23 import fj.data.Either;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.List;
28 import java.util.Optional;
29 import java.util.UUID;
30 import org.apache.commons.collections.CollectionUtils;
31 import org.apache.commons.collections.MapUtils;
32 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
33 import org.openecomp.sdc.be.components.validation.ComponentValidations;
34 import org.openecomp.sdc.be.dao.api.ActionStatus;
35 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
37 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
38 import org.openecomp.sdc.be.model.Component;
39 import org.openecomp.sdc.be.model.ComponentInstance;
40 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
41 import org.openecomp.sdc.be.model.ComponentParametersView;
42 import org.openecomp.sdc.be.model.InterfaceDefinition;
43 import org.openecomp.sdc.be.model.User;
44 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
45 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
46 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
47 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
48 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
49 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
50 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
51 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
52 import org.openecomp.sdc.be.user.Role;
53 import org.openecomp.sdc.common.datastructure.Wrapper;
54 import org.openecomp.sdc.exception.ResponseFormat;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57 import org.springframework.beans.factory.annotation.Autowired;
59 @org.springframework.stereotype.Component("componentInterfaceOperationBusinessLogic")
60 public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic {
62 private static final Logger LOGGER = LoggerFactory.getLogger(ComponentInterfaceOperationBusinessLogic.class);
63 private final ComponentValidations componentValidations;
66 public ComponentInterfaceOperationBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation,
67 final IGroupInstanceOperation groupInstanceOperation,
68 final IGroupTypeOperation groupTypeOperation, final InterfaceOperation interfaceOperation,
69 final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
70 final ArtifactsOperations artifactToscaOperation,
71 final ComponentValidations componentValidations) {
72 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
73 artifactToscaOperation);
74 this.componentValidations = componentValidations;
77 public Optional<ComponentInstance> updateComponentInstanceInterfaceOperation(final String componentId, final String componentInstanceId,
78 final InterfaceDefinition interfaceDefinition,
79 final ComponentTypeEnum componentTypeEnum,
80 final Wrapper<ResponseFormat> errorWrapper, final boolean shouldLock)
81 throws BusinessLogicException {
82 final Component component = getComponent(componentId);
83 final Optional<ComponentInstance> componentInstanceOptional = componentValidations.getComponentInstance(component, componentInstanceId);
84 ResponseFormat responseFormat;
85 if (componentInstanceOptional.isEmpty()) {
86 responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND);
87 LOGGER.debug("Failed to found component instance with id {}, error: {}", componentInstanceId, responseFormat);
88 errorWrapper.setInnerElement(responseFormat);
89 return Optional.empty();
91 Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaceMap = component.getComponentInstancesInterfaces();
92 if (MapUtils.isEmpty(componentInstancesInterfaceMap)) {
93 componentInstancesInterfaceMap = new HashMap<>();
94 component.setComponentInstancesInterfaces(componentInstancesInterfaceMap);
96 final List<ComponentInstanceInterface> componentInstanceInterfaceList = componentInstancesInterfaceMap.get(componentInstanceId);
97 if (CollectionUtils.isEmpty(componentInstanceInterfaceList)) {
98 responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND);
99 LOGGER.debug("Failed to found component instance with id {}, error: {}", componentInstanceId, responseFormat);
100 errorWrapper.setInnerElement(responseFormat);
101 return Optional.empty();
103 final Optional<OperationDataDefinition> optionalOperationDataDefinition = interfaceDefinition.getOperations().values().stream().findFirst();
104 if (optionalOperationDataDefinition.isEmpty()) {
105 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
106 LOGGER.debug("Failed to found interface operation on component instance with id {}, error: {}", componentInstanceId, responseFormat);
107 errorWrapper.setInnerElement(responseFormat);
108 return Optional.empty();
110 final OperationDataDefinition updatedOperationDataDefinition = optionalOperationDataDefinition.get();
111 final Optional<ComponentInstanceInterface> optionalComponentInstanceInterface = componentInstanceInterfaceList.stream().filter(
112 ci -> ci.getOperations().values().stream().anyMatch(
113 operationDataDefinition -> operationDataDefinition.getUniqueId().equalsIgnoreCase(updatedOperationDataDefinition.getUniqueId())))
115 if (optionalComponentInstanceInterface.isEmpty()) {
116 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT);
118 .debug("Failed to found ComponentInstanceInterface on component instance with id {}, error: {}", componentInstanceId, responseFormat);
119 errorWrapper.setInnerElement(responseFormat);
120 return Optional.empty();
122 updateOperationDefinitionImplementation(updatedOperationDataDefinition);
123 optionalComponentInstanceInterface.get().getOperations().replace(updatedOperationDataDefinition.getName(), updatedOperationDataDefinition);
124 boolean wasLocked = false;
127 lockComponent(componentId, component, "Update Interface Operation on Component instance");
130 final StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(component, componentInstanceId);
131 if (status != StorageOperationStatus.OK) {
132 janusGraphDao.rollback();
133 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
134 LOGGER.error("Exception occurred when updating Component Instance Interfaces {}", responseFormat);
135 errorWrapper.setInnerElement(responseFormat);
136 return Optional.empty();
138 final ComponentParametersView componentFilter = new ComponentParametersView();
139 componentFilter.disableAll();
140 componentFilter.setIgnoreUsers(false);
141 componentFilter.setIgnoreComponentInstances(false);
142 componentFilter.setIgnoreInterfaces(false);
143 componentFilter.setIgnoreComponentInstancesInterfaces(false);
144 final Either<Component, StorageOperationStatus> operationStatusEither = toscaOperationFacade
145 .updateComponentInstanceMetadataOfTopologyTemplate(component, componentFilter);
146 if (operationStatusEither.isRight()) {
147 janusGraphDao.rollback();
148 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
149 LOGGER.error("Exception occurred when updating Component Instance Topology template {}", responseFormat);
150 errorWrapper.setInnerElement(responseFormat);
151 return Optional.empty();
153 janusGraphDao.commit();
154 } catch (final Exception e) {
155 janusGraphDao.rollback();
156 LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: {}", e.getMessage(), e);
157 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
158 errorWrapper.setInnerElement(responseFormat);
159 throw new BusinessLogicException(responseFormat);
162 unlockComponent(component.getUniqueId(), componentTypeEnum);
165 return componentInstanceOptional;
168 public Optional<Component> updateResourceInterfaceOperation(final String componentId,
170 final InterfaceDefinition interfaceDefinition,
171 final ComponentTypeEnum componentTypeEnum,
172 final Wrapper<ResponseFormat> errorWrapper,
173 final boolean shouldLock) throws BusinessLogicException {
174 final var component = getComponent(componentId);
175 validateCanWorkOnComponent(component, user);
176 ResponseFormat responseFormat;
178 Map<String, InterfaceDefinition> componentInterfaceMap = component.getInterfaces();
179 final String interfaceDefinitionType = interfaceDefinition.getType();
180 if (MapUtils.isEmpty(componentInterfaceMap)) {
181 componentInterfaceMap = new HashMap<>();
182 componentInterfaceMap.put(interfaceDefinitionType, interfaceDefinition);
183 component.setInterfaces(componentInterfaceMap);
185 InterfaceDefinition componentInterfaceDefinition = componentInterfaceMap.get(interfaceDefinitionType);
186 if (componentInterfaceDefinition == null) {
187 componentInterfaceDefinition = interfaceDefinition;
188 componentInterfaceMap.put(interfaceDefinitionType, interfaceDefinition);
191 final Map<String, OperationDataDefinition> interfaceDefinitionOperations = interfaceDefinition.getOperations();
192 final Optional<OperationDataDefinition> optionalOperationDataDefinition = interfaceDefinitionOperations.values().stream().findFirst();
193 if (optionalOperationDataDefinition.isEmpty()) {
194 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
195 LOGGER.debug("Failed to found interface operation on provided InterfaceDefinition {}, error: {}",
196 interfaceDefinitionType, responseFormat);
197 errorWrapper.setInnerElement(responseFormat);
198 return Optional.empty();
200 final var updatedOperationDataDefinition = optionalOperationDataDefinition.get();
201 updateOperationDefinitionImplementation(updatedOperationDataDefinition);
202 Map<String, OperationDataDefinition> componentOperationDataDefinitionMap = componentInterfaceDefinition.getOperations();
203 if (MapUtils.isEmpty(componentOperationDataDefinitionMap)) {
204 componentOperationDataDefinitionMap = new HashMap<>();
205 componentInterfaceDefinition.setOperations(componentOperationDataDefinitionMap);
207 componentOperationDataDefinitionMap.replace(updatedOperationDataDefinition.getName(), updatedOperationDataDefinition);
209 boolean wasLocked = false;
212 lockComponent(componentId, component, "Update Interface Operation on Component instance");
215 final StorageOperationStatus status = toscaOperationFacade.updateComponentInterfaces(component, interfaceDefinitionType);
216 if (status != StorageOperationStatus.OK) {
217 janusGraphDao.rollback();
218 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
219 LOGGER.error("Exception occurred when updating Component Instance Interfaces {}", responseFormat);
220 errorWrapper.setInnerElement(responseFormat);
221 return Optional.empty();
223 janusGraphDao.commit();
224 } catch (final Exception e) {
225 janusGraphDao.rollback();
226 LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: ", e);
227 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
228 errorWrapper.setInnerElement(responseFormat);
229 throw new BusinessLogicException(responseFormat);
232 unlockComponent(component.getUniqueId(), componentTypeEnum);
235 return Optional.of(component);
238 public Optional<Component> createInterfaceOperationInResource(final String componentId, final InterfaceDefinition interfaceDefinition,
239 final ComponentTypeEnum componentTypeEnum,
240 final Wrapper<ResponseFormat> errorWrapper, final boolean shouldLock)
241 throws BusinessLogicException {
242 final Component component = getComponent(componentId);
243 ResponseFormat responseFormat;
244 final String componentInterfaceUpdatedKey = interfaceDefinition.getType();
246 Map<String, InterfaceDefinition> componentInterfaceMap = component.getInterfaces();
247 if (MapUtils.isEmpty(componentInterfaceMap)) {
248 componentInterfaceMap = new HashMap<>();
249 component.setInterfaces(componentInterfaceMap);
252 interfaceDefinition.setUniqueId(componentInterfaceUpdatedKey);
253 interfaceDefinition.setToscaResourceName(componentInterfaceUpdatedKey);
254 interfaceDefinition.setUserCreated(true);
256 final Optional<OperationDataDefinition> optionalOperationDataDefinition = interfaceDefinition.getOperations().values().stream().findFirst();
257 if (optionalOperationDataDefinition.isEmpty()) {
258 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
259 LOGGER.debug("Failed to found interface operation on component instance with id {}, error: {}", componentId, responseFormat);
260 errorWrapper.setInnerElement(responseFormat);
261 return Optional.empty();
264 final OperationDataDefinition updatedOperationDataDefinition = optionalOperationDataDefinition.get();
265 updatedOperationDataDefinition.setUniqueId(UUID.randomUUID().toString());
267 final InterfaceDefinition interfaceDefinitionFound = componentInterfaceMap.get(componentInterfaceUpdatedKey);
268 if (interfaceDefinitionFound != null) {
269 final Map<String, OperationDataDefinition> operationsFromComponent = interfaceDefinitionFound.getOperations();
270 final String updatedOperationDataDefinitionName = updatedOperationDataDefinition.getName();
271 final boolean find = operationsFromComponent.containsKey(updatedOperationDataDefinitionName);
273 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NAME_ALREADY_IN_USE,
274 updatedOperationDataDefinitionName);
275 LOGGER.error("Operation '{}' for Interface '{}' already exist, error: '{}'", updatedOperationDataDefinitionName,
276 componentInterfaceUpdatedKey, responseFormat);
277 errorWrapper.setInnerElement(responseFormat);
278 return Optional.empty();
280 operationsFromComponent.put(updatedOperationDataDefinitionName, updatedOperationDataDefinition);
281 interfaceDefinition.setOperations(operationsFromComponent);
285 componentInterfaceMap.put(componentInterfaceUpdatedKey, interfaceDefinition);
287 boolean wasLocked = false;
290 lockComponent(componentId, component, "Update Interface Operation on Component instance");
293 final Either<InterfaceDefinition, StorageOperationStatus> operationStatusEither =
294 toscaOperationFacade.addInterfaceToComponent(componentInterfaceUpdatedKey, interfaceDefinition, component);
295 if (operationStatusEither.isRight()) {
296 janusGraphDao.rollback();
297 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
298 LOGGER.error("Exception occurred when updating Component Instance Interfaces {}", responseFormat);
299 errorWrapper.setInnerElement(responseFormat);
300 return Optional.empty();
302 janusGraphDao.commit();
303 } catch (final Exception e) {
304 janusGraphDao.rollback();
305 LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: ", e);
306 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
307 errorWrapper.setInnerElement(responseFormat);
308 throw new BusinessLogicException(responseFormat);
311 unlockComponent(component.getUniqueId(), componentTypeEnum);
314 return Optional.of(component);
317 public User validateUser(final String userId) {
318 final User user = userValidations.validateUserExists(userId);
319 userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
323 private void unlockComponent(final String componentUniqueId, final ComponentTypeEnum componentType) {
324 graphLockOperation.unlockComponent(componentUniqueId, componentType.getNodeType());
327 private void updateOperationDefinitionImplementation(final OperationDataDefinition updatedOperationDataDefinition) {
328 final ArtifactDataDefinition artifactInfo = new ArtifactDataDefinition(updatedOperationDataDefinition.getImplementation());
329 artifactInfo.setArtifactName(String.format("'%s'", updatedOperationDataDefinition.getImplementation().getArtifactName()));
330 updatedOperationDataDefinition.setImplementation(artifactInfo);