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.operations.api.StorageOperationStatus;
64 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
65 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
66 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
67 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
68 import org.openecomp.sdc.common.log.wrappers.Logger;
69 import org.openecomp.sdc.exception.ResponseFormat;
70 import org.springframework.stereotype.Component;
72 @Component("inputsBusinessLogic")
73 public class InputsBusinessLogic extends BaseBusinessLogic {
75 private static final String CREATE_INPUT = "CreateInput";
76 private static final String UPDATE_INPUT = "UpdateInput";
78 private static final Logger log = Logger.getLogger(InputsBusinessLogic.class);
79 private static final String FAILED_TO_FOUND_COMPONENT_ERROR = "Failed to found component {}, error: {}";
80 private static final String GET_PROPERTIES_BY_INPUT = "get Properties by input";
81 private static final String FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR = "Failed to found input {} under component {}, error: {}";
82 private static final String GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP = "Going to execute rollback on create group.";
83 private static final String GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP = "Going to execute commit on create group.";
86 private PropertyDeclarationOrchestrator propertyDeclarationOrchestrator;
88 private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
90 private DataTypeBusinessLogic dataTypeBusinessLogic;
93 * associate inputs to a given component with paging
99 public Either<List<InputDefinition>, ResponseFormat> getInputs(String userId, String componentId) {
101 validateUserExists(userId, "get Inputs", false);
103 ComponentParametersView filters = new ComponentParametersView();
104 filters.disableAll();
105 filters.setIgnoreInputs(false);
107 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
108 if(getComponentEither.isRight()){
109 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
110 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
111 return Either.right(componentsUtils.getResponseFormat(actionStatus));
114 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
115 List<InputDefinition> inputs = component.getInputs();
117 return Either.left(inputs);
121 public Either<List<ComponentInstanceInput>, ResponseFormat> getComponentInstanceInputs(String userId, String componentId, String componentInstanceId) {
123 validateUserExists(userId, "get Inputs", false);
124 ComponentParametersView filters = new ComponentParametersView();
125 filters.disableAll();
126 filters.setIgnoreInputs(false);
127 filters.setIgnoreComponentInstances(false);
128 filters.setIgnoreComponentInstancesInputs(false);
130 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
131 if(getComponentEither.isRight()){
132 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
133 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
134 return Either.right(componentsUtils.getResponseFormat(actionStatus));
137 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
139 if(!ComponentValidations.validateComponentInstanceExist(component, componentInstanceId)){
140 ActionStatus actionStatus = ActionStatus.COMPONENT_INSTANCE_NOT_FOUND;
141 log.debug("Failed to found component instance inputs {}, error: {}", componentInstanceId, actionStatus);
142 return Either.right(componentsUtils.getResponseFormat(actionStatus));
144 Map<String, List<ComponentInstanceInput>> ciInputs =
145 Optional.ofNullable(component.getComponentInstancesInputs()).orElse(Collections.emptyMap());
147 // Set Constraints on Input
148 MapUtils.emptyIfNull(ciInputs).values()
149 .forEach(inputs -> ListUtils.emptyIfNull(inputs)
150 .forEach(input -> input.setConstraints(setInputConstraint(input))));
151 return Either.left(ciInputs.getOrDefault(componentInstanceId, Collections.emptyList()));
155 * associate properties to a given component instance input
163 public Either<List<ComponentInstanceProperty>, ResponseFormat> getComponentInstancePropertiesByInputId(String userId, String componentId, String instanceId, String inputId) {
164 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
165 String parentId = componentId;
166 org.openecomp.sdc.be.model.Component component;
167 ComponentParametersView filters = new ComponentParametersView();
168 filters.disableAll();
169 filters.setIgnoreComponentInstances(false);
171 if(!instanceId.equals(inputId)){
174 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(parentId, filters);
176 if(getComponentEither.isRight()){
177 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
178 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, parentId, actionStatus);
179 return Either.right(componentsUtils.getResponseFormat(actionStatus));
182 component = getComponentEither.left().value();
183 Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci ->ci.getUniqueId().equals(instanceId)).findAny();
184 if(ciOp.isPresent()){
185 parentId = ciOp.get().getComponentUid();
190 filters.setIgnoreInputs(false);
192 filters.setIgnoreComponentInstancesProperties(false);
193 filters.setIgnoreComponentInstancesInputs(false);
194 filters.setIgnoreProperties(false);
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();
206 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
208 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
209 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, parentId, actionStatus);
210 return Either.right(componentsUtils.getResponseFormat(actionStatus));
213 return Either.left(componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(component, inputId));
217 private Either<String,ResponseFormat> updateInputObjectValue(InputDefinition currentInput, InputDefinition newInput, Map<String, DataTypeDefinition> dataTypes) {
218 String innerType = null;
219 String propertyType = currentInput.getType();
220 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
221 log.debug("The type of the property {} is {}", currentInput.getUniqueId(), propertyType);
223 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
224 SchemaDefinition def = currentInput.getSchema();
226 log.debug("Schema doesn't exists for property of type {}", type);
227 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
229 PropertyDataDefinition propDef = def.getProperty();
230 if (propDef == null) {
231 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
232 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
234 innerType = propDef.getType();
236 // Specific Update Logic
238 Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, newInput.getDefaultValue(), true, innerType, dataTypes);
240 String newValue = currentInput.getDefaultValue();
241 if (isValid.isRight()) {
242 Boolean res = isValid.right().value();
243 if (Boolean.FALSE.equals(res)) {
244 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
245 JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
248 Object object = isValid.left().value();
249 if (object != null) {
250 newValue = object.toString();
253 return Either.left(newValue);
256 private InputDefinition getInputFromInputsListById(List<InputDefinition> componentsOldInputs, InputDefinition input) {
257 return componentsOldInputs.stream().filter(in -> in.getUniqueId().equals(input.getUniqueId())).findFirst().orElse(null);
260 public Either<List<InputDefinition>, ResponseFormat> updateInputsValue(ComponentTypeEnum componentType, String componentId, List<InputDefinition> inputs, String userId, boolean shouldLockComp, boolean inTransaction) {
262 List<InputDefinition> returnInputs = new ArrayList<>();
263 Either<List<InputDefinition>, ResponseFormat> result = null;
264 org.openecomp.sdc.be.model.Component component = null;
267 validateUserExists(userId, "get input", false);
269 ComponentParametersView componentParametersView = new ComponentParametersView();
270 componentParametersView.disableAll();
271 componentParametersView.setIgnoreInputs(false);
272 componentParametersView.setIgnoreUsers(false);
273 componentParametersView.setIgnoreProperties(false);
274 componentParametersView.setIgnoreComponentInstancesProperties(false);
275 componentParametersView.setIgnoreComponentInstances(false);
277 Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(componentId, componentType, componentParametersView);
279 if (validateComponent.isRight()) {
280 result = Either.right(validateComponent.right().value());
283 component = validateComponent.left().value();
285 if (shouldLockComp) {
286 Either<Boolean, ResponseFormat> lockComponent = lockComponent(component, UPDATE_INPUT);
287 if (lockComponent.isRight()) {
288 result = Either.right(lockComponent.right().value());
293 Either<Boolean, ResponseFormat> canWork = validateCanWorkOnComponent(component, userId);
294 if (canWork.isRight()) {
295 result = Either.right(canWork.right().value());
299 //Validate value and Constraint of input
300 Either<Boolean, ResponseFormat> constraintValidatorResponse = validateInputValueConstraint(inputs);
301 if (constraintValidatorResponse.isRight()) {
302 log.error("Failed validation value and constraint of property: {}",
303 constraintValidatorResponse.right().value());
304 return Either.right(constraintValidatorResponse.right().value());
307 Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache);
308 if (allDataTypes.isRight()) {
309 result = Either.right(allDataTypes.right().value());
313 Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
314 List<InputDefinition> componentsOldInputs = Optional.ofNullable(component.getInputs()).orElse(Collections.emptyList());
315 for (InputDefinition newInput: inputs) {
316 InputDefinition currInput = getInputFromInputsListById(componentsOldInputs, newInput);
317 if (currInput == null) {
318 ActionStatus actionStatus = ActionStatus.COMPONENT_NOT_FOUND;
319 log.debug("Failed to found newInput {} under component {}, error: {}", newInput.getUniqueId(), componentId, actionStatus);
320 result = Either.right(componentsUtils.getResponseFormat(actionStatus));
323 Either<String, ResponseFormat> updateInputObjectValue = updateInputObjectValue(currInput, newInput, dataTypes);
324 if ( updateInputObjectValue.isRight()) {
325 return Either.right(updateInputObjectValue.right().value());
327 String newValue = updateInputObjectValue.left().value();
328 currInput.setValue(newValue);
329 currInput.setDefaultValue(newValue);
330 currInput.setOwnerId(userId);
331 Either<InputDefinition, StorageOperationStatus> status = toscaOperationFacade.updateInputOfComponent(component, currInput);
332 if(status.isRight()){
333 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status.right().value());
334 result = Either.right(componentsUtils.getResponseFormat(actionStatus, ""));
337 returnInputs.add(status.left().value());
340 result = Either.left(returnInputs);
343 if (!inTransaction) {
344 if (result == null || result.isRight()) {
345 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
346 janusGraphDao.rollback();
348 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
349 janusGraphDao.commit();
353 if (shouldLockComp && component != null) {
354 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
359 private Either<Boolean, ResponseFormat> validateInputValueConstraint(List<InputDefinition> inputs) {
360 PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil =
361 PropertyValueConstraintValidationUtil.getInstance();
362 List<InputDefinition> inputDefinitions = new ArrayList<>();
363 for (InputDefinition inputDefinition : inputs) {
364 InputDefinition inputDef = new InputDefinition();
365 inputDefinition.setDefaultValue(inputDefinition.getDefaultValue());
366 inputDefinition.setInputPath(inputDefinition.getSubPropertyInputPath());
367 inputDefinition.setType(inputDefinition.getType());
368 if (Objects.nonNull(inputDefinition.getParentPropertyType())) {
369 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
370 propertyDefinition.setType(inputDefinition.getParentPropertyType());
372 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
375 inputDefinitions.add(inputDef);
378 return propertyValueConstraintValidationUtil.validatePropertyConstraints(inputDefinitions, applicationDataTypeCache);
381 public Either<List<ComponentInstanceInput>, ResponseFormat> getInputsForComponentInput(String userId, String componentId, String inputId) {
382 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
383 org.openecomp.sdc.be.model.Component component = null;
384 ComponentParametersView filters = new ComponentParametersView();
385 filters.disableAll();
386 filters.setIgnoreComponentInstances(false);
387 filters.setIgnoreInputs(false);
388 filters.setIgnoreComponentInstancesInputs(false);
389 filters.setIgnoreProperties(false);
391 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
393 if(getComponentEither.isRight()){
394 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
395 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
396 return Either.right(componentsUtils.getResponseFormat(actionStatus));
399 component = getComponentEither.left().value();
401 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
403 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
404 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, componentId, actionStatus);
405 return Either.right(componentsUtils.getResponseFormat(actionStatus));
408 return Either.left(componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(component, inputId));
413 public Either<List<InputDefinition>, ResponseFormat> declareProperties(String userId, String componentId,
414 ComponentTypeEnum componentTypeEnum, ComponentInstInputsMap componentInstInputsMap) {
416 return createMultipleInputs(userId, componentId, componentTypeEnum, componentInstInputsMap, true, false);
419 public Either<List<InputDefinition>, ResponseFormat> createMultipleInputs(String userId, String componentId, ComponentTypeEnum componentType, ComponentInstInputsMap componentInstInputsMapUi, boolean shouldLockComp, boolean inTransaction) {
421 Either<List<InputDefinition>, ResponseFormat> result = null;
422 org.openecomp.sdc.be.model.Component component = null;
425 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
427 component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
429 result = propertyDeclarationOrchestrator.declarePropertiesToInputs(component, componentInstInputsMapUi)
431 .bind(inputsToCreate -> prepareInputsForCreation(userId, componentId, inputsToCreate))
433 .map(componentsUtils::getResponseFormat);
437 } catch (ByResponseFormatComponentException e) {
438 log.error("#createMultipleInputs: Exception thrown: ", e);
439 result = Either.right(e.getResponseFormat());
443 if (!inTransaction) {
444 if (result == null || result.isRight()) {
445 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
446 janusGraphDao.rollback();
448 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
449 janusGraphDao.commit();
453 if (shouldLockComp && component != null) {
454 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
461 * Creates a list input with a data type which has properties specified.
463 * @param userId User ID
464 * @param componentId Component ID
465 * @param componentType Component type
466 * @param componentListInput Properties to be declared and input to be created
467 * @param shouldLockComp true if the component should be locked
468 * @param inTransaction true if already in transaction
470 public Either<List<InputDefinition>, ResponseFormat> createListInput(String userId, String componentId,
471 ComponentTypeEnum componentType, ComponentInstListInput componentListInput, boolean shouldLockComp,
472 boolean inTransaction) {
474 Either<List<InputDefinition>, ResponseFormat> result = null;
475 org.openecomp.sdc.be.model.Component component = null;
477 log.trace("#createListInput: enter");
480 /* check if user exists */
481 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
483 component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
485 InputDefinition listInput = componentListInput.getListInput();
486 DataTypeDefinition dataType =
487 prepareDataTypeForListInput(componentListInput.getComponentInstInputsMap(), listInput);
488 Map<String, DataTypeDefinition> dataTypesMap = new HashMap<>();
489 dataTypesMap.put(dataType.getName(), dataType);
490 if (log.isDebugEnabled()) {
491 log.debug("#createListInput: dataTypesMap={}", ReflectionToStringBuilder.toString(dataTypesMap));
494 Either<List<DataTypeDefinition>, StorageOperationStatus> dataTypeResult =
495 toscaOperationFacade.addDataTypesToComponent(dataTypesMap, componentId);
496 if (dataTypeResult.isRight()) {
497 log.debug("#createListInput: DataType creation failed.");
498 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(dataTypeResult.right().value()));
502 listInput.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(componentId, listInput.getName()));
503 listInput.setInstanceUniqueId(
504 propertyDeclarationOrchestrator.getPropOwnerId(componentListInput.getComponentInstInputsMap()));
505 listInput.setIsDeclaredListInput(true);
506 Map<String, InputDefinition> listInputMap = new HashMap<>();
507 listInputMap.put(listInput.getName(), listInput);
508 result = createListInputsInGraph(listInputMap, dataTypesMap, component);
509 if (result.isRight()) {
510 log.debug("#createListInput: createListInputsInGraph failed.");
511 throw new ByResponseFormatComponentException(result.right().value());
515 result = propertyDeclarationOrchestrator
516 .declarePropertiesToListInput(component, componentListInput.getComponentInstInputsMap(), listInput)
517 .right().map(err -> componentsUtils.getResponseFormat(err))
518 .left().map(Arrays::asList);
520 log.trace("#createListInput: leave");
524 } catch (ByResponseFormatComponentException e) {
525 log.error("#createListInput: Exception thrown", e);
526 result = Either.right(e.getResponseFormat());
530 if (!inTransaction) {
531 if (result == null || result.isRight()) {
532 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
533 janusGraphDao.rollback();
535 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
536 janusGraphDao.commit();
540 if (shouldLockComp && component != null) {
541 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
546 private ComponentParametersView getBaseComponentParametersView() {
547 ComponentParametersView componentParametersView = new ComponentParametersView();
548 componentParametersView.disableAll();
549 componentParametersView.setIgnoreInputs(false);
550 componentParametersView.setIgnoreComponentInstances(false);
551 componentParametersView.setIgnoreComponentInstancesInputs(false);
552 componentParametersView.setIgnoreComponentInstancesProperties(false);
553 componentParametersView.setIgnorePolicies(false);
554 componentParametersView.setIgnoreGroups(false);
555 componentParametersView.setIgnoreUsers(false);
556 return componentParametersView;
559 private org.openecomp.sdc.be.model.Component getAndValidateComponentForCreate(
560 String userId, String componentId, ComponentTypeEnum componentType, boolean shouldLockComp
563 ComponentParametersView componentParametersView = getBaseComponentParametersView();
565 Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither =
566 // get Component Object
567 validateComponentExists(componentId, componentType, componentParametersView)
568 .left().bind(component -> {
569 if (shouldLockComp) {
570 // lock the component
571 return lockComponent(component, CREATE_INPUT).left().map(result -> component);
573 return Either.left(component);
574 }).left().bind(component -> validateCanWorkOnComponent(component, userId).left().map(result -> component));
575 if (componentEither.isRight()) {
576 throw new ByResponseFormatComponentException(componentEither.right().value());
578 return componentEither.left().value();
581 private DataTypeDefinition prepareDataTypeForListInput(ComponentInstInputsMap inputsMap, InputDefinition input) {
582 // Confirm if type is list
583 if (StringUtils.isEmpty(input.getType()) || !input.getType().equals(ToscaPropertyType.LIST.getType())) {
584 log.debug("#prepareDataTypeForListInput: Type of input is not list.");
585 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE));
588 // Confirm schema type is not empty
589 String desiredTypeName = input.getSchemaType();
590 if (StringUtils.isEmpty(desiredTypeName)) {
591 log.debug("#prepareDataTypeForListInput: Schema type of list input is empty.");
592 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE));
595 DataTypeDefinition dataType = new DataTypeDefinition();
596 List<ComponentInstancePropInput> propInputs = inputsMap.resolvePropertiesToDeclare().getRight();
597 dataType.setName(desiredTypeName);
598 dataType.setDerivedFromName(ToscaPropertyType.Root.getType());
599 // Copy properties from inputsMap
600 dataType.setProperties(propInputs.stream().map(PropertyDefinition::new).collect(Collectors.toList()));
604 private Either<List<InputDefinition>, StorageOperationStatus> prepareInputsForCreation(String userId, String cmptId, List<InputDefinition> inputsToCreate) {
605 Map<String, InputDefinition> inputsToPersist = MapUtil.toMap(inputsToCreate, InputDefinition::getName);
606 assignOwnerIdToInputs(userId, inputsToPersist);
607 inputsToPersist.values()
608 .forEach(input -> input.setConstraints(componentInstanceBusinessLogic.setInputConstraint(input)));
610 return toscaOperationFacade.addInputsToComponent(inputsToPersist, cmptId)
612 .map(persistedInputs -> inputsToCreate);
615 private void assignOwnerIdToInputs(String userId, Map<String, InputDefinition> inputsToCreate) {
616 inputsToCreate.values().forEach(inputDefinition -> inputDefinition.setOwnerId(userId));
619 public Either<List<InputDefinition>, ResponseFormat> createInputsInGraph(Map<String, InputDefinition> inputs, org.openecomp.sdc.be.model.Component component) {
621 List<InputDefinition> resourceProperties = component.getInputs();
622 Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache);
623 if (allDataTypes.isRight()) {
624 return Either.right(allDataTypes.right().value());
627 Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
629 for (Map.Entry<String, InputDefinition> inputDefinition : inputs.entrySet()) {
630 String inputName = inputDefinition.getKey();
631 inputDefinition.getValue().setName(inputName);
633 Either<InputDefinition, ResponseFormat> preparedInputEither = prepareAndValidateInputBeforeCreate(inputDefinition.getValue(), dataTypes);
634 if(preparedInputEither.isRight()){
635 return Either.right(preparedInputEither.right().value());
639 if (resourceProperties != null) {
640 Map<String, InputDefinition> generatedInputs = resourceProperties.stream().collect(Collectors.toMap(PropertyDataDefinition::getName, i -> i));
641 Either<Map<String, InputDefinition>, String> mergeEither = ToscaDataDefinition.mergeDataMaps(generatedInputs, inputs);
642 if(mergeEither.isRight()){
643 return Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_ALREADY_EXIST, mergeEither.right().value()));
645 inputs = mergeEither.left().value();
648 Either<List<InputDefinition>, StorageOperationStatus> associateInputsEither = toscaOperationFacade.createAndAssociateInputs(inputs, component.getUniqueId());
649 if(associateInputsEither.isRight()){
650 log.debug("Failed to create inputs under component {}. Status is {}", component.getUniqueId(), associateInputsEither.right().value());
651 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(associateInputsEither.right().value())));
653 return Either.left(associateInputsEither.left().value());
656 private Either<List<InputDefinition>, ResponseFormat> createListInputsInGraph(Map<String, InputDefinition> inputs,
657 Map<String, DataTypeDefinition> privateDataTypes, org.openecomp.sdc.be.model.Component component) {
659 log.trace("#createListInputsInGraph: enter");
660 Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(
661 applicationDataTypeCache);
662 if (allDataTypes.isRight()) {
663 return Either.right(allDataTypes.right().value());
666 Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
667 dataTypes.putAll(privateDataTypes);
669 for (Map.Entry<String, InputDefinition> inputDefinition : inputs.entrySet()) {
670 String inputName = inputDefinition.getKey();
671 inputDefinition.getValue().setName(inputName);
673 Either<InputDefinition, ResponseFormat> preparedInputEither =
674 prepareAndValidateInputBeforeCreate(inputDefinition.getValue(), dataTypes);
675 if (preparedInputEither.isRight()) {
676 return Either.right(preparedInputEither.right().value());
680 Either<List<InputDefinition>, StorageOperationStatus> addInputsEither = toscaOperationFacade
681 .addInputsToComponent(inputs, component.getUniqueId());
682 if (addInputsEither.isRight()) {
683 log.debug("#createListInputsInGraph: Failed to create inputs under component {}. Status is {}",
684 component.getUniqueId(), addInputsEither.right().value());
685 return Either.right(componentsUtils.getResponseFormat(
686 componentsUtils.convertFromStorageResponse(addInputsEither.right().value())));
688 log.trace("#createListInputsInGraph: leave");
689 return Either.left(addInputsEither.left().value());
693 * Delete input from service
700 public Either<InputDefinition, ResponseFormat> deleteInput(String componentId, String userId, String inputId) {
702 Either<InputDefinition, ResponseFormat> deleteEither = null;
703 if (log.isDebugEnabled()) {
704 log.debug("Going to delete input id: {}", inputId);
707 validateUserExists(userId, "Delete input", true);
709 ComponentParametersView componentParametersView = getBaseComponentParametersView();
710 componentParametersView.setIgnoreInterfaces(false);
711 componentParametersView.setIgnoreDataType(false);
712 componentParametersView.setIgnoreProperties(false);
714 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentEither =
715 toscaOperationFacade.getToscaElement(componentId, componentParametersView);
716 if (componentEither.isRight()) {
717 deleteEither = Either.right(componentsUtils.getResponseFormat(
718 componentsUtils.convertFromStorageResponse(componentEither.right().value())));
721 org.openecomp.sdc.be.model.Component component = componentEither.left().value();
723 // Validate inputId is child of the component
724 Optional<InputDefinition> optionalInput = component.getInputs().stream().
726 filter(input -> input.getUniqueId().equals(inputId)).
729 if (!optionalInput.isPresent()) {
731 componentsUtils.getResponseFormat(ActionStatus.INPUT_IS_NOT_CHILD_OF_COMPONENT, inputId, componentId));
734 InputDefinition inputForDelete = optionalInput.get();
737 Either<Boolean, ResponseFormat> lockResultEither =
738 lockComponent(componentId, component, "deleteInput");
739 if (lockResultEither.isRight()) {
740 ResponseFormat responseFormat = lockResultEither.right().value();
741 deleteEither = Either.right(responseFormat);
745 // Delete input operations
747 StorageOperationStatus status =
748 toscaOperationFacade.deleteInputOfResource(component, inputForDelete.getName());
749 if (status != StorageOperationStatus.OK) {
750 log.debug("Component id: {} delete input id: {} failed", componentId, inputId);
751 deleteEither = Either.right(componentsUtils.getResponseFormat(
752 componentsUtils.convertFromStorageResponse(status), component.getName()));
756 if (BooleanUtils.isTrue(inputForDelete.getIsDeclaredListInput())){
757 deleteEither = deleteListInput(componentId, inputId, component, inputForDelete, status);
761 StorageOperationStatus storageOperationStatus =
762 propertyDeclarationOrchestrator.unDeclarePropertiesAsInputs(component, inputForDelete);
763 if (storageOperationStatus != StorageOperationStatus.OK) {
764 log.debug("Component id: {} update properties declared as input for input id: {} failed", componentId, inputId);
765 deleteEither = Either.right(componentsUtils.getResponseFormat(
766 componentsUtils.convertFromStorageResponse(status), component.getName()));
770 deleteEither = Either.left(inputForDelete);
773 if (deleteEither == null || deleteEither.isRight()) {
774 log.debug("Component id: {} delete input id: {} failed", componentId, inputId);
775 janusGraphDao.rollback();
777 log.debug("Component id: {} delete input id: {} success", componentId, inputId);
778 janusGraphDao.commit();
780 unlockComponent(deleteEither, component);
784 private Either<InputDefinition, ResponseFormat> deleteListInput(String componentId, String inputId,
785 org.openecomp.sdc.be.model.Component component,
786 InputDefinition inputForDelete, StorageOperationStatus status) {
787 // the input is created by 'Declare List'.
788 // need to 1. undeclare properties, 2. delete input, 3. delete private data type
790 StorageOperationStatus storageOperationStatus =
791 propertyDeclarationOrchestrator.unDeclarePropertiesAsListInputs(component, inputForDelete);
792 if (storageOperationStatus != StorageOperationStatus.OK) {
793 log.debug("Component id: {} update properties declared as input for input id: {} failed", componentId, inputId);
794 return Either.right(componentsUtils.getResponseFormat(
795 componentsUtils.convertFromStorageResponse(status), component.getName()));
797 Either<DataTypeDefinition, StorageOperationStatus> deleteResult =
798 dataTypeBusinessLogic.deletePrivateDataType(component, inputForDelete.getSchemaType());
799 if (deleteResult.isRight()) {
800 log.debug("Component id: {} delete datatype name: {} failed", componentId, inputForDelete.getSchemaType());
801 return Either.right(componentsUtils.getResponseFormat(
802 componentsUtils.convertFromStorageResponse(deleteResult.right().value()), component.getName()));
804 log.trace("deleteInput: deletePrivateDataType (OK)");
805 return Either.left(inputForDelete);
808 private Either<InputDefinition, ResponseFormat> prepareAndValidateInputBeforeCreate(InputDefinition newInputDefinition, Map<String, DataTypeDefinition> dataTypes) {
810 // validate input default values
811 Either<Boolean, ResponseFormat> defaultValuesValidation = validatePropertyDefaultValue(newInputDefinition, dataTypes);
812 if (defaultValuesValidation.isRight()) {
813 return Either.right(defaultValuesValidation.right().value());
816 ToscaPropertyType type = getType(newInputDefinition.getType());
817 if (type != null && newInputDefinition != null) {
818 PropertyValueConverter converter = type.getConverter();
820 SchemaDefinition schema = newInputDefinition.getSchema();
821 String innerType = null;
822 if (schema != null) {
823 PropertyDataDefinition prop = schema.getProperty();
825 innerType = prop.getType();
828 String convertedValue;
829 if (newInputDefinition.getDefaultValue() != null) {
830 convertedValue = converter.convert(newInputDefinition.getDefaultValue(), innerType, dataTypes);
831 newInputDefinition.setDefaultValue(convertedValue);
834 return Either.left(newInputDefinition);
837 public Either<InputDefinition, ResponseFormat> getInputsAndPropertiesForComponentInput(String userId, String componentId, String inputId, boolean inTransaction) {
838 Either<InputDefinition, ResponseFormat> result = null;
841 validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false);
842 ComponentParametersView filters = new ComponentParametersView();
843 filters.disableAll();
844 filters.setIgnoreComponentInstances(false);
845 filters.setIgnoreInputs(false);
846 filters.setIgnoreComponentInstancesInputs(false);
847 filters.setIgnoreComponentInstancesProperties(false);
848 filters.setIgnoreProperties(false);
849 Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters);
850 if(getComponentEither.isRight()){
851 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
852 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
853 return Either.right(componentsUtils.getResponseFormat(actionStatus));
856 org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
857 Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
859 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
860 log.debug(FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR, inputId, componentId, actionStatus);
861 return Either.right(componentsUtils.getResponseFormat(actionStatus));
864 InputDefinition resObj = op.get();
866 List<ComponentInstanceInput> inputCIInput = componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(component, inputId) ;
868 resObj.setInputs(inputCIInput);
871 List<ComponentInstanceProperty> inputProps = componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(component, inputId) ;
873 resObj.setProperties(inputProps);
876 result = Either.left(resObj);
882 if (!inTransaction) {
884 if (result == null || result.isRight()) {
885 log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP);
886 janusGraphDao.rollback();
888 log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP);
889 janusGraphDao.commit();