Constraint validation for instance properties in a service
Validating the properties of instance in a service against it's constraints
Issue-ID: SDC-4190
Signed-off-by: Imam hussain <imam.hussain@est.tech>
Change-Id: I04bb907f52229c3d214e15434595e5429ef5101c
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java
index 1d10c92..0b3610a 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java
@@ -63,6 +63,7 @@
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;
@@ -187,6 +188,7 @@
@Autowired
private ContainerInstanceTypesData containerInstanceTypesData;
private final ToscaFunctionValidator toscaFunctionValidator;
+ private final PropertyBusinessLogic propertyBusinessLogic;
@Autowired
public ComponentInstanceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation,
@@ -196,7 +198,8 @@
ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL,
ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator,
ForwardingPathOperation forwardingPathOperation, NodeFilterOperation nodeFilterOperation,
- ArtifactsOperations artifactToscaOperation, final ToscaFunctionValidator toscaFunctionValidator) {
+ ArtifactsOperations artifactToscaOperation, final ToscaFunctionValidator toscaFunctionValidator,
+ PropertyBusinessLogic propertyBusinessLogic) {
super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
artifactToscaOperation);
this.componentInstanceOperation = componentInstanceOperation;
@@ -206,6 +209,7 @@
this.forwardingPathOperation = forwardingPathOperation;
this.nodeFilterOperation = nodeFilterOperation;
this.toscaFunctionValidator = toscaFunctionValidator;
+ this.propertyBusinessLogic = propertyBusinessLogic;
}
public ComponentInstance createComponentInstance(String containerComponentParam, String containerComponentId, String userId,
@@ -1953,6 +1957,12 @@
}
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) {
@@ -3908,6 +3918,16 @@
}
}
+ private Either<Boolean, ResponseFormat> validatePropertyValueConstraint(List<ComponentInstanceProperty> 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));
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtil.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtil.java
index 442c3da..2d3ef85 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtil.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtil.java
@@ -34,6 +34,7 @@
import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
import org.openecomp.sdc.be.dao.api.ActionStatus;
import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+import org.openecomp.sdc.be.model.ComponentInstanceInput;
import org.openecomp.sdc.be.model.DataTypeDefinition;
import org.openecomp.sdc.be.model.InputDefinition;
import org.openecomp.sdc.be.model.PropertyConstraint;
@@ -77,6 +78,9 @@
}
private boolean isValuePresent(PropertyDefinition propertyDefinition) {
+ if (propertyDefinition instanceof ComponentInstanceInput) {
+ return StringUtils.isNotEmpty(propertyDefinition.getValue());
+ }
if (propertyDefinition instanceof InputDefinition) {
return StringUtils.isNotEmpty(propertyDefinition.getDefaultValue());
}
@@ -90,6 +94,11 @@
}
completeInputName = "";
completePropertyName = new StringBuilder();
+ if (propertyDefinition instanceof ComponentInstanceInput) {
+ setCompletePropertyName(propertyDefinition);
+ evaluateComplexTypeProperties(propertyDefinition);
+ return;
+ }
if (propertyDefinition instanceof InputDefinition) {
completeInputName = propertyDefinition.getName();
propertyDefinition = getPropertyDefinitionObjectFromInputs(propertyDefinition);
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java
index 3a5f40c..f22b346 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java
@@ -51,6 +51,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import lombok.SneakyThrows;
import mockit.Deencapsulation;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
@@ -72,6 +73,7 @@
import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
+import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.ForwardingPathElementDataDefinition;
@@ -190,7 +192,8 @@
private CompositionBusinessLogic compositionBusinessLogic;
@Mock
private ToscaFunctionValidator toscaFunctionValidator;
-
+ @Mock
+ private PropertyBusinessLogic propertyBusinessLogic;
private Component service;
private Component resource;
private ComponentInstance toInstance;
@@ -216,7 +219,7 @@
void init() {
MockitoAnnotations.openMocks(this);
componentInstanceBusinessLogic = new ComponentInstanceBusinessLogic(null, null, null, null, null, null, null, artifactsBusinessLogic, null,
- null, forwardingPathOperation, null, null, toscaFunctionValidator);
+ null, forwardingPathOperation, null, null, toscaFunctionValidator, propertyBusinessLogic);
componentInstanceBusinessLogic.setComponentsUtils(componentsUtils);
componentInstanceBusinessLogic.setToscaOperationFacade(toscaOperationFacade);
componentInstanceBusinessLogic.setUserValidations(userValidations);
@@ -305,6 +308,7 @@
}
+ @SneakyThrows
@Test
void testCreateOrUpdatePropertiesValues2() {
String containerComponentID = "containerId";
@@ -356,6 +360,10 @@
when(janusGraphDao.commit()).thenReturn(JanusGraphOperationStatus.OK);
when(graphLockOperation.unlockComponent(containerComponentID, NodeTypeEnum.ResourceInstance))
.thenReturn(StorageOperationStatus.OK);
+ when(propertyBusinessLogic.getComponentModelByComponentId(any())).thenReturn(component.getModel());
+ when(applicationDataTypeCache.getAll(any())).thenReturn(Either.left(types));
+ PropertyValueConstraintValidationUtil validationUtil = Mockito.mock(PropertyValueConstraintValidationUtil.class);
+ when(validationUtil.validatePropertyConstraints(any(),any(),any())).thenReturn(Either.left(any()));
Either<List<ComponentInstanceProperty>, ResponseFormat> responseFormatEither = componentInstanceBusinessLogic
.createOrUpdatePropertiesValues(
@@ -365,6 +373,7 @@
+ @SneakyThrows
@Test
void testCreateOrUpdatePropertiesValuesPropertyNotExists() {
String containerComponentID = "containerId";
@@ -396,6 +405,12 @@
.thenReturn(StorageOperationStatus.OK);
when(graphLockOperation.unlockComponent(containerComponentID, NodeTypeEnum.ResourceInstance))
.thenReturn(StorageOperationStatus.OK);
+ when(propertyBusinessLogic.getComponentModelByComponentId(any())).thenReturn(component.getModel());
+ Map<String, DataTypeDefinition> dataTypeMap = new HashMap<>();
+ when(applicationDataTypeCache.getAll(any())).thenReturn(Either.left(dataTypeMap));
+ PropertyValueConstraintValidationUtil validationUtil = Mockito.mock(PropertyValueConstraintValidationUtil.class);
+ when(validationUtil.validatePropertyConstraints(any(),any(),any()))
+ .thenReturn(Either.left(any()));
try {
componentInstanceBusinessLogic.createOrUpdatePropertiesValues(
@@ -406,6 +421,7 @@
}
+ @SneakyThrows
@Test
void testCreateOrUpdatePropertiesValuesValidationFailure() {
String containerComponentID = "containerId";
@@ -449,15 +465,22 @@
.thenReturn(Either.right(false));
when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.BAD_REQUEST))
.thenReturn(ActionStatus.INVALID_CONTENT);
+ when(propertyBusinessLogic.getComponentModelByComponentId(any())).thenReturn(component.getModel());
+ Map<String, DataTypeDefinition> dataTypeMap = new HashMap<>();
+ when(applicationDataTypeCache.getAll(any())).thenReturn(Either.left(dataTypeMap));
+ PropertyValueConstraintValidationUtil validationUtil = Mockito.mock(PropertyValueConstraintValidationUtil.class);
+ when(validationUtil.validatePropertyConstraints(any(),any(),any()))
+ .thenReturn(Either.left(any()));
final Either<List<ComponentInstanceProperty>, ResponseFormat> response = componentInstanceBusinessLogic.createOrUpdatePropertiesValues(
ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentID, resourceInstanceId, properties, "userId");
assertThat(response.isRight()).as("Response should be an error").isTrue();
final ResponseFormat responseFormat = response.right().value();
assertThat(responseFormat.getStatus()).as("Response status should be as expected").isEqualTo(400);
- assertThat(responseFormat.getMessageId()).as("Error message id should be as expected").isEqualTo("SVC4000");
+ assertThat(responseFormat.getMessageId()).as("Error message id should be as expected").isEqualTo("SVC4726");
}
+ @SneakyThrows
@Test
void testCreateOrUpdatePropertiesValuesMissingFieldFailure() {
String containerComponentID = "containerId";
@@ -491,6 +514,12 @@
.thenReturn(Either.left(component));
when(graphLockOperation.lockComponent(containerComponentID, NodeTypeEnum.ResourceInstance))
.thenReturn(StorageOperationStatus.OK);
+ when(propertyBusinessLogic.getComponentModelByComponentId(any())).thenReturn(component.getModel());
+ Map<String, DataTypeDefinition> dataTypeMap = new HashMap<>();
+ when(applicationDataTypeCache.getAll(any())).thenReturn(Either.left(dataTypeMap));
+ PropertyValueConstraintValidationUtil validationUtil = Mockito.mock(PropertyValueConstraintValidationUtil.class);
+ when(validationUtil.validatePropertyConstraints(any(),any(),any()))
+ .thenReturn(Either.left(any()));
try {
componentInstanceBusinessLogic.createOrUpdatePropertiesValues(
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java
index 8bd39af..e5ecf0c 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java
@@ -90,7 +90,7 @@
private final ForwardingPathOperation forwardingPathOperation = mock(ForwardingPathOperation.class);
private final NodeFilterOperation serviceFilterOperation = mock(NodeFilterOperation.class);
private final ToscaFunctionValidator toscaFunctionValidator = mock(ToscaFunctionValidator.class);
-
+ private final PropertyBusinessLogic propertyBusinessLogic = mock(PropertyBusinessLogic.class);
private static final UserBusinessLogic userAdminManager = mock(UserBusinessLogic.class);
public static final ComponentsUtils componentsUtils = mock(ComponentsUtils.class);
public static final IGroupInstanceOperation groupInstanceOperation = mock(IGroupInstanceOperation.class);
@@ -101,7 +101,7 @@
private final ComponentInstanceBusinessLogic bl = new ComponentInstanceBusinessLogic(elementDao, groupOperation, groupInstanceOperation,
groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
componentInstanceOperation, artifactBusinessLogic, compInstMergeDataBL, onChangeInstanceOperationOrchestrator,
- forwardingPathOperation, serviceFilterOperation, artifactToscaOperation, toscaFunctionValidator);
+ forwardingPathOperation, serviceFilterOperation, artifactToscaOperation, toscaFunctionValidator, propertyBusinessLogic);
@BeforeEach
void setUp() throws Exception {