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 java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.List;
31 import java.util.Objects;
32 import java.util.Optional;
33 import java.util.stream.Collectors;
34 import org.apache.commons.collections4.ListUtils;
35 import org.apache.commons.collections4.MapUtils;
36 import org.apache.commons.lang.BooleanUtils;
37 import org.apache.commons.lang.StringUtils;
38 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
39 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
40 import org.openecomp.sdc.be.components.property.PropertyDeclarationOrchestrator;
41 import org.openecomp.sdc.be.components.validation.ComponentValidations;
42 import org.openecomp.sdc.be.dao.api.ActionStatus;
43 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
44 import org.openecomp.sdc.be.dao.utils.MapUtil;
45 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
46 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
47 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
48 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
49 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
50 import org.openecomp.sdc.be.model.ComponentInstInputsMap;
51 import org.openecomp.sdc.be.model.ComponentInstListInput;
52 import org.openecomp.sdc.be.model.ComponentInstance;
53 import org.openecomp.sdc.be.model.ComponentInstanceInput;
54 import org.openecomp.sdc.be.model.ComponentInstancePropInput;
55 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
56 import org.openecomp.sdc.be.model.ComponentParametersView;
57 import org.openecomp.sdc.be.model.DataTypeDefinition;
58 import org.openecomp.sdc.be.model.InputDefinition;
59 import org.openecomp.sdc.be.model.PropertyDefinition;
60 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
61 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
62 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
63 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
64 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
65 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
66 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
67 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
68 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
69 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
70 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
71 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
72 import org.openecomp.sdc.common.log.wrappers.Logger;
73 import org.openecomp.sdc.exception.ResponseFormat;
74 import org.springframework.beans.factory.annotation.Autowired;
75 import org.springframework.stereotype.Component;
76 import fj.data.Either;
78 @Component("inputsBusinessLogic")
79 public class InputsBusinessLogic extends BaseBusinessLogic {
81 private static final String CREATE_INPUT = "CreateInput";
82 private static final String UPDATE_INPUT = "UpdateInput";
84 private static final Logger log = Logger.getLogger(InputsBusinessLogic.class);
85 private static final String FAILED_TO_FOUND_COMPONENT_ERROR = "Failed to found component {}, error: {}";
86 private static final String GET_PROPERTIES_BY_INPUT = "get Properties by input";
87 private static final String FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR = "Failed to found input {} under component {}, error: {}";
88 private static final String GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP = "Going to execute rollback on create group.";
89 private static final String GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP = "Going to execute commit on create group.";
91 private final PropertyDeclarationOrchestrator propertyDeclarationOrchestrator;
92 private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
93 private final DataTypeBusinessLogic dataTypeBusinessLogic;
96 public InputsBusinessLogic(IElementOperation elementDao,
97 IGroupOperation groupOperation,
98 IGroupInstanceOperation groupInstanceOperation,
99 IGroupTypeOperation groupTypeOperation,
100 InterfaceOperation interfaceOperation,
101 InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
102 PropertyDeclarationOrchestrator propertyDeclarationOrchestrator,
103 ComponentInstanceBusinessLogic componentInstanceBusinessLogic, DataTypeBusinessLogic dataTypeBusinessLogic,
104 ArtifactsOperations artifactToscaOperation) {
105 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
106 interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
107 this.propertyDeclarationOrchestrator = propertyDeclarationOrchestrator;
108 this.componentInstanceBusinessLogic = componentInstanceBusinessLogic;
109 this.dataTypeBusinessLogic = dataTypeBusinessLogic;
113 * associate inputs to a given component with paging
119 public Either<List<InputDefinition>, ResponseFormat> getInputs(String userId, String componentId) {
121 validateUserExists(userId, "get Inputs", false);
123 ComponentParametersView filters = new ComponentParametersView();
124 filters.disableAll();
125 filters.setIgnoreInputs(false);
127 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
128 if(getComponentEither.isRight()){
129 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
130 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
131 return Either.right(componentsUtils.getResponseFormat(actionStatus));
134 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
135 List<InputDefinition> inputs = component.getInputs();
137 return Either.left(inputs);
141 public Either<List<ComponentInstanceInput>, ResponseFormat> getComponentInstanceInputs(String userId, String componentId, String componentInstanceId) {
143 validateUserExists(userId, "get Inputs", false);
144 ComponentParametersView filters = new ComponentParametersView();
145 filters.disableAll();
146 filters.setIgnoreInputs(false);
147 filters.setIgnoreComponentInstances(false);
148 filters.setIgnoreComponentInstancesInputs(false);
150 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
151 if(getComponentEither.isRight()){
152 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
153 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
154 return Either.right(componentsUtils.getResponseFormat(actionStatus));
157 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
159 if(!ComponentValidations.validateComponentInstanceExist(component, componentInstanceId)){
160 ActionStatus actionStatus = ActionStatus.COMPONENT_INSTANCE_NOT_FOUND;
161 log.debug("Failed to found component instance inputs {}, error: {}", componentInstanceId, actionStatus);
162 return Either.right(componentsUtils.getResponseFormat(actionStatus));
164 Map<String, List<ComponentInstanceInput>> ciInputs =
165 Optional.ofNullable(component.getComponentInstancesInputs()).orElse(Collections.emptyMap());
167 // Set Constraints on Input
168 MapUtils.emptyIfNull(ciInputs).values()
169 .forEach(inputs -> ListUtils.emptyIfNull(inputs)
170 .forEach(input -> input.setConstraints(setInputConstraint(input))));
171 return Either.left(ciInputs.getOrDefault(componentInstanceId, Collections.emptyList()));
175 * associate properties to a given component instance input
183 public Either<List<ComponentInstanceProperty>, ResponseFormat> getComponentInstancePropertiesByInputId(String userId, String componentId, String instanceId, String inputId) {
184 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
185 String parentId = componentId;
186 org.openecomp.sdc.be.model.Component component;
187 ComponentParametersView filters = new ComponentParametersView();
188 filters.disableAll();
189 filters.setIgnoreComponentInstances(false);
191 if(!instanceId.equals(inputId)){
194 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(parentId, filters);
196 if(getComponentEither.isRight()){
197 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
198 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, parentId, actionStatus);
199 return Either.right(componentsUtils.getResponseFormat(actionStatus));
202 component = getComponentEither.left().value();
203 Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci ->ci.getUniqueId().equals(instanceId)).findAny();
204 if(ciOp.isPresent()){
205 parentId = ciOp.get().getComponentUid();
210 filters.setIgnoreInputs(false);
212 filters.setIgnoreComponentInstancesProperties(false);
213 filters.setIgnoreComponentInstancesInputs(false);
214 filters.setIgnoreProperties(false);
216 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(parentId, filters);
218 if(getComponentEither.isRight()){
219 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
220 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, parentId, actionStatus);
221 return Either.right(componentsUtils.getResponseFormat(actionStatus));
224 component = getComponentEither.left().value();
226 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
228 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
229 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, parentId, actionStatus);
230 return Either.right(componentsUtils.getResponseFormat(actionStatus));
233 return Either.left(componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(component, inputId));
237 private Either<String,ResponseFormat> updateInputObjectValue(InputDefinition currentInput, InputDefinition newInput, Map<String, DataTypeDefinition> dataTypes) {
238 String innerType = null;
239 String propertyType = currentInput.getType();
240 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
241 log.debug("The type of the property {} is {}", currentInput.getUniqueId(), propertyType);
243 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
244 SchemaDefinition def = currentInput.getSchema();
246 log.debug("Schema doesn't exists for property of type {}", type);
247 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
249 PropertyDataDefinition propDef = def.getProperty();
250 if (propDef == null) {
251 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
252 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
254 innerType = propDef.getType();
256 // Specific Update Logic
258 Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, newInput.getDefaultValue(), true, innerType, dataTypes);
260 String newValue = currentInput.getDefaultValue();
261 if (isValid.isRight()) {
262 Boolean res = isValid.right().value();
263 if (Boolean.FALSE.equals(res)) {
264 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
265 JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
268 Object object = isValid.left().value();
269 if (object != null) {
270 newValue = object.toString();
273 return Either.left(newValue);
276 private InputDefinition getInputFromInputsListById(List<InputDefinition> componentsOldInputs, InputDefinition input) {
277 return componentsOldInputs.stream().filter(in -> in.getUniqueId().equals(input.getUniqueId())).findFirst().orElse(null);
280 public Either<List<InputDefinition>, ResponseFormat> updateInputsValue(ComponentTypeEnum componentType, String componentId, List<InputDefinition> inputs, String userId, boolean shouldLockComp, boolean inTransaction) {
282 List<InputDefinition> returnInputs = new ArrayList<>();
283 Either<List<InputDefinition>, ResponseFormat> result = null;
284 org.openecomp.sdc.be.model.Component component = null;
287 validateUserExists(userId, "get input", false);
289 ComponentParametersView componentParametersView = new ComponentParametersView();
290 componentParametersView.disableAll();
291 componentParametersView.setIgnoreInputs(false);
292 componentParametersView.setIgnoreUsers(false);
293 componentParametersView.setIgnoreProperties(false);
294 componentParametersView.setIgnoreComponentInstancesProperties(false);
295 componentParametersView.setIgnoreComponentInstances(false);
297 Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(componentId, componentType, componentParametersView);
299 if (validateComponent.isRight()) {
300 result = Either.right(validateComponent.right().value());
303 component = validateComponent.left().value();
305 if (shouldLockComp) {
306 Either<Boolean, ResponseFormat> lockComponent = lockComponent(component, UPDATE_INPUT);
307 if (lockComponent.isRight()) {
308 result = Either.right(lockComponent.right().value());
313 Either<Boolean, ResponseFormat> canWork = validateCanWorkOnComponent(component, userId);
314 if (canWork.isRight()) {
315 result = Either.right(canWork.right().value());
319 //Validate value and Constraint of input
320 Either<Boolean, ResponseFormat> constraintValidatorResponse = validateInputValueConstraint(inputs);
321 if (constraintValidatorResponse.isRight()) {
322 log.error("Failed validation value and constraint of property: {}",
323 constraintValidatorResponse.right().value());
324 return Either.right(constraintValidatorResponse.right().value());
327 Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache);
328 if (allDataTypes.isRight()) {
329 result = Either.right(allDataTypes.right().value());
333 Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
334 List<InputDefinition> componentsOldInputs = Optional.ofNullable(component.getInputs()).orElse(Collections.emptyList());
335 for (InputDefinition newInput: inputs) {
336 InputDefinition currInput = getInputFromInputsListById(componentsOldInputs, newInput);
337 if (currInput == null) {
338 ActionStatus actionStatus = ActionStatus.COMPONENT_NOT_FOUND;
339 log.debug("Failed to found newInput {} under component {}, error: {}", newInput.getUniqueId(), componentId, actionStatus);
340 result = Either.right(componentsUtils.getResponseFormat(actionStatus));
343 Either<String, ResponseFormat> updateInputObjectValue = updateInputObjectValue(currInput, newInput, dataTypes);
344 if ( updateInputObjectValue.isRight()) {
345 return Either.right(updateInputObjectValue.right().value());
347 String newValue = updateInputObjectValue.left().value();
348 currInput.setValue(newValue);
349 currInput.setDefaultValue(newValue);
350 currInput.setOwnerId(userId);
351 Either<InputDefinition, StorageOperationStatus> status = toscaOperationFacade.updateInputOfComponent(component, currInput);
352 if(status.isRight()){
353 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status.right().value());
354 result = Either.right(componentsUtils.getResponseFormat(actionStatus, ""));
357 returnInputs.add(status.left().value());
360 result = Either.left(returnInputs);
363 if (!inTransaction) {
364 if (result == null || result.isRight()) {
365 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
366 janusGraphDao.rollback();
368 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
369 janusGraphDao.commit();
373 if (shouldLockComp && component != null) {
374 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
379 private Either<Boolean, ResponseFormat> validateInputValueConstraint(List<InputDefinition> inputs) {
380 PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil =
381 PropertyValueConstraintValidationUtil.getInstance();
382 List<InputDefinition> inputDefinitions = new ArrayList<>();
383 for (InputDefinition inputDefinition : inputs) {
384 InputDefinition inputDef = new InputDefinition();
385 inputDefinition.setDefaultValue(inputDefinition.getDefaultValue());
386 inputDefinition.setInputPath(inputDefinition.getSubPropertyInputPath());
387 inputDefinition.setType(inputDefinition.getType());
388 if (Objects.nonNull(inputDefinition.getParentPropertyType())) {
389 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
390 propertyDefinition.setType(inputDefinition.getParentPropertyType());
392 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
395 inputDefinitions.add(inputDef);
398 return propertyValueConstraintValidationUtil.validatePropertyConstraints(inputDefinitions, applicationDataTypeCache);
401 public Either<List<ComponentInstanceInput>, ResponseFormat> getInputsForComponentInput(String userId, String componentId, String inputId) {
402 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
403 org.openecomp.sdc.be.model.Component component = null;
404 ComponentParametersView filters = new ComponentParametersView();
405 filters.disableAll();
406 filters.setIgnoreComponentInstances(false);
407 filters.setIgnoreInputs(false);
408 filters.setIgnoreComponentInstancesInputs(false);
409 filters.setIgnoreProperties(false);
411 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
413 if(getComponentEither.isRight()){
414 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
415 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
416 return Either.right(componentsUtils.getResponseFormat(actionStatus));
419 component = getComponentEither.left().value();
421 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
423 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
424 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, componentId, actionStatus);
425 return Either.right(componentsUtils.getResponseFormat(actionStatus));
428 return Either.left(componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(component, inputId));
433 public Either<List<InputDefinition>, ResponseFormat> declareProperties(String userId, String componentId,
434 ComponentTypeEnum componentTypeEnum, ComponentInstInputsMap componentInstInputsMap) {
436 return createMultipleInputs(userId, componentId, componentTypeEnum, componentInstInputsMap, true, false);
439 public Either<List<InputDefinition>, ResponseFormat> createMultipleInputs(String userId, String componentId, ComponentTypeEnum componentType, ComponentInstInputsMap componentInstInputsMapUi, boolean shouldLockComp, boolean inTransaction) {
441 Either<List<InputDefinition>, ResponseFormat> result = null;
442 org.openecomp.sdc.be.model.Component component = null;
445 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
447 component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
449 result = propertyDeclarationOrchestrator.declarePropertiesToInputs(component, componentInstInputsMapUi)
451 .bind(inputsToCreate -> prepareInputsForCreation(userId, componentId, inputsToCreate))
453 .map(componentsUtils::getResponseFormat);
457 } catch (ByResponseFormatComponentException e) {
458 log.error("#createMultipleInputs: Exception thrown: ", e);
459 result = Either.right(e.getResponseFormat());
463 if (!inTransaction) {
464 if (result == null || result.isRight()) {
465 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
466 janusGraphDao.rollback();
468 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
469 janusGraphDao.commit();
473 if (shouldLockComp && component != null) {
474 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
481 * Creates a list input with a data type which has properties specified.
483 * @param userId User ID
484 * @param componentId Component ID
485 * @param componentType Component type
486 * @param componentListInput Properties to be declared and input to be created
487 * @param shouldLockComp true if the component should be locked
488 * @param inTransaction true if already in transaction
490 public Either<List<InputDefinition>, ResponseFormat> createListInput(String userId, String componentId,
491 ComponentTypeEnum componentType, ComponentInstListInput componentListInput, boolean shouldLockComp,
492 boolean inTransaction) {
494 Either<List<InputDefinition>, ResponseFormat> result = null;
495 org.openecomp.sdc.be.model.Component component = null;
497 log.trace("#createListInput: enter");
500 /* check if user exists */
501 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
503 component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
505 InputDefinition listInput = componentListInput.getListInput();
506 DataTypeDefinition dataType =
507 prepareDataTypeForListInput(componentListInput.getComponentInstInputsMap(), listInput);
508 Map<String, DataTypeDefinition> dataTypesMap = new HashMap<>();
509 dataTypesMap.put(dataType.getName(), dataType);
510 if (log.isDebugEnabled()) {
511 log.debug("#createListInput: dataTypesMap={}", ReflectionToStringBuilder.toString(dataTypesMap));
514 Either<List<DataTypeDefinition>, StorageOperationStatus> dataTypeResult =
515 toscaOperationFacade.addDataTypesToComponent(dataTypesMap, componentId);
516 if (dataTypeResult.isRight()) {
517 log.debug("#createListInput: DataType creation failed.");
518 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(dataTypeResult.right().value()));
522 listInput.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(componentId, listInput.getName()));
523 listInput.setInstanceUniqueId(
524 propertyDeclarationOrchestrator.getPropOwnerId(componentListInput.getComponentInstInputsMap()));
525 listInput.setIsDeclaredListInput(true);
526 Map<String, InputDefinition> listInputMap = new HashMap<>();
527 listInputMap.put(listInput.getName(), listInput);
528 result = createListInputsInGraph(listInputMap, dataTypesMap, component);
529 if (result.isRight()) {
530 log.debug("#createListInput: createListInputsInGraph failed.");
531 throw new ByResponseFormatComponentException(result.right().value());
535 result = propertyDeclarationOrchestrator
536 .declarePropertiesToListInput(component, componentListInput.getComponentInstInputsMap(), listInput)
537 .right().map(err -> componentsUtils.getResponseFormat(err))
538 .left().map(Arrays::asList);
540 log.trace("#createListInput: leave");
544 } catch (ByResponseFormatComponentException e) {
545 log.error("#createListInput: Exception thrown", e);
546 result = Either.right(e.getResponseFormat());
550 if (!inTransaction) {
551 if (result == null || result.isRight()) {
552 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
553 janusGraphDao.rollback();
555 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
556 janusGraphDao.commit();
560 if (shouldLockComp && component != null) {
561 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
566 private ComponentParametersView getBaseComponentParametersView() {
567 ComponentParametersView componentParametersView = new ComponentParametersView();
568 componentParametersView.disableAll();
569 componentParametersView.setIgnoreInputs(false);
570 componentParametersView.setIgnoreComponentInstances(false);
571 componentParametersView.setIgnoreComponentInstancesInputs(false);
572 componentParametersView.setIgnoreComponentInstancesProperties(false);
573 componentParametersView.setIgnorePolicies(false);
574 componentParametersView.setIgnoreGroups(false);
575 componentParametersView.setIgnoreUsers(false);
576 return componentParametersView;
579 private org.openecomp.sdc.be.model.Component getAndValidateComponentForCreate(
580 String userId, String componentId, ComponentTypeEnum componentType, boolean shouldLockComp
583 ComponentParametersView componentParametersView = getBaseComponentParametersView();
585 Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither =
586 // get Component Object
587 validateComponentExists(componentId, componentType, componentParametersView)
588 .left().bind(component -> {
589 if (shouldLockComp) {
590 // lock the component
591 return lockComponent(component, CREATE_INPUT).left().map(result -> component);
593 return Either.left(component);
594 }).left().bind(component -> validateCanWorkOnComponent(component, userId).left().map(result -> component));
595 if (componentEither.isRight()) {
596 throw new ByResponseFormatComponentException(componentEither.right().value());
598 return componentEither.left().value();
601 private DataTypeDefinition prepareDataTypeForListInput(ComponentInstInputsMap inputsMap, InputDefinition input) {
602 // Confirm if type is list
603 if (StringUtils.isEmpty(input.getType()) || !input.getType().equals(ToscaPropertyType.LIST.getType())) {
604 log.debug("#prepareDataTypeForListInput: Type of input is not list.");
605 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE));
608 // Confirm schema type is not empty
609 String desiredTypeName = input.getSchemaType();
610 if (StringUtils.isEmpty(desiredTypeName)) {
611 log.debug("#prepareDataTypeForListInput: Schema type of list input is empty.");
612 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE));
615 DataTypeDefinition dataType = new DataTypeDefinition();
616 List<ComponentInstancePropInput> propInputs = inputsMap.resolvePropertiesToDeclare().getRight();
617 dataType.setName(desiredTypeName);
618 dataType.setDerivedFromName(ToscaPropertyType.Root.getType());
619 // Copy properties from inputsMap
620 dataType.setProperties(propInputs.stream().map(PropertyDefinition::new).collect(Collectors.toList()));
624 private Either<List<InputDefinition>, StorageOperationStatus> prepareInputsForCreation(String userId, String cmptId, List<InputDefinition> inputsToCreate) {
625 Map<String, InputDefinition> inputsToPersist = MapUtil.toMap(inputsToCreate, InputDefinition::getName);
626 assignOwnerIdToInputs(userId, inputsToPersist);
627 inputsToPersist.values()
628 .forEach(input -> input.setConstraints(componentInstanceBusinessLogic.setInputConstraint(input)));
630 return toscaOperationFacade.addInputsToComponent(inputsToPersist, cmptId)
632 .map(persistedInputs -> inputsToCreate);
635 private void assignOwnerIdToInputs(String userId, Map<String, InputDefinition> inputsToCreate) {
636 inputsToCreate.values().forEach(inputDefinition -> inputDefinition.setOwnerId(userId));
639 public Either<List<InputDefinition>, ResponseFormat> createInputsInGraph(Map<String, InputDefinition> inputs, org.openecomp.sdc.be.model.Component component) {
641 List<InputDefinition> resourceProperties = component.getInputs();
642 Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache);
643 if (allDataTypes.isRight()) {
644 return Either.right(allDataTypes.right().value());
647 Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
649 for (Map.Entry<String, InputDefinition> inputDefinition : inputs.entrySet()) {
650 String inputName = inputDefinition.getKey();
651 inputDefinition.getValue().setName(inputName);
653 Either<InputDefinition, ResponseFormat> preparedInputEither = prepareAndValidateInputBeforeCreate(inputDefinition.getValue(), dataTypes);
654 if(preparedInputEither.isRight()){
655 return Either.right(preparedInputEither.right().value());
659 if (resourceProperties != null) {
660 Map<String, InputDefinition> generatedInputs = resourceProperties.stream().collect(Collectors.toMap(PropertyDataDefinition::getName, i -> i));
661 Either<Map<String, InputDefinition>, String> mergeEither = ToscaDataDefinition.mergeDataMaps(generatedInputs, inputs);
662 if(mergeEither.isRight()){
663 return Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_ALREADY_EXIST, mergeEither.right().value()));
665 inputs = mergeEither.left().value();
668 Either<List<InputDefinition>, StorageOperationStatus> associateInputsEither = toscaOperationFacade.createAndAssociateInputs(inputs, component.getUniqueId());
669 if(associateInputsEither.isRight()){
670 log.debug("Failed to create inputs under component {}. Status is {}", component.getUniqueId(), associateInputsEither.right().value());
671 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(associateInputsEither.right().value())));
673 return Either.left(associateInputsEither.left().value());
676 private Either<List<InputDefinition>, ResponseFormat> createListInputsInGraph(Map<String, InputDefinition> inputs,
677 Map<String, DataTypeDefinition> privateDataTypes, org.openecomp.sdc.be.model.Component component) {
679 log.trace("#createListInputsInGraph: enter");
680 Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(
681 applicationDataTypeCache);
682 if (allDataTypes.isRight()) {
683 return Either.right(allDataTypes.right().value());
686 Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
687 dataTypes.putAll(privateDataTypes);
689 for (Map.Entry<String, InputDefinition> inputDefinition : inputs.entrySet()) {
690 String inputName = inputDefinition.getKey();
691 inputDefinition.getValue().setName(inputName);
693 Either<InputDefinition, ResponseFormat> preparedInputEither =
694 prepareAndValidateInputBeforeCreate(inputDefinition.getValue(), dataTypes);
695 if (preparedInputEither.isRight()) {
696 return Either.right(preparedInputEither.right().value());
700 Either<List<InputDefinition>, StorageOperationStatus> addInputsEither = toscaOperationFacade
701 .addInputsToComponent(inputs, component.getUniqueId());
702 if (addInputsEither.isRight()) {
703 log.debug("#createListInputsInGraph: Failed to create inputs under component {}. Status is {}",
704 component.getUniqueId(), addInputsEither.right().value());
705 return Either.right(componentsUtils.getResponseFormat(
706 componentsUtils.convertFromStorageResponse(addInputsEither.right().value())));
708 log.trace("#createListInputsInGraph: leave");
709 return Either.left(addInputsEither.left().value());
713 * Delete input from service
720 public Either<InputDefinition, ResponseFormat> deleteInput(String componentId, String userId, String inputId) {
722 Either<InputDefinition, ResponseFormat> deleteEither = null;
723 if (log.isDebugEnabled()) {
724 log.debug("Going to delete input id: {}", inputId);
727 validateUserExists(userId, "Delete input", true);
729 ComponentParametersView componentParametersView = getBaseComponentParametersView();
730 componentParametersView.setIgnoreInterfaces(false);
731 componentParametersView.setIgnoreDataType(false);
732 componentParametersView.setIgnoreProperties(false);
734 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentEither =
735 toscaOperationFacade.getToscaElement(componentId, componentParametersView);
736 if (componentEither.isRight()) {
737 deleteEither = Either.right(componentsUtils.getResponseFormat(
738 componentsUtils.convertFromStorageResponse(componentEither.right().value())));
741 org.openecomp.sdc.be.model.Component component = componentEither.left().value();
743 // Validate inputId is child of the component
744 Optional<InputDefinition> optionalInput = component.getInputs().stream().
746 filter(input -> input.getUniqueId().equals(inputId)).
749 if (!optionalInput.isPresent()) {
751 componentsUtils.getResponseFormat(ActionStatus.INPUT_IS_NOT_CHILD_OF_COMPONENT, inputId, componentId));
754 InputDefinition inputForDelete = optionalInput.get();
757 Either<Boolean, ResponseFormat> lockResultEither =
758 lockComponent(componentId, component, "deleteInput");
759 if (lockResultEither.isRight()) {
760 ResponseFormat responseFormat = lockResultEither.right().value();
761 deleteEither = Either.right(responseFormat);
765 // Delete input operations
767 StorageOperationStatus status =
768 toscaOperationFacade.deleteInputOfResource(component, inputForDelete.getName());
769 if (status != StorageOperationStatus.OK) {
770 log.debug("Component id: {} delete input id: {} failed", componentId, inputId);
771 deleteEither = Either.right(componentsUtils.getResponseFormat(
772 componentsUtils.convertFromStorageResponse(status), component.getName()));
776 if (BooleanUtils.isTrue(inputForDelete.getIsDeclaredListInput())){
777 deleteEither = deleteListInput(componentId, inputId, component, inputForDelete, status);
781 StorageOperationStatus storageOperationStatus =
782 propertyDeclarationOrchestrator.unDeclarePropertiesAsInputs(component, inputForDelete);
783 if (storageOperationStatus != StorageOperationStatus.OK) {
784 log.debug("Component id: {} update properties declared as input for input id: {} failed", componentId, inputId);
785 deleteEither = Either.right(componentsUtils.getResponseFormat(
786 componentsUtils.convertFromStorageResponse(status), component.getName()));
790 deleteEither = Either.left(inputForDelete);
793 if (deleteEither == null || deleteEither.isRight()) {
794 log.debug("Component id: {} delete input id: {} failed", componentId, inputId);
795 janusGraphDao.rollback();
797 log.debug("Component id: {} delete input id: {} success", componentId, inputId);
798 janusGraphDao.commit();
800 unlockComponent(deleteEither, component);
804 private Either<InputDefinition, ResponseFormat> deleteListInput(String componentId, String inputId,
805 org.openecomp.sdc.be.model.Component component,
806 InputDefinition inputForDelete, StorageOperationStatus status) {
807 // the input is created by 'Declare List'.
808 // need to 1. undeclare properties, 2. delete input, 3. delete private data type
810 StorageOperationStatus storageOperationStatus =
811 propertyDeclarationOrchestrator.unDeclarePropertiesAsListInputs(component, inputForDelete);
812 if (storageOperationStatus != StorageOperationStatus.OK) {
813 log.debug("Component id: {} update properties declared as input for input id: {} failed", componentId, inputId);
814 return Either.right(componentsUtils.getResponseFormat(
815 componentsUtils.convertFromStorageResponse(status), component.getName()));
817 Either<DataTypeDefinition, StorageOperationStatus> deleteResult =
818 dataTypeBusinessLogic.deletePrivateDataType(component, inputForDelete.getSchemaType());
819 if (deleteResult.isRight()) {
820 log.debug("Component id: {} delete datatype name: {} failed", componentId, inputForDelete.getSchemaType());
821 return Either.right(componentsUtils.getResponseFormat(
822 componentsUtils.convertFromStorageResponse(deleteResult.right().value()), component.getName()));
824 log.trace("deleteInput: deletePrivateDataType (OK)");
825 return Either.left(inputForDelete);
828 private Either<InputDefinition, ResponseFormat> prepareAndValidateInputBeforeCreate(InputDefinition newInputDefinition, Map<String, DataTypeDefinition> dataTypes) {
830 // validate input default values
831 Either<Boolean, ResponseFormat> defaultValuesValidation = validatePropertyDefaultValue(newInputDefinition, dataTypes);
832 if (defaultValuesValidation.isRight()) {
833 return Either.right(defaultValuesValidation.right().value());
836 ToscaPropertyType type = getType(newInputDefinition.getType());
837 if (type != null && newInputDefinition != null) {
838 PropertyValueConverter converter = type.getConverter();
840 SchemaDefinition schema = newInputDefinition.getSchema();
841 String innerType = null;
842 if (schema != null) {
843 PropertyDataDefinition prop = schema.getProperty();
845 innerType = prop.getType();
848 String convertedValue;
849 if (newInputDefinition.getDefaultValue() != null) {
850 convertedValue = converter.convert(newInputDefinition.getDefaultValue(), innerType, dataTypes);
851 newInputDefinition.setDefaultValue(convertedValue);
854 return Either.left(newInputDefinition);
857 public Either<InputDefinition, ResponseFormat> getInputsAndPropertiesForComponentInput(String userId, String componentId, String inputId, boolean inTransaction) {
858 Either<InputDefinition, ResponseFormat> result = null;
861 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
862 ComponentParametersView filters = new ComponentParametersView();
863 filters.disableAll();
864 filters.setIgnoreComponentInstances(false);
865 filters.setIgnoreInputs(false);
866 filters.setIgnoreComponentInstancesInputs(false);
867 filters.setIgnoreComponentInstancesProperties(false);
868 filters.setIgnoreProperties(false);
869 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
870 if(getComponentEither.isRight()){
871 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
872 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
873 return Either.right(componentsUtils.getResponseFormat(actionStatus));
876 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
877 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
879 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
880 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, componentId, actionStatus);
881 return Either.right(componentsUtils.getResponseFormat(actionStatus));
884 InputDefinition resObj = op.get();
886 List<ComponentInstanceInput> inputCIInput = componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(component, inputId) ;
888 resObj.setInputs(inputCIInput);
891 List<ComponentInstanceProperty> inputProps = componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(component, inputId) ;
893 resObj.setProperties(inputProps);
896 result = Either.left(resObj);
902 if (!inTransaction) {
904 if (result == null || result.isRight()) {
905 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
906 janusGraphDao.rollback();
908 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
909 janusGraphDao.commit();