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
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.components.impl;
22 import fj.data.Either;
23 import java.util.Collections;
24 import java.util.List;
26 import java.util.Optional;
27 import org.openecomp.sdc.be.components.attribute.AttributeDeclarationOrchestrator;
28 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
29 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
30 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
31 import org.openecomp.sdc.be.components.validation.ComponentValidations;
32 import org.openecomp.sdc.be.dao.api.ActionStatus;
33 import org.openecomp.sdc.be.dao.utils.MapUtil;
34 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
35 import org.openecomp.sdc.be.model.Component;
36 import org.openecomp.sdc.be.model.ComponentInstOutputsMap;
37 import org.openecomp.sdc.be.model.ComponentInstanceOutput;
38 import org.openecomp.sdc.be.model.ComponentParametersView;
39 import org.openecomp.sdc.be.model.OutputDefinition;
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.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.common.log.elements.LoggerSupportability;
49 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
50 import org.openecomp.sdc.common.log.enums.StatusCode;
51 import org.openecomp.sdc.common.log.wrappers.Logger;
52 import org.openecomp.sdc.exception.ResponseFormat;
53 import org.springframework.beans.factory.annotation.Autowired;
55 @org.springframework.stereotype.Component("outputsBusinessLogic")
56 public class OutputsBusinessLogic extends BaseBusinessLogic {
58 private static final String CREATE_OUTPUT = "CreateOutput";
59 private static final Logger log = Logger.getLogger(OutputsBusinessLogic.class);
60 private static final String FAILED_TO_FOUND_COMPONENT_ERROR = "Failed to found component {}, error: {}";
61 private static final String GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP = "Going to execute rollback on create group.";
62 private static final String GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP = "Going to execute commit on create group.";
63 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(OutputsBusinessLogic.class);
64 private static final String FAILED_TO_FOUND_COMPONENT_INSTANCE_OUTPUTS_COMPONENT_INSTANCE_ID = "Failed to found component instance outputs componentInstanceId: {}";
65 private static final String FAILED_TO_FOUND_COMPONENT_INSTANCE_OUTPUTS_ERROR = "Failed to found component instance outputs {}, error: {}";
66 private final AttributeDeclarationOrchestrator attributeDeclarationOrchestrator;
69 public OutputsBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation,
70 final IGroupInstanceOperation groupInstanceOperation, final IGroupTypeOperation groupTypeOperation,
71 final InterfaceOperation interfaceOperation, final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
72 final AttributeDeclarationOrchestrator attributeDeclarationOrchestrator,
73 final ArtifactsOperations artifactToscaOperation) {
74 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
75 artifactToscaOperation);
76 this.attributeDeclarationOrchestrator = attributeDeclarationOrchestrator;
79 public Either<List<ComponentInstanceOutput>, ResponseFormat> getComponentInstanceOutputs(final String userId, final String componentId,
80 final String componentInstanceId) {
81 validateUserExists(userId);
82 final ComponentParametersView filters = new ComponentParametersView();
84 filters.setIgnoreOutputs(false);
85 filters.setIgnoreComponentInstances(false);
86 filters.setIgnoreComponentInstancesOutputs(false);
87 final Either<Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
88 if (getComponentEither.isRight()) {
89 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
90 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
91 return Either.right(componentsUtils.getResponseFormat(actionStatus));
93 final Component component = getComponentEither.left().value();
94 if (!ComponentValidations.validateComponentInstanceExist(component, componentInstanceId)) {
95 final ActionStatus actionStatus = ActionStatus.COMPONENT_INSTANCE_NOT_FOUND;
96 log.debug(FAILED_TO_FOUND_COMPONENT_INSTANCE_OUTPUTS_ERROR, componentInstanceId, actionStatus);
97 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, component.getComponentMetadataForSupportLog(), StatusCode.ERROR,
98 FAILED_TO_FOUND_COMPONENT_INSTANCE_OUTPUTS_COMPONENT_INSTANCE_ID, componentInstanceId);
99 return Either.right(componentsUtils.getResponseFormat(actionStatus));
101 final Map<String, List<ComponentInstanceOutput>> ciOutputs = Optional.ofNullable(component.getComponentInstancesOutputs())
102 .orElse(Collections.emptyMap());
103 return Either.left(ciOutputs.getOrDefault(componentInstanceId, Collections.emptyList()));
107 public Either<List<OutputDefinition>, ResponseFormat> declareAttributes(final String userId, final String componentId,
108 final ComponentTypeEnum componentTypeEnum,
109 final ComponentInstOutputsMap componentInstOutputsMap) {
110 return createMultipleOutputs(userId, componentId, componentTypeEnum, componentInstOutputsMap, true, false);
113 public Either<List<OutputDefinition>, ResponseFormat> createMultipleOutputs(final String userId, final String componentId,
114 final ComponentTypeEnum componentType,
115 final ComponentInstOutputsMap componentInstOutputsMapUi,
116 final boolean shouldLockComp, final boolean inTransaction) {
117 Either<List<OutputDefinition>, ResponseFormat> result = null;
118 org.openecomp.sdc.be.model.Component component = null;
120 validateUserExists(userId);
121 component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
122 result = attributeDeclarationOrchestrator.declareAttributesToOutputs(component, componentInstOutputsMapUi).left()
123 .bind(outputsToCreate -> prepareOutputsForCreation(userId, componentId, outputsToCreate)).right()
124 .map(componentsUtils::getResponseFormat);
126 } catch (final ByResponseFormatComponentException e) {
127 log.error("#createMultipleOutputs: Exception thrown: ", e);
128 result = Either.right(e.getResponseFormat());
131 if (!inTransaction) {
132 if (result == null || result.isRight()) {
133 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
134 janusGraphDao.rollback();
136 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
137 janusGraphDao.commit();
141 if (shouldLockComp && component != null) {
142 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
147 private org.openecomp.sdc.be.model.Component getAndValidateComponentForCreate(final String userId, final String componentId,
148 final ComponentTypeEnum componentType,
149 final boolean shouldLockComp) {
150 final ComponentParametersView componentParametersView = getBaseComponentParametersView();
151 final org.openecomp.sdc.be.model.Component component = validateComponentExists(componentId, componentType, componentParametersView);
152 if (shouldLockComp) {
153 // lock the component
154 lockComponent(component, CREATE_OUTPUT);
156 validateCanWorkOnComponent(component, userId);
160 private Either<List<OutputDefinition>, StorageOperationStatus> prepareOutputsForCreation(final String userId, final String cmptId,
161 final List<OutputDefinition> outputsToCreate) {
162 final Map<String, OutputDefinition> outputsToPersist = MapUtil.toMap(outputsToCreate, OutputDefinition::getName);
163 assignOwnerIdToOutputs(userId, outputsToPersist);
164 return toscaOperationFacade.addOutputsToComponent(outputsToPersist, cmptId).left().map(persistedOutputs -> outputsToCreate);
167 private void assignOwnerIdToOutputs(final String userId, final Map<String, OutputDefinition> outputsToCreate) {
168 outputsToCreate.values().forEach(outputDefinition -> outputDefinition.setOwnerId(userId));
171 private ComponentParametersView getBaseComponentParametersView() {
172 final ComponentParametersView componentParametersView = new ComponentParametersView();
173 componentParametersView.disableAll();
174 componentParametersView.setIgnoreOutputs(false);
175 componentParametersView.setIgnoreAttributes(false);
176 componentParametersView.setIgnoreComponentInstances(false);
177 componentParametersView.setIgnoreComponentInstancesOutputs(false);
178 componentParametersView.setIgnoreComponentInstancesAttributes(false);
179 componentParametersView.setIgnoreUsers(false);
180 return componentParametersView;
184 * Delete output from component
191 public OutputDefinition deleteOutput(final String componentId, final String userId, final String outputId) {
192 Either<OutputDefinition, ResponseFormat> deleteEither = null;
193 if (log.isDebugEnabled()) {
194 log.debug("Going to delete output id: {}", outputId);
196 validateUserExists(userId);
197 final ComponentParametersView componentParametersView = getBaseComponentParametersView();
198 componentParametersView.setIgnoreAttributes(false);
199 final Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentEither = toscaOperationFacade
200 .getToscaElement(componentId, componentParametersView);
201 if (componentEither.isRight()) {
202 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(componentEither.right().value()));
204 final org.openecomp.sdc.be.model.Component component = componentEither.left().value();
205 // Validate outputId is child of the component
206 final Optional<OutputDefinition> optionalOutput = component.getOutputs().stream().
208 filter(output -> output.getUniqueId().equals(outputId)).
211 if (!optionalOutput.isPresent()) {
212 throw new ByActionStatusComponentException(ActionStatus.OUTPUT_IS_NOT_CHILD_OF_COMPONENT, outputId, componentId);
214 final OutputDefinition outputForDelete = optionalOutput.get();
216 lockComponent(componentId, component, "deleteOutput");
217 // Delete output operations
218 boolean failed = false;
220 final StorageOperationStatus status = toscaOperationFacade.deleteOutputOfResource(component, outputForDelete.getName());
221 if (status != StorageOperationStatus.OK) {
222 log.debug("Component id: {} delete output id: {} failed", componentId, outputId);
223 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status), component.getName());
225 final StorageOperationStatus storageOperationStatus = attributeDeclarationOrchestrator
226 .unDeclareAttributesAsOutputs(component, outputForDelete);
227 if (storageOperationStatus != StorageOperationStatus.OK) {
228 log.debug("Component id: {} update attributes declared as output for outputId: {} failed", componentId, outputId);
229 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageOperationStatus), component.getName());
231 return outputForDelete;
232 } catch (final ComponentException e) {
236 unlockComponent(failed, component);