* 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.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.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;
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 final ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator;
private final ForwardingPathOperation forwardingPathOperation;
private final NodeFilterOperation nodeFilterOperation;
+ private final ToscaFunctionValidator toscaFunctionValidator;
+ private final PropertyBusinessLogic propertyBusinessLogic;
@Autowired
private CompositionBusinessLogic compositionBusinessLogic;
@Autowired
private ContainerInstanceTypesData containerInstanceTypesData;
- private final ToscaFunctionValidator toscaFunctionValidator;
- private final PropertyBusinessLogic propertyBusinessLogic;
@Autowired
public ComponentInstanceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation,
}
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);
+ 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());
for (ComponentInstanceProperty property : properties) {
validateMandatoryFields(property);
validatePropertyExistsOnComponent(property, containerComponent, foundResourceInstance);
+ validatePropertyConstraintsNotChanged(properties, foundResourceInstance);
String propertyParentUniqueId = property.getParentUniqueId();
if (property.isToscaFunction()) {
toscaFunctionValidator.validate(property, containerComponent);
- property.setValue(property.getToscaFunction().getValue());
+ 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())){
- final JSONObject jObject = property.getValue() == null ? new JSONObject() : new JSONObject(property.getValue());
- property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> {
- setJsonObjectForSubProperty(jObject, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue());
- });
- property.setValue(jObject.toString());
+ 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()) {
graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
}
}
-
+
+ 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);
propertyDefinition.setUniqueId(componentInstanceAttribute.getUniqueId());
attributesToValidate.add(propertyDefinition);
});
- Either<Boolean, ResponseFormat> constraintValidatorResponse = validatePropertyValueConstraint(attributesToValidate,componentId);
+ 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());
}
private void validatePropertyExistsOnComponent(ComponentInstanceProperty property, Component containerComponent,
- ComponentInstance foundResourceInstance) {
+ ComponentInstance foundResourceInstance) {
List<ComponentInstanceProperty> instanceProperties = containerComponent.getComponentInstancesProperties()
.get(foundResourceInstance.getUniqueId());
final boolean hasProperty = instanceProperties.stream().anyMatch(p -> p.getName().equals(property.getName()));
referredProperty = findSubProperty(referredProperty, toscaGetFunction, model);
}
- if (!property.getType().equals(referredProperty.getType())) {
+ 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.getSchemaType())) {
+ 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 void maintainNodeFilters(
- ComponentInstance currentResourceInstance,
- ComponentInstance newComponentInstance,
- String containerComponentId) {
+ ComponentInstance currentResourceInstance,
+ ComponentInstance newComponentInstance,
+ String containerComponentId) {
CINodeFilterDataDefinition filterToMaintain = currentResourceInstance.getNodeFilter();
if (null != filterToMaintain) {
nodeFilterOperation.addNodeFilterData(
- containerComponentId.toLowerCase(),
- newComponentInstance.getUniqueId(),
- filterToMaintain);
+ 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())) {
+ 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();
}
}
+ 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);