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 java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.List;
32 import java.util.Objects;
33 import java.util.Optional;
34 import java.util.stream.Collectors;
35 import javax.inject.Inject;
36 import org.apache.commons.collections4.ListUtils;
37 import org.apache.commons.collections4.MapUtils;
38 import org.apache.commons.lang.BooleanUtils;
39 import org.apache.commons.lang.StringUtils;
40 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
41 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
42 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
43 import org.openecomp.sdc.be.components.property.PropertyDeclarationOrchestrator;
44 import org.openecomp.sdc.be.components.validation.ComponentValidations;
45 import org.openecomp.sdc.be.dao.api.ActionStatus;
46 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
47 import org.openecomp.sdc.be.dao.utils.MapUtil;
48 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
49 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
50 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
51 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
52 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
53 import org.openecomp.sdc.be.model.ComponentInstInputsMap;
54 import org.openecomp.sdc.be.model.ComponentInstListInput;
55 import org.openecomp.sdc.be.model.ComponentInstance;
56 import org.openecomp.sdc.be.model.ComponentInstanceInput;
57 import org.openecomp.sdc.be.model.ComponentInstancePropInput;
58 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
59 import org.openecomp.sdc.be.model.ComponentParametersView;
60 import org.openecomp.sdc.be.model.DataTypeDefinition;
61 import org.openecomp.sdc.be.model.InputDefinition;
62 import org.openecomp.sdc.be.model.PropertyDefinition;
63 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
64 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
65 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
66 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
67 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
68 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
69 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
70 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
71 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
72 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
73 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
74 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
75 import org.openecomp.sdc.common.log.wrappers.Logger;
76 import org.openecomp.sdc.exception.ResponseFormat;
77 import org.springframework.beans.factory.annotation.Autowired;
78 import org.springframework.stereotype.Component;
80 @Component("inputsBusinessLogic")
81 public class InputsBusinessLogic extends BaseBusinessLogic {
83 private static final String CREATE_INPUT = "CreateInput";
84 private static final String UPDATE_INPUT = "UpdateInput";
86 private static final Logger log = Logger.getLogger(InputsBusinessLogic.class);
87 private static final String FAILED_TO_FOUND_COMPONENT_ERROR = "Failed to found component {}, error: {}";
88 private static final String GET_PROPERTIES_BY_INPUT = "get Properties by input";
89 private static final String FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR = "Failed to found input {} under component {}, error: {}";
90 private static final String GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP = "Going to execute rollback on create group.";
91 private static final String GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP = "Going to execute commit on create group.";
93 private final PropertyDeclarationOrchestrator propertyDeclarationOrchestrator;
94 private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
95 private final DataTypeBusinessLogic dataTypeBusinessLogic;
98 public InputsBusinessLogic(IElementOperation elementDao,
99 IGroupOperation groupOperation,
100 IGroupInstanceOperation groupInstanceOperation,
101 IGroupTypeOperation groupTypeOperation,
102 InterfaceOperation interfaceOperation,
103 InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
104 PropertyDeclarationOrchestrator propertyDeclarationOrchestrator,
105 ComponentInstanceBusinessLogic componentInstanceBusinessLogic, DataTypeBusinessLogic dataTypeBusinessLogic,
106 ArtifactsOperations artifactToscaOperation) {
107 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
108 interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
109 this.propertyDeclarationOrchestrator = propertyDeclarationOrchestrator;
110 this.componentInstanceBusinessLogic = componentInstanceBusinessLogic;
111 this.dataTypeBusinessLogic = dataTypeBusinessLogic;
115 * associate inputs to a given component with paging
121 public Either<List<InputDefinition>, ResponseFormat> getInputs(String userId, String componentId) {
123 validateUserExists(userId, "get Inputs", false);
125 ComponentParametersView filters = new ComponentParametersView();
126 filters.disableAll();
127 filters.setIgnoreInputs(false);
129 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
130 if(getComponentEither.isRight()){
131 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
132 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
133 return Either.right(componentsUtils.getResponseFormat(actionStatus));
136 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
137 List<InputDefinition> inputs = component.getInputs();
139 return Either.left(inputs);
143 public Either<List<ComponentInstanceInput>, ResponseFormat> getComponentInstanceInputs(String userId, String componentId, String componentInstanceId) {
145 validateUserExists(userId, "get Inputs", false);
146 ComponentParametersView filters = new ComponentParametersView();
147 filters.disableAll();
148 filters.setIgnoreInputs(false);
149 filters.setIgnoreComponentInstances(false);
150 filters.setIgnoreComponentInstancesInputs(false);
152 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
153 if(getComponentEither.isRight()){
154 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
155 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
156 return Either.right(componentsUtils.getResponseFormat(actionStatus));
159 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
161 if(!ComponentValidations.validateComponentInstanceExist(component, componentInstanceId)){
162 ActionStatus actionStatus = ActionStatus.COMPONENT_INSTANCE_NOT_FOUND;
163 log.debug("Failed to found component instance inputs {}, error: {}", componentInstanceId, actionStatus);
164 return Either.right(componentsUtils.getResponseFormat(actionStatus));
166 Map<String, List<ComponentInstanceInput>> ciInputs =
167 Optional.ofNullable(component.getComponentInstancesInputs()).orElse(Collections.emptyMap());
169 // Set Constraints on Input
170 MapUtils.emptyIfNull(ciInputs).values()
171 .forEach(inputs -> ListUtils.emptyIfNull(inputs)
172 .forEach(input -> input.setConstraints(setInputConstraint(input))));
173 return Either.left(ciInputs.getOrDefault(componentInstanceId, Collections.emptyList()));
177 * associate properties to a given component instance input
185 public Either<List<ComponentInstanceProperty>, ResponseFormat> getComponentInstancePropertiesByInputId(String userId, String componentId, String instanceId, String inputId) {
186 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
187 String parentId = componentId;
188 org.openecomp.sdc.be.model.Component component;
189 ComponentParametersView filters = new ComponentParametersView();
190 filters.disableAll();
191 filters.setIgnoreComponentInstances(false);
193 if(!instanceId.equals(inputId)){
196 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(parentId, filters);
198 if(getComponentEither.isRight()){
199 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
200 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, parentId, actionStatus);
201 return Either.right(componentsUtils.getResponseFormat(actionStatus));
204 component = getComponentEither.left().value();
205 Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci ->ci.getUniqueId().equals(instanceId)).findAny();
206 if(ciOp.isPresent()){
207 parentId = ciOp.get().getComponentUid();
212 filters.setIgnoreInputs(false);
214 filters.setIgnoreComponentInstancesProperties(false);
215 filters.setIgnoreComponentInstancesInputs(false);
216 filters.setIgnoreProperties(false);
218 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(parentId, filters);
220 if(getComponentEither.isRight()){
221 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
222 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, parentId, actionStatus);
223 return Either.right(componentsUtils.getResponseFormat(actionStatus));
226 component = getComponentEither.left().value();
228 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
230 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
231 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, parentId, actionStatus);
232 return Either.right(componentsUtils.getResponseFormat(actionStatus));
235 return Either.left(componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(component, inputId));
239 private Either<String,ResponseFormat> updateInputObjectValue(InputDefinition currentInput, InputDefinition newInput, Map<String, DataTypeDefinition> dataTypes) {
240 String innerType = null;
241 String propertyType = currentInput.getType();
242 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
243 log.debug("The type of the property {} is {}", currentInput.getUniqueId(), propertyType);
245 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
246 SchemaDefinition def = currentInput.getSchema();
248 log.debug("Schema doesn't exists for property of type {}", type);
249 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
251 PropertyDataDefinition propDef = def.getProperty();
252 if (propDef == null) {
253 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
254 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
256 innerType = propDef.getType();
258 // Specific Update Logic
260 Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, newInput.getDefaultValue(), true, innerType, dataTypes);
262 String newValue = currentInput.getDefaultValue();
263 if (isValid.isRight()) {
264 Boolean res = isValid.right().value();
265 if (Boolean.FALSE.equals(res)) {
266 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
267 JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
270 Object object = isValid.left().value();
271 if (object != null) {
272 newValue = object.toString();
275 return Either.left(newValue);
278 private InputDefinition getInputFromInputsListById(List<InputDefinition> componentsOldInputs, InputDefinition input) {
279 return componentsOldInputs.stream().filter(in -> in.getUniqueId().equals(input.getUniqueId())).findFirst().orElse(null);
282 public Either<List<InputDefinition>, ResponseFormat> updateInputsValue(ComponentTypeEnum componentType, String componentId, List<InputDefinition> inputs, String userId, boolean shouldLockComp, boolean inTransaction) {
284 List<InputDefinition> returnInputs = new ArrayList<>();
285 Either<List<InputDefinition>, ResponseFormat> result = null;
286 org.openecomp.sdc.be.model.Component component = null;
289 validateUserExists(userId, "get input", false);
291 ComponentParametersView componentParametersView = new ComponentParametersView();
292 componentParametersView.disableAll();
293 componentParametersView.setIgnoreInputs(false);
294 componentParametersView.setIgnoreUsers(false);
295 componentParametersView.setIgnoreProperties(false);
296 componentParametersView.setIgnoreComponentInstancesProperties(false);
297 componentParametersView.setIgnoreComponentInstances(false);
299 Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(componentId, componentType, componentParametersView);
301 if (validateComponent.isRight()) {
302 result = Either.right(validateComponent.right().value());
305 component = validateComponent.left().value();
307 if (shouldLockComp) {
308 Either<Boolean, ResponseFormat> lockComponent = lockComponent(component, UPDATE_INPUT);
309 if (lockComponent.isRight()) {
310 result = Either.right(lockComponent.right().value());
315 Either<Boolean, ResponseFormat> canWork = validateCanWorkOnComponent(component, userId);
316 if (canWork.isRight()) {
317 result = Either.right(canWork.right().value());
321 //Validate value and Constraint of input
322 Either<Boolean, ResponseFormat> constraintValidatorResponse = validateInputValueConstraint(inputs);
323 if (constraintValidatorResponse.isRight()) {
324 log.error("Failed validation value and constraint of property: {}",
325 constraintValidatorResponse.right().value());
326 return Either.right(constraintValidatorResponse.right().value());
329 Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache);
330 if (allDataTypes.isRight()) {
331 result = Either.right(allDataTypes.right().value());
335 Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
336 List<InputDefinition> componentsOldInputs = Optional.ofNullable(component.getInputs()).orElse(Collections.emptyList());
337 for (InputDefinition newInput: inputs) {
338 InputDefinition currInput = getInputFromInputsListById(componentsOldInputs, newInput);
339 if (currInput == null) {
340 ActionStatus actionStatus = ActionStatus.COMPONENT_NOT_FOUND;
341 log.debug("Failed to found newInput {} under component {}, error: {}", newInput.getUniqueId(), componentId, actionStatus);
342 result = Either.right(componentsUtils.getResponseFormat(actionStatus));
345 Either<String, ResponseFormat> updateInputObjectValue = updateInputObjectValue(currInput, newInput, dataTypes);
346 if ( updateInputObjectValue.isRight()) {
347 return Either.right(updateInputObjectValue.right().value());
349 String newValue = updateInputObjectValue.left().value();
350 currInput.setValue(newValue);
351 currInput.setDefaultValue(newValue);
352 currInput.setOwnerId(userId);
353 Either<InputDefinition, StorageOperationStatus> status = toscaOperationFacade.updateInputOfComponent(component, currInput);
354 if(status.isRight()){
355 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status.right().value());
356 result = Either.right(componentsUtils.getResponseFormat(actionStatus, ""));
359 returnInputs.add(status.left().value());
362 result = Either.left(returnInputs);
365 if (!inTransaction) {
366 if (result == null || result.isRight()) {
367 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
368 janusGraphDao.rollback();
370 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
371 janusGraphDao.commit();
375 if (shouldLockComp && component != null) {
376 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
381 private Either<Boolean, ResponseFormat> validateInputValueConstraint(List<InputDefinition> inputs) {
382 PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil =
383 PropertyValueConstraintValidationUtil.getInstance();
384 List<InputDefinition> inputDefinitions = new ArrayList<>();
385 for (InputDefinition inputDefinition : inputs) {
386 InputDefinition inputDef = new InputDefinition();
387 inputDefinition.setDefaultValue(inputDefinition.getDefaultValue());
388 inputDefinition.setInputPath(inputDefinition.getSubPropertyInputPath());
389 inputDefinition.setType(inputDefinition.getType());
390 if (Objects.nonNull(inputDefinition.getParentPropertyType())) {
391 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
392 propertyDefinition.setType(inputDefinition.getParentPropertyType());
394 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
397 inputDefinitions.add(inputDef);
400 return propertyValueConstraintValidationUtil.validatePropertyConstraints(inputDefinitions, applicationDataTypeCache);
403 public Either<List<ComponentInstanceInput>, ResponseFormat> getInputsForComponentInput(String userId, String componentId, String inputId) {
404 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
405 org.openecomp.sdc.be.model.Component component = null;
406 ComponentParametersView filters = new ComponentParametersView();
407 filters.disableAll();
408 filters.setIgnoreComponentInstances(false);
409 filters.setIgnoreInputs(false);
410 filters.setIgnoreComponentInstancesInputs(false);
411 filters.setIgnoreProperties(false);
413 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
415 if(getComponentEither.isRight()){
416 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
417 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
418 return Either.right(componentsUtils.getResponseFormat(actionStatus));
421 component = getComponentEither.left().value();
423 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
425 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
426 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, componentId, actionStatus);
427 return Either.right(componentsUtils.getResponseFormat(actionStatus));
430 return Either.left(componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(component, inputId));
435 public Either<List<InputDefinition>, ResponseFormat> declareProperties(String userId, String componentId,
436 ComponentTypeEnum componentTypeEnum, ComponentInstInputsMap componentInstInputsMap) {
438 return createMultipleInputs(userId, componentId, componentTypeEnum, componentInstInputsMap, true, false);
441 public Either<List<InputDefinition>, ResponseFormat> createMultipleInputs(String userId, String componentId, ComponentTypeEnum componentType, ComponentInstInputsMap componentInstInputsMapUi, boolean shouldLockComp, boolean inTransaction) {
443 Either<List<InputDefinition>, ResponseFormat> result = null;
444 org.openecomp.sdc.be.model.Component component = null;
447 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
449 component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
451 result = propertyDeclarationOrchestrator.declarePropertiesToInputs(component, componentInstInputsMapUi)
453 .bind(inputsToCreate -> prepareInputsForCreation(userId, componentId, inputsToCreate))
455 .map(componentsUtils::getResponseFormat);
459 } catch (ByResponseFormatComponentException e) {
460 log.error("#createMultipleInputs: Exception thrown: ", e);
461 result = Either.right(e.getResponseFormat());
465 if (!inTransaction) {
466 if (result == null || result.isRight()) {
467 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
468 janusGraphDao.rollback();
470 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
471 janusGraphDao.commit();
475 if (shouldLockComp && component != null) {
476 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
483 * Creates a list input with a data type which has properties specified.
485 * @param userId User ID
486 * @param componentId Component ID
487 * @param componentType Component type
488 * @param componentListInput Properties to be declared and input to be created
489 * @param shouldLockComp true if the component should be locked
490 * @param inTransaction true if already in transaction
492 public Either<List<InputDefinition>, ResponseFormat> createListInput(String userId, String componentId,
493 ComponentTypeEnum componentType, ComponentInstListInput componentListInput, boolean shouldLockComp,
494 boolean inTransaction) {
496 Either<List<InputDefinition>, ResponseFormat> result = null;
497 org.openecomp.sdc.be.model.Component component = null;
499 log.trace("#createListInput: enter");
502 /* check if user exists */
503 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
505 component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
507 InputDefinition listInput = componentListInput.getListInput();
508 DataTypeDefinition dataType =
509 prepareDataTypeForListInput(componentListInput.getComponentInstInputsMap(), listInput);
510 Map<String, DataTypeDefinition> dataTypesMap = new HashMap<>();
511 dataTypesMap.put(dataType.getName(), dataType);
512 if (log.isDebugEnabled()) {
513 log.debug("#createListInput: dataTypesMap={}", ReflectionToStringBuilder.toString(dataTypesMap));
516 Either<List<DataTypeDefinition>, StorageOperationStatus> dataTypeResult =
517 toscaOperationFacade.addDataTypesToComponent(dataTypesMap, componentId);
518 if (dataTypeResult.isRight()) {
519 log.debug("#createListInput: DataType creation failed.");
520 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(dataTypeResult.right().value()));
524 listInput.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(componentId, listInput.getName()));
525 listInput.setInstanceUniqueId(
526 propertyDeclarationOrchestrator.getPropOwnerId(componentListInput.getComponentInstInputsMap()));
527 listInput.setIsDeclaredListInput(true);
528 Map<String, InputDefinition> listInputMap = new HashMap<>();
529 listInputMap.put(listInput.getName(), listInput);
530 result = createListInputsInGraph(listInputMap, dataTypesMap, component);
531 if (result.isRight()) {
532 log.debug("#createListInput: createListInputsInGraph failed.");
533 throw new ByResponseFormatComponentException(result.right().value());
537 result = propertyDeclarationOrchestrator
538 .declarePropertiesToListInput(component, componentListInput.getComponentInstInputsMap(), listInput)
539 .right().map(err -> componentsUtils.getResponseFormat(err))
540 .left().map(Arrays::asList);
542 log.trace("#createListInput: leave");
546 } catch (ByResponseFormatComponentException e) {
547 log.error("#createListInput: Exception thrown", e);
548 result = Either.right(e.getResponseFormat());
552 if (!inTransaction) {
553 if (result == null || result.isRight()) {
554 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
555 janusGraphDao.rollback();
557 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
558 janusGraphDao.commit();
562 if (shouldLockComp && component != null) {
563 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
568 private ComponentParametersView getBaseComponentParametersView() {
569 ComponentParametersView componentParametersView = new ComponentParametersView();
570 componentParametersView.disableAll();
571 componentParametersView.setIgnoreInputs(false);
572 componentParametersView.setIgnoreComponentInstances(false);
573 componentParametersView.setIgnoreComponentInstancesInputs(false);
574 componentParametersView.setIgnoreComponentInstancesProperties(false);
575 componentParametersView.setIgnorePolicies(false);
576 componentParametersView.setIgnoreGroups(false);
577 componentParametersView.setIgnoreUsers(false);
578 return componentParametersView;
581 private org.openecomp.sdc.be.model.Component getAndValidateComponentForCreate(
582 String userId, String componentId, ComponentTypeEnum componentType, boolean shouldLockComp
585 ComponentParametersView componentParametersView = getBaseComponentParametersView();
587 Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither =
588 // get Component Object
589 validateComponentExists(componentId, componentType, componentParametersView)
590 .left().bind(component -> {
591 if (shouldLockComp) {
592 // lock the component
593 return lockComponent(component, CREATE_INPUT).left().map(result -> component);
595 return Either.left(component);
596 }).left().bind(component -> validateCanWorkOnComponent(component, userId).left().map(result -> component));
597 if (componentEither.isRight()) {
598 throw new ByResponseFormatComponentException(componentEither.right().value());
600 return componentEither.left().value();
603 private DataTypeDefinition prepareDataTypeForListInput(ComponentInstInputsMap inputsMap, InputDefinition input) {
604 // Confirm if type is list
605 if (StringUtils.isEmpty(input.getType()) || !input.getType().equals(ToscaPropertyType.LIST.getType())) {
606 log.debug("#prepareDataTypeForListInput: Type of input is not list.");
607 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE));
610 // Confirm schema type is not empty
611 String desiredTypeName = input.getSchemaType();
612 if (StringUtils.isEmpty(desiredTypeName)) {
613 log.debug("#prepareDataTypeForListInput: Schema type of list input is empty.");
614 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE));
617 DataTypeDefinition dataType = new DataTypeDefinition();
618 List<ComponentInstancePropInput> propInputs = inputsMap.resolvePropertiesToDeclare().getRight();
619 dataType.setName(desiredTypeName);
620 dataType.setDerivedFromName(ToscaPropertyType.Root.getType());
621 // Copy properties from inputsMap
622 dataType.setProperties(propInputs.stream().map(PropertyDefinition::new).collect(Collectors.toList()));
626 private Either<List<InputDefinition>, StorageOperationStatus> prepareInputsForCreation(String userId, String cmptId, List<InputDefinition> inputsToCreate) {
627 Map<String, InputDefinition> inputsToPersist = MapUtil.toMap(inputsToCreate, InputDefinition::getName);
628 assignOwnerIdToInputs(userId, inputsToPersist);
629 inputsToPersist.values()
630 .forEach(input -> input.setConstraints(componentInstanceBusinessLogic.setInputConstraint(input)));
632 return toscaOperationFacade.addInputsToComponent(inputsToPersist, cmptId)
634 .map(persistedInputs -> inputsToCreate);
637 private void assignOwnerIdToInputs(String userId, Map<String, InputDefinition> inputsToCreate) {
638 inputsToCreate.values().forEach(inputDefinition -> inputDefinition.setOwnerId(userId));
641 public Either<List<InputDefinition>, ResponseFormat> createInputsInGraph(Map<String, InputDefinition> inputs, org.openecomp.sdc.be.model.Component component) {
643 List<InputDefinition> resourceProperties = component.getInputs();
644 Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache);
645 if (allDataTypes.isRight()) {
646 return Either.right(allDataTypes.right().value());
649 Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
651 for (Map.Entry<String, InputDefinition> inputDefinition : inputs.entrySet()) {
652 String inputName = inputDefinition.getKey();
653 inputDefinition.getValue().setName(inputName);
655 Either<InputDefinition, ResponseFormat> preparedInputEither = prepareAndValidateInputBeforeCreate(inputDefinition.getValue(), dataTypes);
656 if(preparedInputEither.isRight()){
657 return Either.right(preparedInputEither.right().value());
661 if (resourceProperties != null) {
662 Map<String, InputDefinition> generatedInputs = resourceProperties.stream().collect(Collectors.toMap(PropertyDataDefinition::getName, i -> i));
663 Either<Map<String, InputDefinition>, String> mergeEither = ToscaDataDefinition.mergeDataMaps(generatedInputs, inputs);
664 if(mergeEither.isRight()){
665 return Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_ALREADY_EXIST, mergeEither.right().value()));
667 inputs = mergeEither.left().value();
670 Either<List<InputDefinition>, StorageOperationStatus> associateInputsEither = toscaOperationFacade.createAndAssociateInputs(inputs, component.getUniqueId());
671 if(associateInputsEither.isRight()){
672 log.debug("Failed to create inputs under component {}. Status is {}", component.getUniqueId(), associateInputsEither.right().value());
673 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(associateInputsEither.right().value())));
675 return Either.left(associateInputsEither.left().value());
678 private Either<List<InputDefinition>, ResponseFormat> createListInputsInGraph(Map<String, InputDefinition> inputs,
679 Map<String, DataTypeDefinition> privateDataTypes, org.openecomp.sdc.be.model.Component component) {
681 log.trace("#createListInputsInGraph: enter");
682 Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(
683 applicationDataTypeCache);
684 if (allDataTypes.isRight()) {
685 return Either.right(allDataTypes.right().value());
688 Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
689 dataTypes.putAll(privateDataTypes);
691 for (Map.Entry<String, InputDefinition> inputDefinition : inputs.entrySet()) {
692 String inputName = inputDefinition.getKey();
693 inputDefinition.getValue().setName(inputName);
695 Either<InputDefinition, ResponseFormat> preparedInputEither =
696 prepareAndValidateInputBeforeCreate(inputDefinition.getValue(), dataTypes);
697 if (preparedInputEither.isRight()) {
698 return Either.right(preparedInputEither.right().value());
702 Either<List<InputDefinition>, StorageOperationStatus> addInputsEither = toscaOperationFacade
703 .addInputsToComponent(inputs, component.getUniqueId());
704 if (addInputsEither.isRight()) {
705 log.debug("#createListInputsInGraph: Failed to create inputs under component {}. Status is {}",
706 component.getUniqueId(), addInputsEither.right().value());
707 return Either.right(componentsUtils.getResponseFormat(
708 componentsUtils.convertFromStorageResponse(addInputsEither.right().value())));
710 log.trace("#createListInputsInGraph: leave");
711 return Either.left(addInputsEither.left().value());
715 * Delete input from service
722 public Either<InputDefinition, ResponseFormat> deleteInput(String componentId, String userId, String inputId) {
724 Either<InputDefinition, ResponseFormat> deleteEither = null;
725 if (log.isDebugEnabled()) {
726 log.debug("Going to delete input id: {}", inputId);
729 validateUserExists(userId, "Delete input", true);
731 ComponentParametersView componentParametersView = getBaseComponentParametersView();
732 componentParametersView.setIgnoreInterfaces(false);
733 componentParametersView.setIgnoreDataType(false);
734 componentParametersView.setIgnoreProperties(false);
736 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentEither =
737 toscaOperationFacade.getToscaElement(componentId, componentParametersView);
738 if (componentEither.isRight()) {
739 deleteEither = Either.right(componentsUtils.getResponseFormat(
740 componentsUtils.convertFromStorageResponse(componentEither.right().value())));
743 org.openecomp.sdc.be.model.Component component = componentEither.left().value();
745 // Validate inputId is child of the component
746 Optional<InputDefinition> optionalInput = component.getInputs().stream().
748 filter(input -> input.getUniqueId().equals(inputId)).
751 if (!optionalInput.isPresent()) {
753 componentsUtils.getResponseFormat(ActionStatus.INPUT_IS_NOT_CHILD_OF_COMPONENT, inputId, componentId));
756 InputDefinition inputForDelete = optionalInput.get();
759 Either<Boolean, ResponseFormat> lockResultEither =
760 lockComponent(componentId, component, "deleteInput");
761 if (lockResultEither.isRight()) {
762 ResponseFormat responseFormat = lockResultEither.right().value();
763 deleteEither = Either.right(responseFormat);
767 // Delete input operations
769 StorageOperationStatus status =
770 toscaOperationFacade.deleteInputOfResource(component, inputForDelete.getName());
771 if (status != StorageOperationStatus.OK) {
772 log.debug("Component id: {} delete input id: {} failed", componentId, inputId);
773 deleteEither = Either.right(componentsUtils.getResponseFormat(
774 componentsUtils.convertFromStorageResponse(status), component.getName()));
778 if (BooleanUtils.isTrue(inputForDelete.getIsDeclaredListInput())){
779 deleteEither = deleteListInput(componentId, inputId, component, inputForDelete, status);
783 StorageOperationStatus storageOperationStatus =
784 propertyDeclarationOrchestrator.unDeclarePropertiesAsInputs(component, inputForDelete);
785 if (storageOperationStatus != StorageOperationStatus.OK) {
786 log.debug("Component id: {} update properties declared as input for input id: {} failed", componentId, inputId);
787 deleteEither = Either.right(componentsUtils.getResponseFormat(
788 componentsUtils.convertFromStorageResponse(status), component.getName()));
792 deleteEither = Either.left(inputForDelete);
795 if (deleteEither == null || deleteEither.isRight()) {
796 log.debug("Component id: {} delete input id: {} failed", componentId, inputId);
797 janusGraphDao.rollback();
799 log.debug("Component id: {} delete input id: {} success", componentId, inputId);
800 janusGraphDao.commit();
802 unlockComponent(deleteEither, component);
806 private Either<InputDefinition, ResponseFormat> deleteListInput(String componentId, String inputId,
807 org.openecomp.sdc.be.model.Component component,
808 InputDefinition inputForDelete, StorageOperationStatus status) {
809 // the input is created by 'Declare List'.
810 // need to 1. undeclare properties, 2. delete input, 3. delete private data type
812 StorageOperationStatus storageOperationStatus =
813 propertyDeclarationOrchestrator.unDeclarePropertiesAsListInputs(component, inputForDelete);
814 if (storageOperationStatus != StorageOperationStatus.OK) {
815 log.debug("Component id: {} update properties declared as input for input id: {} failed", componentId, inputId);
816 return Either.right(componentsUtils.getResponseFormat(
817 componentsUtils.convertFromStorageResponse(status), component.getName()));
819 Either<DataTypeDefinition, StorageOperationStatus> deleteResult =
820 dataTypeBusinessLogic.deletePrivateDataType(component, inputForDelete.getSchemaType());
821 if (deleteResult.isRight()) {
822 log.debug("Component id: {} delete datatype name: {} failed", componentId, inputForDelete.getSchemaType());
823 return Either.right(componentsUtils.getResponseFormat(
824 componentsUtils.convertFromStorageResponse(deleteResult.right().value()), component.getName()));
826 log.trace("deleteInput: deletePrivateDataType (OK)");
827 return Either.left(inputForDelete);
830 private Either<InputDefinition, ResponseFormat> prepareAndValidateInputBeforeCreate(InputDefinition newInputDefinition, Map<String, DataTypeDefinition> dataTypes) {
832 // validate input default values
833 Either<Boolean, ResponseFormat> defaultValuesValidation = validatePropertyDefaultValue(newInputDefinition, dataTypes);
834 if (defaultValuesValidation.isRight()) {
835 return Either.right(defaultValuesValidation.right().value());
838 ToscaPropertyType type = getType(newInputDefinition.getType());
839 if (type != null && newInputDefinition != null) {
840 PropertyValueConverter converter = type.getConverter();
842 SchemaDefinition schema = newInputDefinition.getSchema();
843 String innerType = null;
844 if (schema != null) {
845 PropertyDataDefinition prop = schema.getProperty();
847 innerType = prop.getType();
850 String convertedValue;
851 if (newInputDefinition.getDefaultValue() != null) {
852 convertedValue = converter.convert(newInputDefinition.getDefaultValue(), innerType, dataTypes);
853 newInputDefinition.setDefaultValue(convertedValue);
856 return Either.left(newInputDefinition);
859 public Either<InputDefinition, ResponseFormat> getInputsAndPropertiesForComponentInput(String userId, String componentId, String inputId, boolean inTransaction) {
860 Either<InputDefinition, ResponseFormat> result = null;
863 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
864 ComponentParametersView filters = new ComponentParametersView();
865 filters.disableAll();
866 filters.setIgnoreComponentInstances(false);
867 filters.setIgnoreInputs(false);
868 filters.setIgnoreComponentInstancesInputs(false);
869 filters.setIgnoreComponentInstancesProperties(false);
870 filters.setIgnoreProperties(false);
871 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
872 if(getComponentEither.isRight()){
873 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
874 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
875 return Either.right(componentsUtils.getResponseFormat(actionStatus));
878 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
879 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
881 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
882 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, componentId, actionStatus);
883 return Either.right(componentsUtils.getResponseFormat(actionStatus));
886 InputDefinition resObj = op.get();
888 List<ComponentInstanceInput> inputCIInput = componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(component, inputId) ;
890 resObj.setInputs(inputCIInput);
893 List<ComponentInstanceProperty> inputProps = componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(component, inputId) ;
895 resObj.setProperties(inputProps);
898 result = Either.left(resObj);
904 if (!inTransaction) {
906 if (result == null || result.isRight()) {
907 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
908 janusGraphDao.rollback();
910 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
911 janusGraphDao.commit();