* limitations under the License.
* ============LICENSE_END=========================================================
*/
+
package org.openecomp.sdc.be.components.impl;
import static org.openecomp.sdc.be.components.attribute.GetOutputUtils.isGetOutputValueForOutput;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.text.StringEscapeUtils;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.onap.sdc.tosca.datatypes.model.PropertyType;
import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
+import org.openecomp.sdc.be.components.impl.exceptions.ToscaGetFunctionExceptionSupplier;
import org.openecomp.sdc.be.components.impl.instance.ComponentInstanceChangeOperationOrchestrator;
import org.openecomp.sdc.be.components.impl.utils.DirectivesUtil;
import org.openecomp.sdc.be.components.merge.instance.ComponentInstanceMergeDataBusinessLogic;
import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
+import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType;
+import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.PropertySource;
import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
import org.openecomp.sdc.be.exception.BusinessException;
import org.openecomp.sdc.be.model.LifecycleStateEnum;
import org.openecomp.sdc.be.model.OutputDefinition;
import org.openecomp.sdc.be.model.PolicyDefinition;
+import org.openecomp.sdc.be.model.PropertyConstraint;
import org.openecomp.sdc.be.model.PropertyDefinition;
import org.openecomp.sdc.be.model.RelationshipInfo;
import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
import org.openecomp.sdc.be.model.RequirementDefinition;
import org.openecomp.sdc.be.model.Resource;
import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.ToscaPropertyData;
import org.openecomp.sdc.be.model.User;
import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData;
import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
+import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator;
import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
import org.openecomp.sdc.be.user.Role;
import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
import org.openecomp.sdc.common.util.ValidationUtils;
import org.openecomp.sdc.exception.ResponseFormat;
import org.springframework.beans.factory.annotation.Autowired;
+import org.yaml.snakeyaml.Yaml;
@org.springframework.stereotype.Component
public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
private static final String CREATE_OR_UPDATE_PROPERTY_VALUE = "CreateOrUpdatePropertyValue";
private static final String FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS = "Failed to copy the component instance to the canvas";
private static final String COPY_COMPONENT_INSTANCE_OK = "Copy component instance OK";
- private static final String CANNOT_ATTACH_RESOURCE_INSTANCES_TO_CONTAINER_RESOURCE_OF_TYPE = "Cannot attach resource instances to container resource of type {}";
+ private static final String CANNOT_ATTACH_RESOURCE_INSTANCES_TO_CONTAINER_RESOURCE_OF_TYPE =
+ "Cannot attach resource instances to container resource of type {}";
private static final String FAILED_TO_UPDATE_COMPONENT_INSTANCE_CAPABILITY = "Failed to update component instance capability on instance {} in "
+ "container {}";
private static final String SERVICE_PROXY = "serviceProxy";
private static final String RESTRICTED_OPERATION_ON_COMPONENT = "Restricted operation for user: {} on component {}";
private static final String RESOURCE_INSTANCE = "resource instance";
private static final String SERVICE = "service";
- private static final String UPDATE_PROPERTY_CONTEXT = "UpdatePropertyValueOnComponentInstance";
-
- private ComponentInstanceOperation componentInstanceOperation;
- private ArtifactsBusinessLogic artifactBusinessLogic;
- private ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL;
- private ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator;
- private ForwardingPathOperation forwardingPathOperation;
- private NodeFilterOperation nodeFilterOperation;
+
+ private final ComponentInstanceOperation componentInstanceOperation;
+ private final ArtifactsBusinessLogic artifactBusinessLogic;
+ private final ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL;
+ private final ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator;
+ private final ForwardingPathOperation forwardingPathOperation;
+ private final NodeFilterOperation nodeFilterOperation;
+ private final ToscaFunctionValidator toscaFunctionValidator;
+ private final PropertyBusinessLogic propertyBusinessLogic;
@Autowired
private CompositionBusinessLogic compositionBusinessLogic;
@Autowired
ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL,
ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator,
ForwardingPathOperation forwardingPathOperation, NodeFilterOperation nodeFilterOperation,
- ArtifactsOperations artifactToscaOperation) {
+ ArtifactsOperations artifactToscaOperation, final ToscaFunctionValidator toscaFunctionValidator,
+ PropertyBusinessLogic propertyBusinessLogic) {
super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
artifactToscaOperation);
this.componentInstanceOperation = componentInstanceOperation;
this.onChangeInstanceOperationOrchestrator = onChangeInstanceOperationOrchestrator;
this.forwardingPathOperation = forwardingPathOperation;
this.nodeFilterOperation = nodeFilterOperation;
+ this.toscaFunctionValidator = toscaFunctionValidator;
+ this.propertyBusinessLogic = propertyBusinessLogic;
}
public ComponentInstance createComponentInstance(String containerComponentParam, String containerComponentId, String userId,
}
if (CollectionUtils.isNotEmpty(filteredGroups)) {
filteredGroups.stream()
- .filter(g -> g.getArtifacts() != null && g.getArtifacts().stream().anyMatch(p -> p.equals(artifactDefinition.getGeneratedFromId()))).findFirst()
+ .filter(g -> g.getArtifacts() != null &&
+ g.getArtifacts().stream().anyMatch(p -> p.equals(artifactDefinition.getGeneratedFromId()))).findFirst()
.ifPresent(g -> fillInstanceArtifactMap(groupInstancesArtifacts, artifactDefinition, g));
}
}
}
ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
+ // Validate instance property against it's constrains
+ Either<Boolean, ResponseFormat> constraintValidatorResponse = validatePropertyValueConstraint(properties, componentId);
+ if (constraintValidatorResponse.isRight()) {
+ log.error("Failed validation value and constraint of property: {}", constraintValidatorResponse.right().value());
+ return Either.right(constraintValidatorResponse.right().value());
+ }
// lock resource
StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
if (lockStatus != StorageOperationStatus.OK) {
try {
for (ComponentInstanceProperty property : properties) {
validateMandatoryFields(property);
- ComponentInstanceProperty componentInstanceProperty = validatePropertyExistsOnComponent(property, containerComponent,
- foundResourceInstance);
+ validatePropertyExistsOnComponent(property, containerComponent, foundResourceInstance);
+ validatePropertyConstraintsNotChanged(properties, foundResourceInstance);
String propertyParentUniqueId = property.getParentUniqueId();
- Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, false, containerComponent.getModel());
+ if (property.isToscaFunction()) {
+ toscaFunctionValidator.validate(property, containerComponent);
+ property.setValue(StringEscapeUtils.unescapeJava(property.getToscaFunction().getValue()));
+ if (ToscaFunctionType.GET_INPUT == property.getToscaFunction().getType()) {
+ property.setGetInputValues(Collections.singletonList(buildGetInputValue(property)));
+ }
+ }
+ if (CollectionUtils.isNotEmpty(property.getSubPropertyToscaFunctions())) {
+ ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
+ if (ToscaPropertyType.LIST.equals(type)) {
+ final JSONArray jsonArray = property.getValue() == null ? new JSONArray() : new JSONArray(property.getValue());
+ property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> {
+ addE(jsonArray, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue());
+ });
+ property.setValue(jsonArray.toString());
+ } else {
+ final JSONObject jObject = property.getValue() == null ? new JSONObject() : new JSONObject(property.getValue());
+ property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> {
+ addE(jObject, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue());
+ });
+ property.setValue(jObject.toString());
+ }
+ }
+ Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, containerComponent.getModel());
if (updatedPropertyValue.isRight()) {
log.error("Failed to update property object value of property: {}",
property);
capPropDefinition.get().getName()), Either::right);
} else {
updatedPropertyValue.bimap(
- updatedValue -> {
- componentInstanceProperty.setValue(updatedValue);
- return updatePropertyOnContainerComponent(property, updatedValue,
- containerComponent, foundResourceInstance);
- }, Either::right);
- updatedProperties.add(componentInstanceProperty);
+ updatedValue -> updatePropertyOnContainerComponent(property, updatedValue, containerComponent, foundResourceInstance),
+ Either::right
+ );
+ updatedProperties.add(property);
}
}
}
}
+ private GetInputValueDataDefinition buildGetInputValue(final ComponentInstanceProperty property) {
+ final GetInputValueDataDefinition getInputValueDataDefinition = new GetInputValueDataDefinition();
+ getInputValueDataDefinition.setPropName(property.getName());
+ getInputValueDataDefinition.setInputName(((ToscaGetFunctionDataDefinition) property.getToscaFunction()).getPropertyName());
+ getInputValueDataDefinition.setInputId(((ToscaGetFunctionDataDefinition) property.getToscaFunction()).getPropertyUniqueId());
+ return getInputValueDataDefinition;
+ }
+
+ private void addE(JSONArray jsonArray, List<String> path, String value) {
+ Object objectForPath = jsonArray.opt(Integer.parseInt(path.get(0)));
+ if (objectForPath == null) {
+ if (path.size() > 1) {
+ if (StringUtils.isNumeric(path.get(1))) {
+ objectForPath = new JSONArray();
+ } else {
+ objectForPath = new JSONObject();
+ }
+ jsonArray.put(Integer.parseInt(path.get(0)), objectForPath);
+ }
+ }
+
+ if (path.size() == 1) {
+ Object valueAsObject = new Yaml().loadAs(value, Object.class);
+ jsonArray.put(Integer.parseInt(path.get(0)), valueAsObject);
+ } else {
+ if (objectForPath instanceof JSONObject) {
+ addE((JSONObject) objectForPath, path.subList(1, path.size()), value);
+ } else {
+ addE((JSONArray) objectForPath, path.subList(1, path.size()), value);
+ }
+ }
+ }
+
+ private void addE(JSONObject jsonObject, List<String> path, String value) {
+
+ Object objectForPath = null;
+ if (jsonObject.has(path.get(0))) {
+ objectForPath = jsonObject.get(path.get(0));
+ } else {
+ if (path.size() > 1 && StringUtils.isNumeric(path.get(1))) {
+ objectForPath = new JSONArray();
+ } else {
+ objectForPath = new JSONObject();
+ }
+ jsonObject.put(path.get(0), objectForPath);
+ }
+
+ if (path.size() == 1) {
+ Object valueAsObject = new Yaml().loadAs(value, Object.class);
+ jsonObject.put(path.get(0), valueAsObject);
+ } else {
+ if (objectForPath instanceof JSONObject) {
+ addE((JSONObject) objectForPath, path.subList(1, path.size()), value);
+ } else {
+ addE((JSONArray) objectForPath, path.subList(1, path.size()), value);
+ }
+ }
+ }
+
+ private void setJsonObjectForSubProperty(final JSONObject jObject, final List<String> path, String value) {
+ if (path.size() == 1) {
+ Object valueAsObject = new Yaml().loadAs(value, Object.class);
+ jObject.put(path.get(0), valueAsObject);
+ } else {
+ if (!jObject.has(path.get(0))) {
+ jObject.put(path.get(0), new JSONObject());
+ }
+ final JSONObject jsonObject = jObject.getJSONObject(path.get(0));
+ setJsonObjectForSubProperty(jsonObject, path.subList(1, path.size()), value);
+ }
+ }
+
public Either<List<ComponentInstanceAttribute>, ResponseFormat> createOrUpdateAttributeValues(final ComponentTypeEnum componentTypeEnum,
final String componentId,
final String resourceInstanceId,
}
final ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
+ // Validate instance attributes against it's constraints
+ List<PropertyDefinition> attributesToValidate = new ArrayList<>();
+ attributes.forEach((componentInstanceAttribute) -> {
+ PropertyDefinition propertyDefinition = new PropertyDefinition();
+ propertyDefinition.setValue(componentInstanceAttribute.getValue());
+ propertyDefinition.setType(componentInstanceAttribute.getType());
+ propertyDefinition.setName(componentInstanceAttribute.getName());
+ propertyDefinition.setUniqueId(componentInstanceAttribute.getUniqueId());
+ attributesToValidate.add(propertyDefinition);
+ });
+ Either<Boolean, ResponseFormat> constraintValidatorResponse = validatePropertyValueConstraint(attributesToValidate, componentId);
+ if (constraintValidatorResponse.isRight()) {
+ log.error("Failed validation value and constraint of attribute: {}", constraintValidatorResponse.right().value());
+ return Either.right(constraintValidatorResponse.right().value());
+ }
+
// lock resource
final StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
if (lockStatus != StorageOperationStatus.OK) {
}
}
- private ComponentInstanceProperty validatePropertyExistsOnComponent(ComponentInstanceProperty property, Component containerComponent,
- ComponentInstance foundResourceInstance) {
+ private void validatePropertyExistsOnComponent(ComponentInstanceProperty property, Component containerComponent,
+ ComponentInstance foundResourceInstance) {
List<ComponentInstanceProperty> instanceProperties = containerComponent.getComponentInstancesProperties()
.get(foundResourceInstance.getUniqueId());
- Optional<ComponentInstanceProperty> instanceProperty = instanceProperties.stream().filter(p -> p.getName().equals(property.getName()))
- .findAny();
- if (!instanceProperty.isPresent()) {
+ final boolean hasProperty = instanceProperties.stream().anyMatch(p -> p.getName().equals(property.getName()));
+ if (!hasProperty) {
throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, property.getName());
}
- return instanceProperty.get();
}
private ComponentInstanceAttribute validateAttributeExistsOnComponent(final ComponentInstanceAttribute attribute,
final Component containerComponent,
final ComponentInstance foundResourceInstance) {
- final List<ComponentInstanceAttribute> instanceProperties =
+ final List<ComponentInstanceAttribute> instanceAttributes =
containerComponent.getComponentInstancesAttributes().get(foundResourceInstance.getUniqueId());
+ final List<ComponentInstanceProperty> instanceProperties =
+ containerComponent.getComponentInstancesProperties().get(foundResourceInstance.getUniqueId());
final Optional<ComponentInstanceAttribute> instanceAttribute =
+ instanceAttributes.stream().filter(p -> p.getName().equals(attribute.getName())).findAny();
+ final Optional<ComponentInstanceProperty> instanceProperty =
instanceProperties.stream().filter(p -> p.getName().equals(attribute.getName())).findAny();
- if (!instanceAttribute.isPresent()) {
- throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, attribute.getName());
+ if (instanceAttribute.isPresent()) {
+ return instanceAttribute.get();
}
- return instanceAttribute.get();
+ if (instanceProperty.isPresent()) {
+ ComponentInstanceAttribute propAttribute = getComponentInstanceAttribute(instanceProperty.get());
+ return propAttribute;
+ }
+ throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, attribute.getName());
+ }
+
+ private ComponentInstanceAttribute getComponentInstanceAttribute(ComponentInstanceProperty property) {
+ ComponentInstanceAttribute attribute = new ComponentInstanceAttribute();
+ attribute.setParentUniqueId(property.getParentUniqueId());
+ attribute.setName(property.getName());
+ attribute.setOwnerId(property.getOwnerId());
+ attribute.setType(property.getType());
+ attribute.setSchema(property.getSchema());
+ attribute.setUniqueId(property.getUniqueId());
+ attribute.setValue(property.getValue());
+ attribute.setDefaultValue(property.getDefaultValue());
+ return attribute;
}
private ResponseFormat updateCapabilityPropertyOnContainerComponent(ComponentInstanceProperty property,
return false;
}
- private <T extends PropertyDefinition> Either<String, ResponseFormat> updatePropertyObjectValue(T property, boolean isInput, final String model) {
+ private <T extends PropertyDefinition> Either<String, ResponseFormat> updatePropertyObjectValue(T property, final String model) {
final Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, model);
String innerType = null;
String propertyType = property.getType();
log.debug("The type of the property {} is {}", property.getUniqueId(), propertyType);
if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
- SchemaDefinition def = property.getSchema();
- if (def == null) {
+ SchemaDefinition schema = property.getSchema();
+ if (schema == null) {
log.debug("Schema doesn't exists for property of type {}", type);
return Either
.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
}
- PropertyDataDefinition propDef = def.getProperty();
+ PropertyDataDefinition propDef = schema.getProperty();
if (propDef == null) {
log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
return Either
// Specific Update Logic
String newValue = property.getValue();
- if (property.getToscaGetFunctionType() != null) {
- validateToscaGetFunction(property);
+ if (property.hasToscaFunction() || CollectionUtils.isNotEmpty(property.getSubPropertyToscaFunctions())) {
return Either.left(newValue);
}
newValue = object.toString();
}
}
- if (!isInput) {
- ImmutablePair<String, Boolean> pair = propertyOperation
- .validateAndUpdateRules(propertyType, ((ComponentInstanceProperty) property).getRules(), innerType, allDataTypes, true);
- if (pair.getRight() != null && Boolean.FALSE.equals(pair.getRight())) {
- BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), property.getName(), propertyType);
- return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
- DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
- }
+ ImmutablePair<String, Boolean> pair = propertyOperation
+ .validateAndUpdateRules(propertyType, ((ComponentInstanceProperty) property).getRules(), innerType, allDataTypes, true);
+ if (pair.getRight() != null && Boolean.FALSE.equals(pair.getRight())) {
+ BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), property.getName(), propertyType);
+ return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
+ DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
}
return Either.left(newValue);
}
return Either.left(newValue);
}
- private <T extends PropertyDefinition> void validateToscaGetFunction(T property) {
- if (property.getToscaGetFunctionType() == ToscaGetFunctionType.GET_INPUT) {
- final List<GetInputValueDataDefinition> getInputValues = property.getGetInputValues();
- if (CollectionUtils.isEmpty(getInputValues)) {
- log.debug("No input information provided. Cannot set get_input.");
- throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
- }
- if (getInputValues.size() > 1) {
- log.debug("More than one input provided. Cannot set get_input.");
- throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
+ private <T extends PropertyDefinition> void validateToscaGetFunction(T property, Component parentComponent) {
+ final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction();
+ validateGetToscaFunctionAttributes(toscaGetFunction);
+ validateGetPropertySource(toscaGetFunction.getFunctionType(), toscaGetFunction.getPropertySource());
+ if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_INPUT) {
+ validateGetFunction(property, parentComponent.getInputs(), parentComponent.getModel());
+ return;
+ }
+ if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_PROPERTY) {
+ if (toscaGetFunction.getPropertySource() == PropertySource.SELF) {
+ validateGetFunction(property, parentComponent.getProperties(), parentComponent.getModel());
+ } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) {
+ final ComponentInstance componentInstance =
+ parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId())
+ .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName()));
+ validateGetFunction(property, componentInstance.getProperties(), parentComponent.getModel());
}
- final GetInputValueDataDefinition getInputValueDataDefinition = getInputValues.get(0);
- if (!property.getType().equals(getInputValueDataDefinition.getInputType())) {
- log.debug("Input type '{}' diverges from the property type '{}'. Cannot set get_input.",
- getInputValueDataDefinition.getInputType(), property.getType());
- throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
+ return;
+ }
+ if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_ATTRIBUTE) {
+ if (toscaGetFunction.getPropertySource() == PropertySource.SELF) {
+ validateGetFunction(property, parentComponent.getAttributes(), parentComponent.getModel());
+ } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) {
+ final ComponentInstance componentInstance =
+ parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId())
+ .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName()));
+ validateGetFunction(property, componentInstance.getAttributes(), parentComponent.getModel());
}
+
return;
}
- throw new ByActionStatusComponentException(ActionStatus.NOT_SUPPORTED,
- "Tosca function " + property.getToscaGetFunctionType().getToscaGetFunctionName());
+ throw ToscaGetFunctionExceptionSupplier.functionNotSupported(toscaGetFunction.getFunctionType()).get();
+ }
+
+ private <T extends PropertyDefinition> void validateGetFunction(final T property,
+ final List<? extends ToscaPropertyData> parentProperties,
+ final String model) {
+ final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction();
+ if (CollectionUtils.isEmpty(parentProperties)) {
+ throw ToscaGetFunctionExceptionSupplier
+ .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource(),
+ toscaGetFunction.getFunctionType()
+ ).get();
+ }
+ final String getFunctionPropertyUniqueId = toscaGetFunction.getPropertyUniqueId();
+ ToscaPropertyData referredProperty = parentProperties.stream()
+ .filter(property1 -> getFunctionPropertyUniqueId.equals(property1.getUniqueId()))
+ .findFirst()
+ .orElseThrow(ToscaGetFunctionExceptionSupplier
+ .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource()
+ , toscaGetFunction.getFunctionType())
+ );
+ if (toscaGetFunction.isSubProperty()) {
+ referredProperty = findSubProperty(referredProperty, toscaGetFunction, model);
+ }
+
+ if (!property.getType().equals(referredProperty.getType()) && !"list".equalsIgnoreCase(referredProperty.getType())) {
+ throw ToscaGetFunctionExceptionSupplier
+ .propertyTypeDiverge(toscaGetFunction.getType(), referredProperty.getType(), property.getType()).get();
+ }
+ if (PropertyType.typeHasSchema(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getType())
+ && !"list".equalsIgnoreCase(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getSchemaType())) {
+ throw ToscaGetFunctionExceptionSupplier
+ .propertySchemaDiverge(toscaGetFunction.getType(), referredProperty.getSchemaType(), property.getSchemaType()).get();
+ }
+ }
+
+ private ToscaPropertyData findSubProperty(final ToscaPropertyData referredProperty,
+ final ToscaGetFunctionDataDefinition toscaGetFunction,
+ final String model) {
+ final Map<String, DataTypeDefinition> dataTypeMap = loadDataTypes(model);
+ final List<String> propertyPathFromSource = toscaGetFunction.getPropertyPathFromSource();
+ DataTypeDefinition dataType = dataTypeMap.get(referredProperty.getType());
+ if (dataType == null) {
+ throw ToscaGetFunctionExceptionSupplier
+ .propertyDataTypeNotFound(propertyPathFromSource.get(0), referredProperty.getType(), toscaGetFunction.getFunctionType()).get();
+ }
+ ToscaPropertyData foundProperty = referredProperty;
+ for (int i = 1; i < propertyPathFromSource.size(); i++) {
+ final String currentPropertyName = propertyPathFromSource.get(i);
+ foundProperty = dataType.getProperties().stream()
+ .filter(propertyDefinition -> currentPropertyName.equals(propertyDefinition.getName())).findFirst()
+ .orElseThrow(
+ ToscaGetFunctionExceptionSupplier
+ .propertyNotFoundOnTarget(propertyPathFromSource.subList(0, i), toscaGetFunction.getPropertySource(),
+ toscaGetFunction.getFunctionType())
+ );
+ dataType = dataTypeMap.get(foundProperty.getType());
+ if (dataType == null) {
+ throw ToscaGetFunctionExceptionSupplier
+ .propertyDataTypeNotFound(propertyPathFromSource.subList(0, i), foundProperty.getType(),
+ toscaGetFunction.getFunctionType()).get();
+ }
+ }
+ return foundProperty;
+ }
+
+ private Map<String, DataTypeDefinition> loadDataTypes(String model) {
+ final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypeEither =
+ applicationDataTypeCache.getAll(model);
+ if (dataTypeEither.isRight()) {
+ throw ToscaGetFunctionExceptionSupplier.couldNotLoadDataTypes(model).get();
+ }
+ return dataTypeEither.left().value();
+ }
+
+ private void validateGetPropertySource(final ToscaGetFunctionType functionType, final PropertySource propertySource) {
+ if (functionType == ToscaGetFunctionType.GET_INPUT && propertySource != PropertySource.SELF) {
+ throw ToscaGetFunctionExceptionSupplier
+ .targetSourceNotSupported(functionType, propertySource).get();
+ }
+ if (functionType == ToscaGetFunctionType.GET_PROPERTY && !List.of(PropertySource.SELF, PropertySource.INSTANCE).contains(propertySource)) {
+ throw ToscaGetFunctionExceptionSupplier
+ .targetSourceNotSupported(functionType, propertySource).get();
+ }
+ }
+
+ private void validateGetToscaFunctionAttributes(final ToscaGetFunctionDataDefinition toscaGetFunction) {
+ if (toscaGetFunction.getFunctionType() == null) {
+ throw ToscaGetFunctionExceptionSupplier.targetFunctionTypeNotFound().get();
+ }
+ if (toscaGetFunction.getPropertySource() == null) {
+ throw ToscaGetFunctionExceptionSupplier.targetPropertySourceNotFound(toscaGetFunction.getFunctionType()).get();
+ }
+ if (CollectionUtils.isEmpty(toscaGetFunction.getPropertyPathFromSource())) {
+ throw ToscaGetFunctionExceptionSupplier
+ .targetSourcePathNotFound(toscaGetFunction.getFunctionType()).get();
+ }
+ if (StringUtils.isEmpty(toscaGetFunction.getSourceName()) || StringUtils.isBlank(toscaGetFunction.getSourceName())) {
+ throw ToscaGetFunctionExceptionSupplier.sourceNameNotFound(toscaGetFunction.getPropertySource()).get();
+ }
+ if (StringUtils.isEmpty(toscaGetFunction.getSourceUniqueId()) || StringUtils.isBlank(toscaGetFunction.getSourceUniqueId())) {
+ throw ToscaGetFunctionExceptionSupplier.sourceIdNotFound(toscaGetFunction.getPropertySource()).get();
+ }
+ if (StringUtils.isEmpty(toscaGetFunction.getPropertyName()) || StringUtils.isBlank(toscaGetFunction.getPropertyName())) {
+ throw ToscaGetFunctionExceptionSupplier.propertyNameNotFound(toscaGetFunction.getPropertySource()).get();
+ }
+ if (StringUtils.isEmpty(toscaGetFunction.getPropertyUniqueId()) || StringUtils.isBlank(toscaGetFunction.getPropertyUniqueId())) {
+ throw ToscaGetFunctionExceptionSupplier.propertyIdNotFound(toscaGetFunction.getPropertySource()).get();
+ }
}
private ResponseFormat updateInputOnContainerComponent(ComponentInstanceInput input, String newValue, Component containerComponent,
}
Component eitherOriginComponent = getInstanceOriginNode(currentResourceInstance);
- DataForMergeHolder dataHolder = compInstMergeDataBL
- .saveAllDataBeforeDeleting(containerComponent, currentResourceInstance, eitherOriginComponent);
+ DataForMergeHolder dataHolder =
+ compInstMergeDataBL.saveAllDataBeforeDeleting(containerComponent, currentResourceInstance, eitherOriginComponent);
ComponentInstance resResourceInfo = deleteComponentInstance(containerComponent, componentInstanceId,
containerComponentType);
} else {
origComponent = getOriginComponentFromComponentInstance(newComponentInstance);
newComponentInstance.setName(resResourceInfo.getName());
- final Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade
- .getToscaFullElement(newComponentInstance.getComponentUid());
- if (getComponentRes.isRight()) {
- throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
- }
- final Component component = getComponentRes.left().value();
- final Map<String, InterfaceDefinition> componentInterfaces = component.getInterfaces();
+ final Map<String, InterfaceDefinition> componentInterfaces = origComponent.getInterfaces();
if (MapUtils.isNotEmpty(componentInterfaces)) {
componentInterfaces.forEach(newComponentInstance::addInterface);
}
newComponentInstance.setInstanceCount(resResourceInfo.getInstanceCount());
newComponentInstance.setMaxOccurrences(resResourceInfo.getMaxOccurrences());
newComponentInstance.setMinOccurrences(resResourceInfo.getMinOccurrences());
+ newComponentInstance.setDirectives(resResourceInfo.getDirectives());
+ checkForExternalReqAndCapabilities(origComponent, resResourceInfo);
ComponentInstance updatedComponentInstance =
createComponentInstanceOnGraph(containerComponent, origComponent, newComponentInstance, user);
log.debug("Component with id {} was not found", containerComponentId);
throw new ByActionStatusComponentException(actionStatus, Constants.EMPTY_STRING);
}
- resourceInstanceStatus = getResourceInstanceById(updatedComponentRes.left().value(),
- updatedComponentInstance.getUniqueId());
+
+ maintainNodeFilters(currentResourceInstance, newComponentInstance, containerComponentId);
+
+ resourceInstanceStatus = getResourceInstanceById(updatedComponentRes.left().value(), updatedComponentInstance.getUniqueId());
if (resourceInstanceStatus.isRight()) {
throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse
(resourceInstanceStatus.right().value()), updatedComponentInstance.getUniqueId());
}
}
+ private void maintainNodeFilters(
+ ComponentInstance currentResourceInstance,
+ ComponentInstance newComponentInstance,
+ String containerComponentId) {
+ CINodeFilterDataDefinition filterToMaintain = currentResourceInstance.getNodeFilter();
+ if (null != filterToMaintain) {
+ nodeFilterOperation.addNodeFilterData(
+ containerComponentId.toLowerCase(),
+ newComponentInstance.getUniqueId(),
+ filterToMaintain);
+ }
+ }
+
+ private void checkForExternalReqAndCapabilities(Component component, ComponentInstance resResourceInfo) {
+ if (MapUtils.isNotEmpty(component.getRequirements())) {
+ component.getRequirements().entrySet().forEach(requirementsMap -> {
+ if (MapUtils.isNotEmpty(resResourceInfo.getRequirements()) &&
+ resResourceInfo.getRequirements().containsKey(requirementsMap.getKey())) {
+ List<RequirementDefinition> resourceReqList = resResourceInfo.getRequirements().get(requirementsMap.getKey());
+ for (RequirementDefinition requirements : requirementsMap.getValue()) {
+ String requirementName = requirements.getName();
+ resourceReqList.forEach(requirementDefinition -> {
+ if (requirementName.equals(requirementDefinition.getName()) && requirementDefinition.isExternal()) {
+ requirements.setExternal(requirementDefinition.isExternal());
+ }
+ });
+ }
+ }
+ });
+ }
+ if (MapUtils.isNotEmpty(component.getCapabilities())) {
+ component.getCapabilities().entrySet().forEach(capabilityMap -> {
+ if (MapUtils.isNotEmpty(resResourceInfo.getCapabilities()) && resResourceInfo.getCapabilities().containsKey(capabilityMap.getKey())) {
+ List<CapabilityDefinition> resourceCapList = resResourceInfo.getCapabilities().get(capabilityMap.getKey());
+ capabilityMap.getValue().forEach(capabilities -> {
+ String capabilityName = capabilities.getName();
+ for (CapabilityDefinition capDef : resourceCapList) {
+ if (capabilityName.equals(capDef.getName()) && capDef.isExternal()) {
+ capabilities.setExternal(capDef.isExternal());
+ }
+ }
+ });
+ }
+ });
+ }
+ }
+
private boolean isFillProxyRes(StorageOperationStatus fillProxyRes) {
if (fillProxyRes != StorageOperationStatus.OK) {
log.debug("Failed to fill service proxy resource data with data from service, error {}", fillProxyRes);
containerComponentId);
}
- List<ComponentInstanceProperty> instanceProperties = containerComponent.getComponentInstancesProperties().get(componentInstanceUniqueId);
- if (CollectionUtils.isEmpty(instanceProperties)) {
- instanceProperties = new ArrayList<>();
+ List<ComponentInstanceProperty> instanceProperties = new ArrayList<>();
+ if (MapUtils.isNotEmpty(containerComponent.getComponentInstancesProperties())) {
+ instanceProperties = containerComponent.getComponentInstancesProperties()
+ .get(componentInstanceUniqueId);
}
return instanceProperties;
} catch (ComponentException e) {
return ComponentValidations.validateNameIsUniqueInComponent(oldComponentInstance.getName(), newInstanceName, containerComponent);
}
- private Either<ComponentInstance, StorageOperationStatus> getResourceInstanceById(Component containerComponent, String instanceId) {
- Either<ComponentInstance, StorageOperationStatus> result = Either.right(StorageOperationStatus.NOT_FOUND);
- List<ComponentInstance> instances = containerComponent.getComponentInstances();
- Optional<ComponentInstance> foundInstance = Optional.empty();
- if (!CollectionUtils.isEmpty(instances)) {
- if (result.isRight()) {
- foundInstance = instances.stream().filter(i -> i.getUniqueId().equals(instanceId)).findFirst();
- if (!foundInstance.isPresent()) {
- result = Either.right(StorageOperationStatus.NOT_FOUND);
- }
- }
- if (result.isRight() && foundInstance.isPresent()) {
- result = Either.left(foundInstance.get());
- }
+ private Either<ComponentInstance, StorageOperationStatus> getResourceInstanceById(final Component containerComponent, final String instanceId) {
+ final List<ComponentInstance> instances = containerComponent.getComponentInstances();
+ if (CollectionUtils.isEmpty(instances)) {
+ return Either.right(StorageOperationStatus.NOT_FOUND);
}
- return result;
+
+ final Optional<ComponentInstance> foundInstance = instances.stream().filter(i -> i.getUniqueId().equals(instanceId)).findFirst();
+ if (foundInstance.isEmpty()) {
+ return Either.right(StorageOperationStatus.NOT_FOUND);
+ }
+
+ return Either.left(foundInstance.get());
}
private ComponentInstance buildComponentInstance(ComponentInstance resourceInstanceForUpdate, ComponentInstance origInstanceForUpdate) {
if (sourceAttributeName.equals(destAttribute.getName())) {
log.debug("Start to copy the attribute exists {}", sourceAttributeName);
sourceAttribute.setUniqueId(
- UniqueIdBuilder.buildResourceInstanceUniuqeId("attribute", destComponentInstanceId.split("\\.")[1], sourceAttributeName));
+ UniqueIdBuilder.buildResourceInstanceUniqueId("attribute", destComponentInstanceId.split("\\.")[1], sourceAttributeName));
Either<ComponentInstanceAttribute, ResponseFormat> updateAttributeValueEither = createOrUpdateAttributeValueForCopyPaste(
ComponentTypeEnum.SERVICE, destComponent.getUniqueId(), destComponentInstanceId, sourceAttribute, userId);
if (updateAttributeValueEither.isRight()) {
}
}
+ private void validatePropertyConstraintsNotChanged(List<ComponentInstanceProperty> newProperties, ComponentInstance originalResourceInstance) {
+ for (ComponentInstanceProperty newProperty : newProperties) {
+ Optional<PropertyDefinition> originalProperty = originalResourceInstance.getProperties().stream()
+ .filter(prop -> prop.getUniqueId().equals(newProperty.getUniqueId())).findAny();
+ if (originalProperty.isPresent()) {
+ List<PropertyConstraint> originalConstraints = originalProperty.get().getConstraints();
+ List<PropertyConstraint> newConstraints = newProperty.getConstraints();
+ if (!Objects.equals(originalConstraints, newConstraints)) {
+ throw new ByActionStatusComponentException(ActionStatus.CANNOT_CHANGE_CONSTRAINTS);
+ }
+ } else {
+ throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, newProperty.getUniqueId());
+ }
+ }
+ }
+
+ private Either<Boolean, ResponseFormat> validatePropertyValueConstraint(List<? extends PropertyDefinition> properties, final String componentId) {
+ try {
+ String propertyModel = propertyBusinessLogic.getComponentModelByComponentId(componentId);
+ PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil = new PropertyValueConstraintValidationUtil();
+ return propertyValueConstraintValidationUtil.validatePropertyConstraints(properties, applicationDataTypeCache, propertyModel);
+ } catch (BusinessLogicException e) {
+ return Either.right(e.getResponseFormat());
+ }
+ }
+
public void validateUser(final String userId) {
final User user = userValidations.validateUserExists(userId);
userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
}
+
+ public void setCompositionBusinessLogic(CompositionBusinessLogic compositionBusinessLogic) {
+ this.compositionBusinessLogic = compositionBusinessLogic;
+ }
+
+ public void setContainerInstanceTypesData(ContainerInstanceTypesData containerInstanceTypesData) {
+ this.containerInstanceTypesData = containerInstanceTypesData;
+ }
+
}