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=========================================================
21 package org.openecomp.sdc.be.components.impl;
23 import fj.data.Either;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.List;
30 import java.util.Objects;
31 import java.util.Optional;
32 import java.util.stream.Collectors;
33 import javax.inject.Inject;
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.ComponentException;
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.titan.TitanOperationStatus;
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.operations.api.StorageOperationStatus;
61 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
62 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
63 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
64 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
65 import org.openecomp.sdc.common.log.wrappers.Logger;
66 import org.openecomp.sdc.exception.ResponseFormat;
67 import org.springframework.stereotype.Component;
69 @Component("inputsBusinessLogic")
70 public class InputsBusinessLogic extends BaseBusinessLogic {
72 private static final String CREATE_INPUT = "CreateInput";
73 private static final String UPDATE_INPUT = "UpdateInput";
75 private static final Logger log = Logger.getLogger(InputsBusinessLogic.class);
76 private static final String FAILED_TO_FOUND_COMPONENT_ERROR = "Failed to found component {}, error: {}";
77 private static final String GET_PROPERTIES_BY_INPUT = "get Properties by input";
78 private static final String FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR = "Failed to found input {} under component {}, error: {}";
79 private static final String GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP = "Going to execute rollback on create group.";
80 private static final String GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP = "Going to execute commit on create group.";
83 private PropertyDeclarationOrchestrator propertyDeclarationOrchestrator;
85 private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
87 private DataTypeBusinessLogic dataTypeBusinessLogic;
90 * associate inputs to a given component with paging
96 public Either<List<InputDefinition>, ResponseFormat> getInputs(String userId, String componentId) {
98 validateUserExists(userId, "get Inputs", false);
100 ComponentParametersView filters = new ComponentParametersView();
101 filters.disableAll();
102 filters.setIgnoreInputs(false);
104 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
105 if(getComponentEither.isRight()){
106 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
107 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
108 return Either.right(componentsUtils.getResponseFormat(actionStatus));
111 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
112 List<InputDefinition> inputs = component.getInputs();
114 return Either.left(inputs);
118 public Either<List<ComponentInstanceInput>, ResponseFormat> getComponentInstanceInputs(String userId, String componentId, String componentInstanceId) {
120 validateUserExists(userId, "get Inputs", false);
121 ComponentParametersView filters = new ComponentParametersView();
122 filters.disableAll();
123 filters.setIgnoreInputs(false);
124 filters.setIgnoreComponentInstances(false);
125 filters.setIgnoreComponentInstancesInputs(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();
136 if(!ComponentValidations.validateComponentInstanceExist(component, componentInstanceId)){
137 ActionStatus actionStatus = ActionStatus.COMPONENT_INSTANCE_NOT_FOUND;
138 log.debug("Failed to found component instance inputs {}, error: {}", componentInstanceId, actionStatus);
139 return Either.right(componentsUtils.getResponseFormat(actionStatus));
141 Map<String, List<ComponentInstanceInput>> ciInputs =
142 Optional.ofNullable(component.getComponentInstancesInputs()).orElse(Collections.emptyMap());
144 // Set Constraints on Input
145 MapUtils.emptyIfNull(ciInputs).values()
146 .forEach(inputs -> ListUtils.emptyIfNull(inputs)
147 .forEach(input -> input.setConstraints(setInputConstraint(input))));
148 return Either.left(ciInputs.getOrDefault(componentInstanceId, Collections.emptyList()));
152 * associate properties to a given component instance input
160 public Either<List<ComponentInstanceProperty>, ResponseFormat> getComponentInstancePropertiesByInputId(String userId, String componentId, String instanceId, String inputId) {
161 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
162 String parentId = componentId;
163 org.openecomp.sdc.be.model.Component component;
164 ComponentParametersView filters = new ComponentParametersView();
165 filters.disableAll();
166 filters.setIgnoreComponentInstances(false);
168 if(!instanceId.equals(inputId)){
171 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(parentId, filters);
173 if(getComponentEither.isRight()){
174 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
175 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, parentId, actionStatus);
176 return Either.right(componentsUtils.getResponseFormat(actionStatus));
179 component = getComponentEither.left().value();
180 Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci ->ci.getUniqueId().equals(instanceId)).findAny();
181 if(ciOp.isPresent()){
182 parentId = ciOp.get().getComponentUid();
187 filters.setIgnoreInputs(false);
189 filters.setIgnoreComponentInstancesProperties(false);
190 filters.setIgnoreComponentInstancesInputs(false);
191 filters.setIgnoreProperties(false);
193 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(parentId, filters);
195 if(getComponentEither.isRight()){
196 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
197 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, parentId, actionStatus);
198 return Either.right(componentsUtils.getResponseFormat(actionStatus));
201 component = getComponentEither.left().value();
203 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
205 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
206 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, parentId, actionStatus);
207 return Either.right(componentsUtils.getResponseFormat(actionStatus));
210 return Either.left(componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(component, inputId));
214 private Either<String,ResponseFormat> updateInputObjectValue(InputDefinition currentInput, InputDefinition newInput, Map<String, DataTypeDefinition> dataTypes) {
215 String innerType = null;
216 String propertyType = currentInput.getType();
217 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
218 log.debug("The type of the property {} is {}", currentInput.getUniqueId(), propertyType);
220 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
221 SchemaDefinition def = currentInput.getSchema();
223 log.debug("Schema doesn't exists for property of type {}", type);
224 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
226 PropertyDataDefinition propDef = def.getProperty();
227 if (propDef == null) {
228 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
229 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
231 innerType = propDef.getType();
233 // Specific Update Logic
235 Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, newInput.getDefaultValue(), true, innerType, dataTypes);
237 String newValue = currentInput.getDefaultValue();
238 if (isValid.isRight()) {
239 Boolean res = isValid.right().value();
240 if (Boolean.FALSE.equals(res)) {
241 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT))));
244 Object object = isValid.left().value();
245 if (object != null) {
246 newValue = object.toString();
249 return Either.left(newValue);
252 private InputDefinition getInputFromInputsListById(List<InputDefinition> componentsOldInputs, InputDefinition input) {
253 return componentsOldInputs.stream().filter(in -> in.getUniqueId().equals(input.getUniqueId())).findFirst().orElse(null);
256 public Either<List<InputDefinition>, ResponseFormat> updateInputsValue(ComponentTypeEnum componentType, String componentId, List<InputDefinition> inputs, String userId, boolean shouldLockComp, boolean inTransaction) {
258 List<InputDefinition> returnInputs = new ArrayList<>();
259 Either<List<InputDefinition>, ResponseFormat> result = null;
260 org.openecomp.sdc.be.model.Component component = null;
263 validateUserExists(userId, "get input", false);
265 ComponentParametersView componentParametersView = new ComponentParametersView();
266 componentParametersView.disableAll();
267 componentParametersView.setIgnoreInputs(false);
268 componentParametersView.setIgnoreUsers(false);
269 componentParametersView.setIgnoreProperties(false);
270 componentParametersView.setIgnoreComponentInstancesProperties(false);
271 componentParametersView.setIgnoreComponentInstances(false);
273 Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(componentId, componentType, componentParametersView);
275 if (validateComponent.isRight()) {
276 result = Either.right(validateComponent.right().value());
279 component = validateComponent.left().value();
281 if (shouldLockComp) {
282 Either<Boolean, ResponseFormat> lockComponent = lockComponent(component, UPDATE_INPUT);
283 if (lockComponent.isRight()) {
284 result = Either.right(lockComponent.right().value());
289 Either<Boolean, ResponseFormat> canWork = validateCanWorkOnComponent(component, userId);
290 if (canWork.isRight()) {
291 result = Either.right(canWork.right().value());
295 //Validate value and Constraint of input
296 Either<Boolean, ResponseFormat> constraintValidatorResponse = validateInputValueConstraint(inputs);
297 if (constraintValidatorResponse.isRight()) {
298 log.error("Failed validation value and constraint of property: {}",
299 constraintValidatorResponse.right().value());
300 return Either.right(constraintValidatorResponse.right().value());
303 Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache);
304 if (allDataTypes.isRight()) {
305 result = Either.right(allDataTypes.right().value());
309 Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
310 List<InputDefinition> componentsOldInputs = Optional.ofNullable(component.getInputs()).orElse(Collections.emptyList());
311 for (InputDefinition newInput: inputs) {
312 InputDefinition currInput = getInputFromInputsListById(componentsOldInputs, newInput);
313 if (currInput == null) {
314 ActionStatus actionStatus = ActionStatus.COMPONENT_NOT_FOUND;
315 log.debug("Failed to found newInput {} under component {}, error: {}", newInput.getUniqueId(), componentId, actionStatus);
316 result = Either.right(componentsUtils.getResponseFormat(actionStatus));
319 Either<String, ResponseFormat> updateInputObjectValue = updateInputObjectValue(currInput, newInput, dataTypes);
320 if ( updateInputObjectValue.isRight()) {
321 return Either.right(updateInputObjectValue.right().value());
323 String newValue = updateInputObjectValue.left().value();
324 currInput.setValue(newValue);
325 currInput.setDefaultValue(newValue);
326 currInput.setOwnerId(userId);
327 Either<InputDefinition, StorageOperationStatus> status = toscaOperationFacade.updateInputOfComponent(component, currInput);
328 if(status.isRight()){
329 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status.right().value());
330 result = Either.right(componentsUtils.getResponseFormat(actionStatus, ""));
333 returnInputs.add(status.left().value());
336 result = Either.left(returnInputs);
339 if (!inTransaction) {
340 if (result == null || result.isRight()) {
341 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
344 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
349 if (shouldLockComp && component != null) {
350 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
355 private Either<Boolean, ResponseFormat> validateInputValueConstraint(List<InputDefinition> inputs) {
356 PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil =
357 PropertyValueConstraintValidationUtil.getInstance();
358 List<InputDefinition> inputDefinitions = new ArrayList<>();
359 for (InputDefinition inputDefinition : inputs) {
360 InputDefinition inputDef = new InputDefinition();
361 inputDefinition.setDefaultValue(inputDefinition.getDefaultValue());
362 inputDefinition.setInputPath(inputDefinition.getSubPropertyInputPath());
363 inputDefinition.setType(inputDefinition.getType());
364 if (Objects.nonNull(inputDefinition.getParentPropertyType())) {
365 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
366 propertyDefinition.setType(inputDefinition.getParentPropertyType());
368 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
371 inputDefinitions.add(inputDef);
374 return propertyValueConstraintValidationUtil.validatePropertyConstraints(inputDefinitions, applicationDataTypeCache);
377 public Either<List<ComponentInstanceInput>, ResponseFormat> getInputsForComponentInput(String userId, String componentId, String inputId) {
378 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
379 org.openecomp.sdc.be.model.Component component = null;
380 ComponentParametersView filters = new ComponentParametersView();
381 filters.disableAll();
382 filters.setIgnoreComponentInstances(false);
383 filters.setIgnoreInputs(false);
384 filters.setIgnoreComponentInstancesInputs(false);
385 filters.setIgnoreProperties(false);
387 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
389 if(getComponentEither.isRight()){
390 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
391 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
392 return Either.right(componentsUtils.getResponseFormat(actionStatus));
395 component = getComponentEither.left().value();
397 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
399 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
400 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, componentId, actionStatus);
401 return Either.right(componentsUtils.getResponseFormat(actionStatus));
404 return Either.left(componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(component, inputId));
409 public Either<List<InputDefinition>, ResponseFormat> declareProperties(String userId, String componentId,
410 ComponentTypeEnum componentTypeEnum, ComponentInstInputsMap componentInstInputsMap) {
412 return createMultipleInputs(userId, componentId, componentTypeEnum, componentInstInputsMap, true, false);
415 public Either<List<InputDefinition>, ResponseFormat> createMultipleInputs(String userId, String componentId, ComponentTypeEnum componentType, ComponentInstInputsMap componentInstInputsMapUi, boolean shouldLockComp, boolean inTransaction) {
417 Either<List<InputDefinition>, ResponseFormat> result = null;
418 org.openecomp.sdc.be.model.Component component = null;
421 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
423 component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
425 result = propertyDeclarationOrchestrator.declarePropertiesToInputs(component, componentInstInputsMapUi)
427 .bind(inputsToCreate -> prepareInputsForCreation(userId, componentId, inputsToCreate))
429 .map(componentsUtils::getResponseFormat);
433 } catch (ComponentException e) {
434 log.error("#createMultipleInputs: Exception thrown: ", e);
435 result = Either.right(e.getResponseFormat());
439 if (!inTransaction) {
440 if (result == null || result.isRight()) {
441 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
444 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
449 if (shouldLockComp && component != null) {
450 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
457 * Creates a list input with a data type which has properties specified.
459 * @param userId User ID
460 * @param componentId Component ID
461 * @param componentType Component type
462 * @param componentListInput Properties to be declared and input to be created
463 * @param shouldLockComp true if the component should be locked
464 * @param inTransaction true if already in transaction
466 public Either<List<InputDefinition>, ResponseFormat> createListInput(String userId, String componentId,
467 ComponentTypeEnum componentType, ComponentInstListInput componentListInput, boolean shouldLockComp,
468 boolean inTransaction) {
470 Either<List<InputDefinition>, ResponseFormat> result = null;
471 org.openecomp.sdc.be.model.Component component = null;
473 log.trace("#createListInput: enter");
476 /* check if user exists */
477 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
479 component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
481 InputDefinition listInput = componentListInput.getListInput();
482 DataTypeDefinition dataType =
483 prepareDataTypeForListInput(componentListInput.getComponentInstInputsMap(), listInput);
484 Map<String, DataTypeDefinition> dataTypesMap = new HashMap<>();
485 dataTypesMap.put(dataType.getName(), dataType);
486 if (log.isDebugEnabled()) {
487 log.debug("#createListInput: dataTypesMap={}", ReflectionToStringBuilder.toString(dataTypesMap));
490 Either<List<DataTypeDefinition>, StorageOperationStatus> dataTypeResult =
491 toscaOperationFacade.addDataTypesToComponent(dataTypesMap, componentId);
492 if (dataTypeResult.isRight()) {
493 log.debug("#createListInput: DataType creation failed.");
494 throw new ComponentException(componentsUtils.getResponseFormat(dataTypeResult.right().value()));
498 listInput.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(componentId, listInput.getName()));
499 listInput.setInstanceUniqueId(
500 propertyDeclarationOrchestrator.getPropOwnerId(componentListInput.getComponentInstInputsMap()));
501 listInput.setIsDeclaredListInput(true);
502 Map<String, InputDefinition> listInputMap = new HashMap<>();
503 listInputMap.put(listInput.getName(), listInput);
504 result = createListInputsInGraph(listInputMap, dataTypesMap, component);
505 if (result.isRight()) {
506 log.debug("#createListInput: createListInputsInGraph failed.");
507 throw new ComponentException(result.right().value());
511 result = propertyDeclarationOrchestrator
512 .declarePropertiesToListInput(component, componentListInput.getComponentInstInputsMap(), listInput)
513 .right().map(err -> componentsUtils.getResponseFormat(err))
514 .left().map(Arrays::asList);
516 log.trace("#createListInput: leave");
520 } catch (ComponentException e) {
521 log.error("#createListInput: Exception thrown", e);
522 result = Either.right(e.getResponseFormat());
526 if (!inTransaction) {
527 if (result == null || result.isRight()) {
528 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
531 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
536 if (shouldLockComp && component != null) {
537 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
542 private ComponentParametersView getBaseComponentParametersView() {
543 ComponentParametersView componentParametersView = new ComponentParametersView();
544 componentParametersView.disableAll();
545 componentParametersView.setIgnoreInputs(false);
546 componentParametersView.setIgnoreComponentInstances(false);
547 componentParametersView.setIgnoreComponentInstancesInputs(false);
548 componentParametersView.setIgnoreComponentInstancesProperties(false);
549 componentParametersView.setIgnorePolicies(false);
550 componentParametersView.setIgnoreGroups(false);
551 componentParametersView.setIgnoreUsers(false);
552 return componentParametersView;
555 private org.openecomp.sdc.be.model.Component getAndValidateComponentForCreate(
556 String userId, String componentId, ComponentTypeEnum componentType, boolean shouldLockComp
559 ComponentParametersView componentParametersView = getBaseComponentParametersView();
561 Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither =
562 // get Component Object
563 validateComponentExists(componentId, componentType, componentParametersView)
564 .left().bind(component -> {
565 if (shouldLockComp) {
566 // lock the component
567 return lockComponent(component, CREATE_INPUT).left().map(result -> component);
569 return Either.left(component);
570 }).left().bind(component -> validateCanWorkOnComponent(component, userId).left().map(result -> component));
571 if (componentEither.isRight()) {
572 throw new ComponentException(componentEither.right().value());
574 return componentEither.left().value();
577 private DataTypeDefinition prepareDataTypeForListInput(ComponentInstInputsMap inputsMap, InputDefinition input) {
578 // Confirm if type is list
579 if (StringUtils.isEmpty(input.getType()) || !input.getType().equals(ToscaPropertyType.LIST.getType())) {
580 log.debug("#prepareDataTypeForListInput: Type of input is not list.");
581 throw new ComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE));
584 // Confirm schema type is not empty
585 String desiredTypeName = input.getSchemaType();
586 if (StringUtils.isEmpty(desiredTypeName)) {
587 log.debug("#prepareDataTypeForListInput: Schema type of list input is empty.");
588 throw new ComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE));
591 DataTypeDefinition dataType = new DataTypeDefinition();
592 List<ComponentInstancePropInput> propInputs = inputsMap.resolvePropertiesToDeclare().getRight();
593 dataType.setName(desiredTypeName);
594 dataType.setDerivedFromName(ToscaPropertyType.Root.getType());
595 // Copy properties from inputsMap
596 dataType.setProperties(propInputs.stream().map(PropertyDefinition::new).collect(Collectors.toList()));
600 private Either<List<InputDefinition>, StorageOperationStatus> prepareInputsForCreation(String userId, String cmptId, List<InputDefinition> inputsToCreate) {
601 Map<String, InputDefinition> inputsToPersist = MapUtil.toMap(inputsToCreate, InputDefinition::getName);
602 assignOwnerIdToInputs(userId, inputsToPersist);
603 inputsToPersist.values()
604 .forEach(input -> input.setConstraints(componentInstanceBusinessLogic.setInputConstraint(input)));
606 return toscaOperationFacade.addInputsToComponent(inputsToPersist, cmptId)
608 .map(persistedInputs -> inputsToCreate);
611 private void assignOwnerIdToInputs(String userId, Map<String, InputDefinition> inputsToCreate) {
612 inputsToCreate.values().forEach(inputDefinition -> inputDefinition.setOwnerId(userId));
615 public Either<List<InputDefinition>, ResponseFormat> createInputsInGraph(Map<String, InputDefinition> inputs, org.openecomp.sdc.be.model.Component component) {
617 List<InputDefinition> resourceProperties = component.getInputs();
618 Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache);
619 if (allDataTypes.isRight()) {
620 return Either.right(allDataTypes.right().value());
623 Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
625 for (Map.Entry<String, InputDefinition> inputDefinition : inputs.entrySet()) {
626 String inputName = inputDefinition.getKey();
627 inputDefinition.getValue().setName(inputName);
629 Either<InputDefinition, ResponseFormat> preparedInputEither = prepareAndValidateInputBeforeCreate(inputDefinition.getValue(), dataTypes);
630 if(preparedInputEither.isRight()){
631 return Either.right(preparedInputEither.right().value());
635 if (resourceProperties != null) {
636 Map<String, InputDefinition> generatedInputs = resourceProperties.stream().collect(Collectors.toMap(PropertyDataDefinition::getName, i -> i));
637 Either<Map<String, InputDefinition>, String> mergeEither = ToscaDataDefinition.mergeDataMaps(generatedInputs, inputs);
638 if(mergeEither.isRight()){
639 return Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_ALREADY_EXIST, mergeEither.right().value()));
641 inputs = mergeEither.left().value();
644 Either<List<InputDefinition>, StorageOperationStatus> associateInputsEither = toscaOperationFacade.createAndAssociateInputs(inputs, component.getUniqueId());
645 if(associateInputsEither.isRight()){
646 log.debug("Failed to create inputs under component {}. Status is {}", component.getUniqueId(), associateInputsEither.right().value());
647 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(associateInputsEither.right().value())));
649 return Either.left(associateInputsEither.left().value());
652 private Either<List<InputDefinition>, ResponseFormat> createListInputsInGraph(Map<String, InputDefinition> inputs,
653 Map<String, DataTypeDefinition> privateDataTypes, org.openecomp.sdc.be.model.Component component) {
655 log.trace("#createListInputsInGraph: enter");
656 Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(
657 applicationDataTypeCache);
658 if (allDataTypes.isRight()) {
659 return Either.right(allDataTypes.right().value());
662 Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
663 dataTypes.putAll(privateDataTypes);
665 for (Map.Entry<String, InputDefinition> inputDefinition : inputs.entrySet()) {
666 String inputName = inputDefinition.getKey();
667 inputDefinition.getValue().setName(inputName);
669 Either<InputDefinition, ResponseFormat> preparedInputEither =
670 prepareAndValidateInputBeforeCreate(inputDefinition.getValue(), dataTypes);
671 if (preparedInputEither.isRight()) {
672 return Either.right(preparedInputEither.right().value());
676 Either<List<InputDefinition>, StorageOperationStatus> addInputsEither = toscaOperationFacade
677 .addInputsToComponent(inputs, component.getUniqueId());
678 if (addInputsEither.isRight()) {
679 log.debug("#createListInputsInGraph: Failed to create inputs under component {}. Status is {}",
680 component.getUniqueId(), addInputsEither.right().value());
681 return Either.right(componentsUtils.getResponseFormat(
682 componentsUtils.convertFromStorageResponse(addInputsEither.right().value())));
684 log.trace("#createListInputsInGraph: leave");
685 return Either.left(addInputsEither.left().value());
689 * Delete input from service
696 public Either<InputDefinition, ResponseFormat> deleteInput(String componentId, String userId, String inputId) {
698 Either<InputDefinition, ResponseFormat> deleteEither = null;
699 if (log.isDebugEnabled()) {
700 log.debug("Going to delete input id: {}", inputId);
703 validateUserExists(userId, "Delete input", true);
705 ComponentParametersView componentParametersView = getBaseComponentParametersView();
706 componentParametersView.setIgnoreInterfaces(false);
707 componentParametersView.setIgnoreDataType(false);
708 componentParametersView.setIgnoreProperties(false);
710 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentEither =
711 toscaOperationFacade.getToscaElement(componentId, componentParametersView);
712 if (componentEither.isRight()) {
713 deleteEither = Either.right(componentsUtils.getResponseFormat(
714 componentsUtils.convertFromStorageResponse(componentEither.right().value())));
717 org.openecomp.sdc.be.model.Component component = componentEither.left().value();
719 // Validate inputId is child of the component
720 Optional<InputDefinition> optionalInput = component.getInputs().stream().
722 filter(input -> input.getUniqueId().equals(inputId)).
725 if (!optionalInput.isPresent()) {
727 componentsUtils.getResponseFormat(ActionStatus.INPUT_IS_NOT_CHILD_OF_COMPONENT, inputId, componentId));
730 InputDefinition inputForDelete = optionalInput.get();
733 Either<Boolean, ResponseFormat> lockResultEither =
734 lockComponent(componentId, component, "deleteInput");
735 if (lockResultEither.isRight()) {
736 ResponseFormat responseFormat = lockResultEither.right().value();
737 deleteEither = Either.right(responseFormat);
741 // Delete input operations
743 StorageOperationStatus status =
744 toscaOperationFacade.deleteInputOfResource(component, inputForDelete.getName());
745 if (status != StorageOperationStatus.OK) {
746 log.debug("Component id: {} delete input id: {} failed", componentId, inputId);
747 deleteEither = Either.right(componentsUtils.getResponseFormat(
748 componentsUtils.convertFromStorageResponse(status), component.getName()));
752 if (BooleanUtils.isTrue(inputForDelete.getIsDeclaredListInput())){
753 deleteEither = deleteListInput(componentId, inputId, component, inputForDelete, status);
757 StorageOperationStatus storageOperationStatus =
758 propertyDeclarationOrchestrator.unDeclarePropertiesAsInputs(component, inputForDelete);
759 if (storageOperationStatus != StorageOperationStatus.OK) {
760 log.debug("Component id: {} update properties declared as input for input id: {} failed", componentId, inputId);
761 deleteEither = Either.right(componentsUtils.getResponseFormat(
762 componentsUtils.convertFromStorageResponse(status), component.getName()));
766 deleteEither = Either.left(inputForDelete);
769 if (deleteEither == null || deleteEither.isRight()) {
770 log.debug("Component id: {} delete input id: {} failed", componentId, inputId);
773 log.debug("Component id: {} delete input id: {} success", componentId, inputId);
776 unlockComponent(deleteEither, component);
780 private Either<InputDefinition, ResponseFormat> deleteListInput(String componentId, String inputId,
781 org.openecomp.sdc.be.model.Component component,
782 InputDefinition inputForDelete, StorageOperationStatus status) {
783 // the input is created by 'Declare List'.
784 // need to 1. undeclare properties, 2. delete input, 3. delete private data type
786 StorageOperationStatus storageOperationStatus =
787 propertyDeclarationOrchestrator.unDeclarePropertiesAsListInputs(component, inputForDelete);
788 if (storageOperationStatus != StorageOperationStatus.OK) {
789 log.debug("Component id: {} update properties declared as input for input id: {} failed", componentId, inputId);
790 return Either.right(componentsUtils.getResponseFormat(
791 componentsUtils.convertFromStorageResponse(status), component.getName()));
793 Either<DataTypeDefinition, StorageOperationStatus> deleteResult =
794 dataTypeBusinessLogic.deletePrivateDataType(component, inputForDelete.getSchemaType());
795 if (deleteResult.isRight()) {
796 log.debug("Component id: {} delete datatype name: {} failed", componentId, inputForDelete.getSchemaType());
797 return Either.right(componentsUtils.getResponseFormat(
798 componentsUtils.convertFromStorageResponse(deleteResult.right().value()), component.getName()));
800 log.trace("deleteInput: deletePrivateDataType (OK)");
801 return Either.left(inputForDelete);
804 private Either<InputDefinition, ResponseFormat> prepareAndValidateInputBeforeCreate(InputDefinition newInputDefinition, Map<String, DataTypeDefinition> dataTypes) {
806 // validate input default values
807 Either<Boolean, ResponseFormat> defaultValuesValidation = validatePropertyDefaultValue(newInputDefinition, dataTypes);
808 if (defaultValuesValidation.isRight()) {
809 return Either.right(defaultValuesValidation.right().value());
812 ToscaPropertyType type = getType(newInputDefinition.getType());
813 if (type != null && newInputDefinition != null) {
814 PropertyValueConverter converter = type.getConverter();
816 SchemaDefinition schema = newInputDefinition.getSchema();
817 String innerType = null;
818 if (schema != null) {
819 PropertyDataDefinition prop = schema.getProperty();
821 innerType = prop.getType();
824 String convertedValue;
825 if (newInputDefinition.getDefaultValue() != null) {
826 convertedValue = converter.convert(newInputDefinition.getDefaultValue(), innerType, dataTypes);
827 newInputDefinition.setDefaultValue(convertedValue);
830 return Either.left(newInputDefinition);
833 public Either<InputDefinition, ResponseFormat> getInputsAndPropertiesForComponentInput(String userId, String componentId, String inputId, boolean inTransaction) {
834 Either<InputDefinition, ResponseFormat> result = null;
837 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
838 ComponentParametersView filters = new ComponentParametersView();
839 filters.disableAll();
840 filters.setIgnoreComponentInstances(false);
841 filters.setIgnoreInputs(false);
842 filters.setIgnoreComponentInstancesInputs(false);
843 filters.setIgnoreComponentInstancesProperties(false);
844 filters.setIgnoreProperties(false);
845 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
846 if(getComponentEither.isRight()){
847 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
848 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
849 return Either.right(componentsUtils.getResponseFormat(actionStatus));
852 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
853 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
855 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
856 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, componentId, actionStatus);
857 return Either.right(componentsUtils.getResponseFormat(actionStatus));
860 InputDefinition resObj = op.get();
862 List<ComponentInstanceInput> inputCIInput = componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(component, inputId) ;
864 resObj.setInputs(inputCIInput);
867 List<ComponentInstanceProperty> inputProps = componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(component, inputId) ;
869 resObj.setProperties(inputProps);
872 result = Either.left(resObj);
878 if (!inTransaction) {
880 if (result == null || result.isRight()) {
881 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
884 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);