2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. 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=========================================================
19 * Modifications copyright (c) 2019 Nokia
20 * ================================================================================
23 package org.openecomp.sdc.be.components.impl;
25 import fj.data.Either;
26 import org.apache.commons.collections4.ListUtils;
27 import org.apache.commons.collections4.MapUtils;
28 import org.apache.commons.lang.BooleanUtils;
29 import org.apache.commons.lang.StringUtils;
30 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
31 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
32 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
33 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
34 import org.openecomp.sdc.be.components.property.PropertyDeclarationOrchestrator;
35 import org.openecomp.sdc.be.components.validation.ComponentValidations;
36 import org.openecomp.sdc.be.dao.api.ActionStatus;
37 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
38 import org.openecomp.sdc.be.dao.utils.MapUtil;
39 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
40 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
41 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
42 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
43 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
44 import org.openecomp.sdc.be.model.ComponentInstInputsMap;
45 import org.openecomp.sdc.be.model.ComponentInstListInput;
46 import org.openecomp.sdc.be.model.ComponentInstance;
47 import org.openecomp.sdc.be.model.ComponentInstanceInput;
48 import org.openecomp.sdc.be.model.ComponentInstancePropInput;
49 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
50 import org.openecomp.sdc.be.model.ComponentParametersView;
51 import org.openecomp.sdc.be.model.DataTypeDefinition;
52 import org.openecomp.sdc.be.model.InputDefinition;
53 import org.openecomp.sdc.be.model.PropertyDefinition;
54 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
55 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
56 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
57 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
58 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
59 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
60 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
61 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
62 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
63 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
64 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
65 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
66 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
67 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
68 import org.openecomp.sdc.common.log.enums.StatusCode;
69 import org.openecomp.sdc.common.log.wrappers.Logger;
70 import org.openecomp.sdc.exception.ResponseFormat;
71 import org.springframework.beans.factory.annotation.Autowired;
72 import org.springframework.stereotype.Component;
74 import java.util.ArrayList;
75 import java.util.Arrays;
76 import java.util.Collections;
77 import java.util.HashMap;
78 import java.util.List;
80 import java.util.Objects;
81 import java.util.Optional;
82 import java.util.stream.Collectors;
84 @Component("inputsBusinessLogic")
85 public class InputsBusinessLogic extends BaseBusinessLogic {
87 private static final String CREATE_INPUT = "CreateInput";
88 private static final String UPDATE_INPUT = "UpdateInput";
90 private static final Logger log = Logger.getLogger(InputsBusinessLogic.class);
91 private static final String FAILED_TO_FOUND_COMPONENT_ERROR = "Failed to found component {}, error: {}";
92 private static final String GET_PROPERTIES_BY_INPUT = "get Properties by input";
93 private static final String FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR = "Failed to found input {} under component {}, error: {}";
94 private static final String GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP = "Going to execute rollback on create group.";
95 private static final String GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP = "Going to execute commit on create group.";
96 public LoggerSupportability loggerSupportability=LoggerSupportability.getLogger(InputsBusinessLogic.class.getName());
98 private final PropertyDeclarationOrchestrator propertyDeclarationOrchestrator;
99 private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
100 private final DataTypeBusinessLogic dataTypeBusinessLogic;
103 public InputsBusinessLogic(IElementOperation elementDao,
104 IGroupOperation groupOperation,
105 IGroupInstanceOperation groupInstanceOperation,
106 IGroupTypeOperation groupTypeOperation,
107 InterfaceOperation interfaceOperation,
108 InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
109 PropertyDeclarationOrchestrator propertyDeclarationOrchestrator,
110 ComponentInstanceBusinessLogic componentInstanceBusinessLogic, DataTypeBusinessLogic dataTypeBusinessLogic,
111 ArtifactsOperations artifactToscaOperation) {
112 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
113 interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
114 this.propertyDeclarationOrchestrator = propertyDeclarationOrchestrator;
115 this.componentInstanceBusinessLogic = componentInstanceBusinessLogic;
116 this.dataTypeBusinessLogic = dataTypeBusinessLogic;
120 * associate inputs to a given component with paging
126 public Either<List<InputDefinition>, ResponseFormat> getInputs(String userId, String componentId) {
128 validateUserExists(userId);
130 ComponentParametersView filters = new ComponentParametersView();
131 filters.disableAll();
132 filters.setIgnoreInputs(false);
134 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
135 if(getComponentEither.isRight()){
136 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
137 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
138 return Either.right(componentsUtils.getResponseFormat(actionStatus));
141 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
142 List<InputDefinition> inputs = component.getInputs();
144 return Either.left(inputs);
148 public Either<List<ComponentInstanceInput>, ResponseFormat> getComponentInstanceInputs(String userId, String componentId, String componentInstanceId) {
150 validateUserExists(userId);
151 ComponentParametersView filters = new ComponentParametersView();
152 filters.disableAll();
153 filters.setIgnoreInputs(false);
154 filters.setIgnoreComponentInstances(false);
155 filters.setIgnoreComponentInstancesInputs(false);
157 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
158 if(getComponentEither.isRight()){
159 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
160 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
161 return Either.right(componentsUtils.getResponseFormat(actionStatus));
164 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
166 if(!ComponentValidations.validateComponentInstanceExist(component, componentInstanceId)){
167 ActionStatus actionStatus = ActionStatus.COMPONENT_INSTANCE_NOT_FOUND;
168 log.debug("Failed to found component instance inputs {}, error: {}", componentInstanceId, actionStatus);
169 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS,component.getComponentMetadataForSupportLog(),
170 StatusCode.ERROR,"Failed to found component instance inputs componentInstanceId: {}",componentInstanceId);
171 return Either.right(componentsUtils.getResponseFormat(actionStatus));
173 Map<String, List<ComponentInstanceInput>> ciInputs =
174 Optional.ofNullable(component.getComponentInstancesInputs()).orElse(Collections.emptyMap());
176 // Set Constraints on Input
177 MapUtils.emptyIfNull(ciInputs).values()
178 .forEach(inputs -> ListUtils.emptyIfNull(inputs)
179 .forEach(input -> input.setConstraints(setInputConstraint(input))));
180 return Either.left(ciInputs.getOrDefault(componentInstanceId, Collections.emptyList()));
184 * associate properties to a given component instance input
192 public Either<List<ComponentInstanceProperty>, ResponseFormat> getComponentInstancePropertiesByInputId(String userId, String componentId, String instanceId, String inputId) {
193 validateUserExists(userId);
194 String parentId = componentId;
195 org.openecomp.sdc.be.model.Component component;
196 ComponentParametersView filters = new ComponentParametersView();
197 filters.disableAll();
198 filters.setIgnoreComponentInstances(false);
200 if(!instanceId.equals(inputId)){
203 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(parentId, filters);
205 if(getComponentEither.isRight()){
206 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
207 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, parentId, actionStatus);
208 return Either.right(componentsUtils.getResponseFormat(actionStatus));
211 component = getComponentEither.left().value();
212 Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci ->ci.getUniqueId().equals(instanceId)).findAny();
213 if(ciOp.isPresent()){
214 parentId = ciOp.get().getComponentUid();
219 filters.setIgnoreInputs(false);
221 filters.setIgnoreComponentInstancesProperties(false);
222 filters.setIgnoreComponentInstancesInputs(false);
223 filters.setIgnoreProperties(false);
225 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(parentId, filters);
227 if(getComponentEither.isRight()){
228 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
229 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, parentId, actionStatus);
230 return Either.right(componentsUtils.getResponseFormat(actionStatus));
233 component = getComponentEither.left().value();
235 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
237 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
238 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, parentId, actionStatus);
239 return Either.right(componentsUtils.getResponseFormat(actionStatus));
242 return Either.left(componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(component, inputId));
246 private String updateInputObjectValue(InputDefinition currentInput, InputDefinition newInput, Map<String, DataTypeDefinition> dataTypes) {
247 String innerType = null;
248 String propertyType = currentInput.getType();
249 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
250 log.debug("The type of the property {} is {}", currentInput.getUniqueId(), propertyType);
252 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
253 SchemaDefinition def = currentInput.getSchema();
255 log.debug("Schema doesn't exists for property of type {}", type);
256 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE));
258 PropertyDataDefinition propDef = def.getProperty();
259 if (propDef == null) {
260 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
261 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE));
263 innerType = propDef.getType();
265 // Specific Update Logic
267 Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, newInput.getDefaultValue(), true, innerType, dataTypes);
269 String newValue = currentInput.getDefaultValue();
270 if (isValid.isRight()) {
271 Boolean res = isValid.right().value();
272 if (Boolean.FALSE.equals(res)) {
273 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
276 Object object = isValid.left().value();
277 if (object != null) {
278 newValue = object.toString();
284 private InputDefinition getInputFromInputsListById(List<InputDefinition> componentsOldInputs, InputDefinition input) {
285 return componentsOldInputs.stream().filter(in -> in.getUniqueId().equals(input.getUniqueId())).findFirst().orElse(null);
288 public Either<List<InputDefinition>, ResponseFormat> updateInputsValue(ComponentTypeEnum componentType, String componentId, List<InputDefinition> inputs, String userId, boolean shouldLockComp, boolean inTransaction) {
290 List<InputDefinition> returnInputs = new ArrayList<>();
291 Either<List<InputDefinition>, ResponseFormat> result = null;
292 org.openecomp.sdc.be.model.Component component = null;
295 validateUserExists(userId);
297 ComponentParametersView componentParametersView = new ComponentParametersView();
298 componentParametersView.disableAll();
299 componentParametersView.setIgnoreInputs(false);
300 componentParametersView.setIgnoreUsers(false);
301 componentParametersView.setIgnoreProperties(false);
302 componentParametersView.setIgnoreComponentInstancesProperties(false);
303 componentParametersView.setIgnoreComponentInstances(false);
305 component = validateComponentExists(componentId, componentType, componentParametersView);
307 if (shouldLockComp) {
309 lockComponent(component, UPDATE_INPUT);
310 }catch (ComponentException e){
311 result = Either.right(e.getResponseFormat());
316 //Validate value and Constraint of input
317 Either<Boolean, ResponseFormat> constraintValidatorResponse = validateInputValueConstraint(inputs);
318 if (constraintValidatorResponse.isRight()) {
319 log.error("Failed validation value and constraint of property: {}",
320 constraintValidatorResponse.right().value());
321 return Either.right(constraintValidatorResponse.right().value());
324 validateCanWorkOnComponent(component, userId);
325 Map<String, DataTypeDefinition> dataTypes;
326 dataTypes = getAllDataTypes(applicationDataTypeCache);
328 List<InputDefinition> componentsOldInputs = Optional.ofNullable(component.getInputs()).orElse(Collections.emptyList());
329 for (InputDefinition newInput: inputs) {
330 InputDefinition currInput = getInputFromInputsListById(componentsOldInputs, newInput);
331 if (currInput == null) {
332 ActionStatus actionStatus = ActionStatus.COMPONENT_NOT_FOUND;
333 log.debug("Failed to found newInput {} under component {}, error: {}", newInput.getUniqueId(), componentId, actionStatus);
334 result = Either.right(componentsUtils.getResponseFormat(actionStatus));
337 String updateInputObjectValue = updateInputObjectValue(currInput, newInput, dataTypes);
338 currInput.setDefaultValue(updateInputObjectValue);
339 currInput.setOwnerId(userId);
340 Either<InputDefinition, StorageOperationStatus> status = toscaOperationFacade.updateInputOfComponent(component, currInput);
341 if(status.isRight()){
342 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status.right().value());
343 result = Either.right(componentsUtils.getResponseFormat(actionStatus, ""));
346 returnInputs.add(status.left().value());
349 result = Either.left(returnInputs);
350 }catch (ComponentException e) {
351 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
352 unlockRollbackWithException(component, e);
353 } catch (Exception e){
354 unlockRollbackWithException(component, new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR));
356 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
357 unlockWithCommit(component);
362 private Either<Boolean, ResponseFormat> validateInputValueConstraint(List<InputDefinition> inputs) {
363 PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil =
364 PropertyValueConstraintValidationUtil.getInstance();
365 List<InputDefinition> inputDefinitions = new ArrayList<>();
366 for (InputDefinition inputDefinition : inputs) {
367 InputDefinition inputDef = new InputDefinition();
368 inputDefinition.setDefaultValue(inputDefinition.getDefaultValue());
369 inputDefinition.setInputPath(inputDefinition.getSubPropertyInputPath());
370 inputDefinition.setType(inputDefinition.getType());
371 if (Objects.nonNull(inputDefinition.getParentPropertyType())) {
372 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
373 propertyDefinition.setType(inputDefinition.getParentPropertyType());
375 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
378 inputDefinitions.add(inputDef);
381 return propertyValueConstraintValidationUtil.validatePropertyConstraints(inputDefinitions, applicationDataTypeCache);
384 public Either<List<ComponentInstanceInput>, ResponseFormat> getInputsForComponentInput(String userId, String componentId, String inputId) {
385 validateUserExists(userId);
386 org.openecomp.sdc.be.model.Component component = null;
387 ComponentParametersView filters = new ComponentParametersView();
388 filters.disableAll();
389 filters.setIgnoreComponentInstances(false);
390 filters.setIgnoreInputs(false);
391 filters.setIgnoreComponentInstancesInputs(false);
392 filters.setIgnoreProperties(false);
394 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
396 if(getComponentEither.isRight()){
397 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
398 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
399 return Either.right(componentsUtils.getResponseFormat(actionStatus));
402 component = getComponentEither.left().value();
404 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
406 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
407 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, componentId, actionStatus);
408 return Either.right(componentsUtils.getResponseFormat(actionStatus));
411 return Either.left(componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(component, inputId));
416 public Either<List<InputDefinition>, ResponseFormat> declareProperties(String userId, String componentId,
417 ComponentTypeEnum componentTypeEnum, ComponentInstInputsMap componentInstInputsMap) {
419 return createMultipleInputs(userId, componentId, componentTypeEnum, componentInstInputsMap, true, false);
422 public Either<List<InputDefinition>, ResponseFormat> createMultipleInputs(String userId, String componentId, ComponentTypeEnum componentType, ComponentInstInputsMap componentInstInputsMapUi, boolean shouldLockComp, boolean inTransaction) {
424 Either<List<InputDefinition>, ResponseFormat> result = null;
425 org.openecomp.sdc.be.model.Component component = null;
428 validateUserExists(userId);
430 component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
432 result = propertyDeclarationOrchestrator.declarePropertiesToInputs(component, componentInstInputsMapUi)
434 .bind(inputsToCreate -> prepareInputsForCreation(userId, componentId, inputsToCreate))
436 .map(componentsUtils::getResponseFormat);
440 } catch (ByResponseFormatComponentException e) {
441 log.error("#createMultipleInputs: Exception thrown: ", e);
442 result = Either.right(e.getResponseFormat());
446 if (!inTransaction) {
447 if (result == null || result.isRight()) {
448 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
449 janusGraphDao.rollback();
451 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
452 janusGraphDao.commit();
456 if (shouldLockComp && component != null) {
457 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
464 * Creates a list input with a data type which has properties specified.
466 * @param userId User ID
467 * @param componentId Component ID
468 * @param componentType Component type
469 * @param componentListInput Properties to be declared and input to be created
470 * @param shouldLockComp true if the component should be locked
471 * @param inTransaction true if already in transaction
473 public Either<List<InputDefinition>, ResponseFormat> createListInput(String userId, String componentId,
474 ComponentTypeEnum componentType, ComponentInstListInput componentListInput, boolean shouldLockComp,
475 boolean inTransaction) {
477 Either<List<InputDefinition>, ResponseFormat> result = null;
478 org.openecomp.sdc.be.model.Component component = null;
480 log.trace("#createListInput: enter");
483 /* check if user exists */
484 validateUserExists(userId);
486 component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
488 InputDefinition listInput = componentListInput.getListInput();
489 DataTypeDefinition dataType =
490 prepareDataTypeForListInput(componentListInput.getComponentInstInputsMap(), listInput);
491 Map<String, DataTypeDefinition> dataTypesMap = new HashMap<>();
492 dataTypesMap.put(dataType.getName(), dataType);
493 if (log.isDebugEnabled()) {
494 log.debug("#createListInput: dataTypesMap={}", ReflectionToStringBuilder.toString(dataTypesMap));
497 Either<List<DataTypeDefinition>, StorageOperationStatus> dataTypeResult =
498 toscaOperationFacade.addDataTypesToComponent(dataTypesMap, componentId);
499 if (dataTypeResult.isRight()) {
500 log.debug("#createListInput: DataType creation failed.");
501 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(dataTypeResult.right().value()));
505 listInput.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(componentId, listInput.getName()));
506 listInput.setInstanceUniqueId(
507 propertyDeclarationOrchestrator.getPropOwnerId(componentListInput.getComponentInstInputsMap()));
508 listInput.setIsDeclaredListInput(true);
509 Map<String, InputDefinition> listInputMap = new HashMap<>();
510 listInputMap.put(listInput.getName(), listInput);
511 result = createListInputsInGraph(listInputMap, dataTypesMap, component);
512 if (result.isRight()) {
513 log.debug("#createListInput: createListInputsInGraph failed.");
514 throw new ByResponseFormatComponentException(result.right().value());
518 result = propertyDeclarationOrchestrator
519 .declarePropertiesToListInput(component, componentListInput.getComponentInstInputsMap(), listInput)
520 .right().map(err -> componentsUtils.getResponseFormat(err))
521 .left().map(Arrays::asList);
523 log.trace("#createListInput: leave");
527 } catch (ByResponseFormatComponentException e) {
528 log.error("#createListInput: Exception thrown", e);
529 result = Either.right(e.getResponseFormat());
533 if (!inTransaction) {
534 if (result == null || result.isRight()) {
535 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
536 janusGraphDao.rollback();
538 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
539 janusGraphDao.commit();
543 if (shouldLockComp && component != null) {
544 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
549 private ComponentParametersView getBaseComponentParametersView() {
550 ComponentParametersView componentParametersView = new ComponentParametersView();
551 componentParametersView.disableAll();
552 componentParametersView.setIgnoreInputs(false);
553 componentParametersView.setIgnoreComponentInstances(false);
554 componentParametersView.setIgnoreComponentInstancesInputs(false);
555 componentParametersView.setIgnoreComponentInstancesProperties(false);
556 componentParametersView.setIgnorePolicies(false);
557 componentParametersView.setIgnoreGroups(false);
558 componentParametersView.setIgnoreUsers(false);
559 return componentParametersView;
562 private org.openecomp.sdc.be.model.Component getAndValidateComponentForCreate(
563 String userId, String componentId, ComponentTypeEnum componentType, boolean shouldLockComp
565 ComponentParametersView componentParametersView = getBaseComponentParametersView();
566 org.openecomp.sdc.be.model.Component component = validateComponentExists(componentId, componentType, componentParametersView);
567 if (shouldLockComp) {
568 // lock the component
569 lockComponent(component, CREATE_INPUT);
571 validateCanWorkOnComponent(component, userId);
575 private DataTypeDefinition prepareDataTypeForListInput(ComponentInstInputsMap inputsMap, InputDefinition input) {
576 // Confirm if type is list
577 if (StringUtils.isEmpty(input.getType()) || !input.getType().equals(ToscaPropertyType.LIST.getType())) {
578 log.debug("#prepareDataTypeForListInput: Type of input is not list.");
579 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE));
582 // Confirm schema type is not empty
583 String desiredTypeName = input.getSchemaType();
584 if (StringUtils.isEmpty(desiredTypeName)) {
585 log.debug("#prepareDataTypeForListInput: Schema type of list input is empty.");
586 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE));
589 DataTypeDefinition dataType = new DataTypeDefinition();
590 List<ComponentInstancePropInput> propInputs = inputsMap.resolvePropertiesToDeclare().getRight();
591 dataType.setName(desiredTypeName);
592 dataType.setDerivedFromName(ToscaPropertyType.ROOT.getType());
593 // Copy properties from inputsMap
594 dataType.setProperties(propInputs.stream().map(PropertyDefinition::new).collect(Collectors.toList()));
598 private Either<List<InputDefinition>, StorageOperationStatus> prepareInputsForCreation(String userId, String cmptId, List<InputDefinition> inputsToCreate) {
599 Map<String, InputDefinition> inputsToPersist = MapUtil.toMap(inputsToCreate, InputDefinition::getName);
600 assignOwnerIdToInputs(userId, inputsToPersist);
601 inputsToPersist.values()
602 .forEach(input -> input.setConstraints(componentInstanceBusinessLogic.setInputConstraint(input)));
604 return toscaOperationFacade.addInputsToComponent(inputsToPersist, cmptId)
606 .map(persistedInputs -> inputsToCreate);
609 private void assignOwnerIdToInputs(String userId, Map<String, InputDefinition> inputsToCreate) {
610 inputsToCreate.values().forEach(inputDefinition -> inputDefinition.setOwnerId(userId));
613 public Either<List<InputDefinition>, ResponseFormat> createInputsInGraph(Map<String, InputDefinition> inputs, org.openecomp.sdc.be.model.Component component) {
615 List<InputDefinition> resourceProperties = component.getInputs();
617 Map<String, DataTypeDefinition> dataTypes = getAllDataTypes(applicationDataTypeCache);
619 for (Map.Entry<String, InputDefinition> inputDefinition : inputs.entrySet()) {
620 String inputName = inputDefinition.getKey();
621 inputDefinition.getValue().setName(inputName);
623 Either<InputDefinition, ResponseFormat> preparedInputEither = prepareAndValidateInputBeforeCreate(inputDefinition.getValue(), dataTypes);
624 if(preparedInputEither.isRight()){
625 return Either.right(preparedInputEither.right().value());
629 if (resourceProperties != null) {
630 Map<String, InputDefinition> generatedInputs = resourceProperties.stream().collect(Collectors.toMap(PropertyDataDefinition::getName, i -> i));
631 Either<Map<String, InputDefinition>, String> mergeEither = ToscaDataDefinition.mergeDataMaps(generatedInputs, inputs);
632 if(mergeEither.isRight()){
633 return Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_ALREADY_EXIST, mergeEither.right().value()));
635 inputs = mergeEither.left().value();
638 Either<List<InputDefinition>, StorageOperationStatus> associateInputsEither = toscaOperationFacade.createAndAssociateInputs(inputs, component.getUniqueId());
639 if(associateInputsEither.isRight()){
640 log.debug("Failed to create inputs under component {}. Status is {}", component.getUniqueId(), associateInputsEither.right().value());
642 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(associateInputsEither.right().value())));
644 return Either.left(associateInputsEither.left().value());
647 private Either<List<InputDefinition>, ResponseFormat> createListInputsInGraph(Map<String, InputDefinition> inputs,
648 Map<String, DataTypeDefinition> privateDataTypes, org.openecomp.sdc.be.model.Component component) {
650 log.trace("#createListInputsInGraph: enter");
652 Map<String, DataTypeDefinition> dataTypes = getAllDataTypes(
653 applicationDataTypeCache);
654 dataTypes.putAll(privateDataTypes);
656 for (Map.Entry<String, InputDefinition> inputDefinition : inputs.entrySet()) {
657 String inputName = inputDefinition.getKey();
658 inputDefinition.getValue().setName(inputName);
660 Either<InputDefinition, ResponseFormat> preparedInputEither =
661 prepareAndValidateInputBeforeCreate(inputDefinition.getValue(), dataTypes);
662 if (preparedInputEither.isRight()) {
663 return Either.right(preparedInputEither.right().value());
667 Either<List<InputDefinition>, StorageOperationStatus> addInputsEither = toscaOperationFacade
668 .addInputsToComponent(inputs, component.getUniqueId());
669 if (addInputsEither.isRight()) {
670 log.debug("#createListInputsInGraph: Failed to create inputs under component {}. Status is {}",
671 component.getUniqueId(), addInputsEither.right().value());
672 return Either.right(componentsUtils.getResponseFormat(
673 componentsUtils.convertFromStorageResponse(addInputsEither.right().value())));
675 log.trace("#createListInputsInGraph: leave");
676 return Either.left(addInputsEither.left().value());
680 * Delete input from service
687 public InputDefinition deleteInput(String componentId, String userId, String inputId) {
689 Either<InputDefinition, ResponseFormat> deleteEither = null;
690 if (log.isDebugEnabled()) {
691 log.debug("Going to delete input id: {}", inputId);
694 validateUserExists(userId);
696 ComponentParametersView componentParametersView = getBaseComponentParametersView();
697 componentParametersView.setIgnoreInterfaces(false);
698 componentParametersView.setIgnoreDataType(false);
699 componentParametersView.setIgnoreProperties(false);
701 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentEither =
702 toscaOperationFacade.getToscaElement(componentId, componentParametersView);
703 if (componentEither.isRight()) {
704 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(componentEither.right().value()));
706 org.openecomp.sdc.be.model.Component component = componentEither.left().value();
708 // Validate inputId is child of the component
709 Optional<InputDefinition> optionalInput = component.getInputs().stream().
711 filter(input -> input.getUniqueId().equals(inputId)).
714 if (!optionalInput.isPresent()) {
715 throw new ByActionStatusComponentException(ActionStatus.INPUT_IS_NOT_CHILD_OF_COMPONENT, inputId, componentId);
718 InputDefinition inputForDelete = optionalInput.get();
721 lockComponent(componentId, component, "deleteInput");
722 // Delete input operations
723 boolean failed = false;
725 StorageOperationStatus status =
726 toscaOperationFacade.deleteInputOfResource(component, inputForDelete.getName());
727 if (status != StorageOperationStatus.OK) {
728 log.debug("Component id: {} delete input id: {} failed", componentId, inputId);
729 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status), component.getName());
732 if (BooleanUtils.isTrue(inputForDelete.getIsDeclaredListInput())){
733 deleteEither = deleteListInput(componentId, inputId, component, inputForDelete, status);
734 if (deleteEither.isRight()){
735 throw new ByResponseFormatComponentException(deleteEither.right().value());
737 return deleteEither.left().value();
740 StorageOperationStatus storageOperationStatus =
741 propertyDeclarationOrchestrator.unDeclarePropertiesAsInputs(component, inputForDelete);
742 if (storageOperationStatus != StorageOperationStatus.OK) {
743 log.debug("Component id: {} update properties declared as input for input id: {} failed", componentId, inputId);
744 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageOperationStatus), component.getName());
746 return inputForDelete;
747 }catch (ComponentException e){
751 unlockComponent(failed, component);
755 private Either<InputDefinition, ResponseFormat> deleteListInput(String componentId, String inputId,
756 org.openecomp.sdc.be.model.Component component,
757 InputDefinition inputForDelete, StorageOperationStatus status) {
758 // the input is created by 'Declare List'.
759 // need to 1. undeclare properties, 2. delete input, 3. delete private data type
761 StorageOperationStatus storageOperationStatus =
762 propertyDeclarationOrchestrator.unDeclarePropertiesAsListInputs(component, inputForDelete);
763 if (storageOperationStatus != StorageOperationStatus.OK) {
764 log.debug("Component id: {} update properties declared as input for input id: {} failed", componentId, inputId);
765 return Either.right(componentsUtils.getResponseFormat(
766 componentsUtils.convertFromStorageResponse(status), component.getName()));
768 Either<DataTypeDefinition, StorageOperationStatus> deleteResult =
769 dataTypeBusinessLogic.deletePrivateDataType(component, inputForDelete.getSchemaType());
770 if (deleteResult.isRight()) {
771 log.debug("Component id: {} delete datatype name: {} failed", componentId, inputForDelete.getSchemaType());
772 return Either.right(componentsUtils.getResponseFormat(
773 componentsUtils.convertFromStorageResponse(deleteResult.right().value()), component.getName()));
775 log.trace("deleteInput: deletePrivateDataType (OK)");
776 return Either.left(inputForDelete);
779 private Either<InputDefinition, ResponseFormat> prepareAndValidateInputBeforeCreate(InputDefinition newInputDefinition, Map<String, DataTypeDefinition> dataTypes) {
781 // validate input default values
782 Either<Boolean, ResponseFormat> defaultValuesValidation = validatePropertyDefaultValue(newInputDefinition, dataTypes);
783 if (defaultValuesValidation.isRight()) {
784 return Either.right(defaultValuesValidation.right().value());
787 ToscaPropertyType type = getType(newInputDefinition.getType());
788 if (type != null && newInputDefinition != null) {
789 PropertyValueConverter converter = type.getConverter();
791 SchemaDefinition schema = newInputDefinition.getSchema();
792 String innerType = null;
793 if (schema != null) {
794 PropertyDataDefinition prop = schema.getProperty();
796 innerType = prop.getType();
799 String convertedValue;
800 if (newInputDefinition.getDefaultValue() != null) {
801 convertedValue = converter.convert(newInputDefinition.getDefaultValue(), innerType, dataTypes);
802 newInputDefinition.setDefaultValue(convertedValue);
805 return Either.left(newInputDefinition);
808 public Either<InputDefinition, ResponseFormat> getInputsAndPropertiesForComponentInput(String userId, String componentId, String inputId, boolean inTransaction) {
809 Either<InputDefinition, ResponseFormat> result = null;
812 validateUserExists(userId);
813 ComponentParametersView filters = new ComponentParametersView();
814 filters.disableAll();
815 filters.setIgnoreComponentInstances(false);
816 filters.setIgnoreInputs(false);
817 filters.setIgnoreComponentInstancesInputs(false);
818 filters.setIgnoreComponentInstancesProperties(false);
819 filters.setIgnoreProperties(false);
820 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
821 if(getComponentEither.isRight()){
822 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
823 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
824 return Either.right(componentsUtils.getResponseFormat(actionStatus));
827 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
828 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
830 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
831 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, componentId, actionStatus);
832 return Either.right(componentsUtils.getResponseFormat(actionStatus));
835 InputDefinition resObj = op.get();
837 List<ComponentInstanceInput> inputCIInput = componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(component, inputId) ;
839 resObj.setInputs(inputCIInput);
842 List<ComponentInstanceProperty> inputProps = componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(component, inputId) ;
844 resObj.setProperties(inputProps);
847 result = Either.left(resObj);
853 if (!inTransaction) {
855 if (result == null || result.isRight()) {
856 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
857 janusGraphDao.rollback();
859 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
860 janusGraphDao.commit();