Fix Service/VF set value to list/map properties

In the Service Property Assignment page, setting a value to a property
of type list<complex> or map<complex> was having the type replaced by
the schema type and the value incorrectly set.
Add test cases to cover the problem.
Include small refactors.

Issue-ID: SDC-3926
Change-Id: I1257dbb02e18b103118672ec52d663707d53229c
Signed-off-by: andre.schmid <andre.schmid@est.tech>
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java
index 28faf73..33bb865 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java
@@ -336,7 +336,7 @@
     }
 
     private Either<Boolean, ResponseFormat> validateInputValueConstraint(List<InputDefinition> inputs, final String model) {
-        PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil = PropertyValueConstraintValidationUtil.getInstance();
+        PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil = new PropertyValueConstraintValidationUtil();
         List<InputDefinition> inputDefinitions = new ArrayList<>();
         for (InputDefinition inputDefinition : inputs) {
             InputDefinition inputDef = new InputDefinition();
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java
index 24ba0ea..aa011e9 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java
@@ -548,7 +548,7 @@
         if (Objects.nonNull(operationInputDefinition.getParentPropertyType())) {
             inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
         }
-        return PropertyValueConstraintValidationUtil.getInstance().validatePropertyConstraints(Collections.singletonList(inputDefinition),
+        return new PropertyValueConstraintValidationUtil().validatePropertyConstraints(Collections.singletonList(inputDefinition),
             applicationDataTypeCache, model);
     }
 
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 e7c6ef3..25ca7d6 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
@@ -15,6 +15,7 @@
  */
 package org.openecomp.sdc.be.datamodel.utils;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import fj.data.Either;
@@ -53,27 +54,23 @@
     private static final Logger logger = LoggerFactory.getLogger(PropertyValueConstraintValidationUtil.class);
     private static final String IGNORE_PROPERTY_VALUE_START_WITH = "{\"get_input\":";
     private Map<String, DataTypeDefinition> dataTypeDefinitionCache;
-    private ObjectMapper objectMapper = new ObjectMapper();
-    private List<String> errorMessages = new ArrayList<>();
+    private final ObjectMapper objectMapper = new ObjectMapper();
+    private final List<String> errorMessages = new ArrayList<>();
     private StringBuilder completePropertyName;
     private String completeInputName;
 
-    public static PropertyValueConstraintValidationUtil getInstance() {
-        return new PropertyValueConstraintValidationUtil();
-    }
-
     public Either<Boolean, ResponseFormat> validatePropertyConstraints(final Collection<? extends PropertyDefinition> propertyDefinitionList,
                                                                        final ApplicationDataTypeCache applicationDataTypeCache,
                                                                        final String model) {
-        ResponseFormatManager responseFormatManager = getResponseFormatManager();
+
         dataTypeDefinitionCache = applicationDataTypeCache.getAll(model).left().value();
-        CollectionUtils.emptyIfNull(propertyDefinitionList).stream().filter(this::isValuePresent)
+        CollectionUtils.emptyIfNull(propertyDefinitionList).stream()
+            .filter(this::isValuePresent)
             .forEach(this::evaluatePropertyTypeForConstraintValidation);
         if (CollectionUtils.isNotEmpty(errorMessages)) {
-            logger.error("Properties with Invalid Data:", errorMessages);
-            ResponseFormat inputResponse = responseFormatManager
-                .getResponseFormat(ActionStatus.INVALID_PROPERTY_VALUES, String.join(",", errorMessages));
-            return Either.right(inputResponse);
+            final String errorMsgAsString = String.join(",", errorMessages);
+            logger.debug("Properties with Invalid Data: {}", errorMsgAsString);
+            return Either.right(getResponseFormatManager().getResponseFormat(ActionStatus.INVALID_PROPERTY_VALUES, errorMsgAsString));
         }
         return Either.left(Boolean.TRUE);
     }
@@ -86,30 +83,30 @@
     }
 
     private void evaluatePropertyTypeForConstraintValidation(PropertyDefinition propertyDefinition) {
-        if (Objects.nonNull(propertyDefinition.getType()) && dataTypeDefinitionCache.containsKey(propertyDefinition.getType())) {
-            completeInputName = "";
-            completePropertyName = new StringBuilder();
-            if (propertyDefinition instanceof InputDefinition) {
-                completeInputName = propertyDefinition.getName();
-                propertyDefinition = getPropertyDefinitionObjectFromInputs(propertyDefinition);
-            }
-            if (Objects.nonNull(propertyDefinition)) {
-                if (ToscaType.isPrimitiveType(propertyDefinition.getType())) {
-                    propertyDefinition.setConstraints(org.openecomp.sdc.be.dao.utils.CollectionUtils.merge(propertyDefinition.safeGetConstraints(),
-                        dataTypeDefinitionCache.get(propertyDefinition.getType()).safeGetConstraints()));
-                    evaluateConstraintsOnProperty(propertyDefinition);
-                } else if (ToscaType.isCollectionType(propertyDefinition.getType())) {
-                    propertyDefinition.setConstraints(org.openecomp.sdc.be.dao.utils.CollectionUtils.merge(propertyDefinition.safeGetConstraints(),
-                        dataTypeDefinitionCache.get(propertyDefinition.getType()).safeGetConstraints()));
-                    evaluateConstraintsOnProperty(propertyDefinition);
-                    evaluateCollectionTypeProperties(propertyDefinition);
-                } else {
-                    setCompletePropertyName(propertyDefinition);
-                    evaluateComplexTypeProperties(propertyDefinition);
-                }
-            }
-        } else {
+        if (propertyDefinition == null || propertyDefinition.getType() == null || !dataTypeDefinitionCache.containsKey(propertyDefinition.getType())) {
             errorMessages.add("\nUnsupported datatype found for property " + getCompletePropertyName(propertyDefinition));
+            return;
+        }
+        completeInputName = "";
+        completePropertyName = new StringBuilder();
+        if (propertyDefinition instanceof InputDefinition) {
+            completeInputName = propertyDefinition.getName();
+            propertyDefinition = getPropertyDefinitionObjectFromInputs(propertyDefinition);
+        }
+        if (propertyDefinition != null) {
+            if (ToscaType.isPrimitiveType(propertyDefinition.getType())) {
+                propertyDefinition.setConstraints(org.openecomp.sdc.be.dao.utils.CollectionUtils.merge(propertyDefinition.safeGetConstraints(),
+                    dataTypeDefinitionCache.get(propertyDefinition.getType()).safeGetConstraints()));
+                evaluateConstraintsOnProperty(propertyDefinition);
+            } else if (ToscaType.isCollectionType(propertyDefinition.getType())) {
+                propertyDefinition.setConstraints(org.openecomp.sdc.be.dao.utils.CollectionUtils.merge(propertyDefinition.safeGetConstraints(),
+                    dataTypeDefinitionCache.get(propertyDefinition.getType()).safeGetConstraints()));
+                evaluateConstraintsOnProperty(propertyDefinition);
+                evaluateCollectionTypeProperties(propertyDefinition);
+            } else {
+                setCompletePropertyName(propertyDefinition);
+                evaluateComplexTypeProperties(propertyDefinition);
+            }
         }
     }
 
@@ -157,7 +154,7 @@
         List<PropertyDefinition> propertyDefinitions = dataTypeDefinitionCache.get(propertyDefinition.getType()).getProperties();
         try {
             Map<String, Object> valueMap = MapUtils
-                .emptyIfNull(ConstraintUtil.parseToCollection(propertyDefinition.getValue(), new TypeReference<Map<String, Object>>() {
+                .emptyIfNull(ConstraintUtil.parseToCollection(propertyDefinition.getValue(), new TypeReference<>() {
                 }));
             if (CollectionUtils.isEmpty(propertyDefinitions)) {
                 checkAndEvaluatePrimitiveProperty(propertyDefinition, dataTypeDefinitionCache.get(propertyDefinition.getType()));
@@ -174,13 +171,13 @@
         try {
             if (valueMap.containsKey(prop.getName())) {
                 if (ToscaType.isPrimitiveType(prop.getType())) {
-                    evaluateConstraintsOnProperty(createPropertyDefinition(prop, String.valueOf(valueMap.get(prop.getName()))));
+                    evaluateConstraintsOnProperty(copyPropertyWithNewValue(prop, String.valueOf(valueMap.get(prop.getName()))));
                 } else if (ToscaType.isCollectionType(prop.getType())) {
-                    evaluateCollectionTypeProperties(createPropertyDefinition(prop, objectMapper.writeValueAsString(valueMap.get(prop.getName()))));
+                    evaluateCollectionTypeProperties(copyPropertyWithNewValue(prop, objectMapper.writeValueAsString(valueMap.get(prop.getName()))));
                 } else {
                     completePropertyName.append(UNDERSCORE);
                     completePropertyName.append(prop.getName());
-                    evaluateComplexTypeProperties(createPropertyDefinition(prop, objectMapper.writeValueAsString(valueMap.get(prop.getName()))));
+                    evaluateComplexTypeProperties(copyPropertyWithNewValue(prop, objectMapper.writeValueAsString(valueMap.get(prop.getName()))));
                 }
             }
         } catch (IOException e) {
@@ -201,8 +198,7 @@
     private void evaluateListType(PropertyDefinition propertyDefinition) {
         try {
             String schemaType = propertyDefinition.getSchemaType();
-            List list = ConstraintUtil.parseToCollection(propertyDefinition.getValue(), new TypeReference<List<Object>>() {
-            });
+            List<Object> list = ConstraintUtil.parseToCollection(propertyDefinition.getValue(), new TypeReference<>() {});
             evaluateCollectionType(propertyDefinition, list, schemaType);
         } catch (ConstraintValueDoNotMatchPropertyTypeException e) {
             logger.debug(e.getMessage(), e);
@@ -213,8 +209,7 @@
     private void evaluateMapType(PropertyDefinition propertyDefinition) {
         try {
             String schemaType = propertyDefinition.getSchemaType();
-            Map map = ConstraintUtil.parseToCollection(propertyDefinition.getValue(), new TypeReference<Map<String, Object>>() {
-            });
+            Map<String, Object> map = ConstraintUtil.parseToCollection(propertyDefinition.getValue(), new TypeReference<>() {});
             evaluateCollectionType(propertyDefinition, map.values(), schemaType);
         } catch (ConstraintValueDoNotMatchPropertyTypeException e) {
             logger.debug(e.getMessage(), e);
@@ -222,56 +217,60 @@
         }
     }
 
-    private void evaluateCollectionPrimitiveSchemaType(PropertyDefinition propertyDefinition, Object value, String schemaType) {
-        if (Objects.nonNull(propertyDefinition.getSchema()) && propertyDefinition.getSchema().getProperty() instanceof PropertyDefinition) {
+    private void evaluateCollectionPrimitiveSchemaType(final PropertyDefinition propertyDefinition,
+                                                       final String schemaType) throws JsonProcessingException {
+        if (propertyDefinition.getSchema() != null && propertyDefinition.getSchema().getProperty() instanceof PropertyDefinition) {
             propertyDefinition.setConstraints(((PropertyDefinition) propertyDefinition.getSchema().getProperty()).getConstraints());
-            propertyDefinition.setValue(String.valueOf(value));
+            propertyDefinition.setValue(objectMapper.readValue(propertyDefinition.getValue(), String.class));
             propertyDefinition.setType(schemaType);
             evaluateConstraintsOnProperty(propertyDefinition);
         }
     }
 
-    private void evaluateCollectionType(PropertyDefinition propertyDefinition, Collection valueList, String schemaType) {
-        for (Object value : valueList) {
+    private void evaluateCollectionType(final PropertyDefinition propertyDefinition, final Collection<Object> valueList, final String schemaType) {
+        for (final Object value : valueList) {
             try {
+                final PropertyDefinition propertyDefinition1 = copyPropertyWithNewValue(propertyDefinition, objectMapper.writeValueAsString(value));
                 if (ToscaType.isPrimitiveType(schemaType)) {
-                    evaluateCollectionPrimitiveSchemaType(propertyDefinition, value, schemaType);
+                    evaluateCollectionPrimitiveSchemaType(propertyDefinition1, schemaType);
                 } else if (ToscaType.isCollectionType(schemaType)) {
-                    propertyDefinition.setValue(objectMapper.writeValueAsString(value));
-                    propertyDefinition.setType(schemaType);
-                    evaluateCollectionTypeProperties(propertyDefinition);
+                    propertyDefinition1.setType(schemaType);
+                    propertyDefinition1.setSchemaType(propertyDefinition.getSchemaProperty().getSchemaType());
+                    evaluateCollectionTypeProperties(propertyDefinition1);
                 } else {
-                    propertyDefinition.setValue(objectMapper.writeValueAsString(value));
-                    propertyDefinition.setType(schemaType);
+                    propertyDefinition1.setType(schemaType);
                     completePropertyName.append(UNDERSCORE);
-                    completePropertyName.append(propertyDefinition.getName());
-                    evaluateComplexTypeProperties(propertyDefinition);
+                    completePropertyName.append(propertyDefinition1.getName());
+                    evaluateComplexTypeProperties(propertyDefinition1);
                 }
-            } catch (IOException e) {
+            } catch (final Exception e) {
                 logger.debug(e.getMessage(), e);
                 errorMessages.add(String.format(VALUE_PROVIDED_IN_INVALID_FORMAT_FOR_PROPERTY, getCompletePropertyName(propertyDefinition)));
             }
         }
     }
 
-    private String getCompletePropertyName(PropertyDefinition propertyDefinition) {
-        return StringUtils.isNotBlank(completeInputName) ? completeInputName
-            : StringUtils.isBlank(completePropertyName) ? propertyDefinition.getName()
-                : completePropertyName + UNDERSCORE + propertyDefinition.getName();
+    private String getCompletePropertyName(final PropertyDefinition propertyDefinition) {
+        if (StringUtils.isNotBlank(completeInputName)) {
+            return completeInputName;
+        }
+
+        final String propertyName = propertyDefinition == null ? "" : propertyDefinition.getName();
+        if (StringUtils.isNotBlank(completePropertyName)) {
+            return completePropertyName + UNDERSCORE + propertyName;
+        }
+
+        return propertyName;
     }
 
-    private PropertyDefinition createPropertyDefinition(PropertyDefinition prop, String value) {
-        PropertyDefinition propertyDefinition = new PropertyDefinition();
-        propertyDefinition.setName(prop.getName());
+    private PropertyDefinition copyPropertyWithNewValue(final PropertyDefinition propertyToCopy, final String value) {
+        final var propertyDefinition = new PropertyDefinition(propertyToCopy);
         propertyDefinition.setValue(value);
-        propertyDefinition.setType(prop.getType());
-        propertyDefinition.setConstraints(prop.getConstraints());
-        propertyDefinition.setSchema(prop.getSchema());
         return propertyDefinition;
     }
 
     private boolean isValidValueConstraintPresent(List<PropertyConstraint> propertyConstraints) {
-        return propertyConstraints.stream().anyMatch(propertyConstraint -> propertyConstraint instanceof ValidValuesConstraint);
+        return propertyConstraints != null && propertyConstraints.stream().anyMatch(ValidValuesConstraint.class::isInstance);
     }
 
     private PropertyDefinition getPropertyDefinitionObjectFromInputs(PropertyDefinition property) {
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentPropertyServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentPropertyServlet.java
index fec5dd8..b411a97 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentPropertyServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentPropertyServlet.java
@@ -24,9 +24,7 @@
 import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.responses.ApiResponse;
 import io.swagger.v3.oas.annotations.servers.Server;
-import io.swagger.v3.oas.annotations.servers.Servers;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.tags.Tags;
 import java.util.List;
 import java.util.Map;
 import javax.inject.Inject;
@@ -66,8 +64,8 @@
 
 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
 @Path("/v1/catalog")
-@Tags({@Tag(name = "SDCE-2 APIs")})
-@Servers({@Server(url = "/sdc2/rest")})
+@Tag(name = "SDCE-2 APIs")
+@Server(url = "/sdc2/rest")
 @Singleton
 public class ComponentPropertyServlet extends BeGenericServlet {
 
@@ -316,7 +314,7 @@
                 return buildErrorResponse(responseFormat);
             }
             //Validate value and Constraint of property and Fetch all data types from cache
-            Either<Boolean, ResponseFormat> constraintValidatorResponse = PropertyValueConstraintValidationUtil.getInstance()
+            Either<Boolean, ResponseFormat> constraintValidatorResponse = new PropertyValueConstraintValidationUtil()
                 .validatePropertyConstraints(properties.values(), applicationDataTypeCache,
                     propertyBusinessLogic.getComponentModelByComponentId(componentId));
             if (constraintValidatorResponse.isRight()) {
@@ -328,7 +326,7 @@
                 Either<EntryData<String, PropertyDefinition>, ResponseFormat> status = propertyBusinessLogic
                     .updateComponentProperty(componentId, propertyDefinition.getUniqueId(), propertyDefinition, userId);
                 if (status.isRight()) {
-                    log.info("Failed to update Property. Reason - ", status.right().value());
+                    log.info("Failed to update Property. Reason - {}", status.right().value());
                     return buildErrorResponse(status.right().value());
                 }
                 EntryData<String, PropertyDefinition> property = status.left().value();
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtilTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtilTest.java
index a8dcf8a..c1e33a8 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtilTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtilTest.java
@@ -20,34 +20,33 @@
 
 package org.openecomp.sdc.be.datamodel.utils;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.reflect.TypeToken;
 import fj.data.Either;
-import java.io.BufferedReader;
-import java.io.File;
+import java.io.IOException;
 import java.lang.reflect.Type;
-import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
-import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.Spy;
 import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.be.model.InputDefinition;
@@ -58,7 +57,7 @@
 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
 import org.openecomp.sdc.exception.ResponseFormat;
 
-public class PropertyValueConstraintValidationUtilTest {
+class PropertyValueConstraintValidationUtilTest {
 
 	@Mock
 	ApplicationDataTypeCache applicationDataTypeCache;
@@ -72,10 +71,10 @@
 
 	private Map<String, DataTypeDefinition> dataTypeDefinitionMap;
 
-	@Before
-	public void init() {
+	@BeforeEach
+	void init() throws IOException {
 		MockitoAnnotations.openMocks(this);
-		ResponseFormatManager responseFormatManagerMock = Mockito.mock(ResponseFormatManager.class);
+		ResponseFormatManager responseFormatManagerMock = mock(ResponseFormatManager.class);
 		when(responseFormatManagerMock.getResponseFormat(any())).thenReturn(new ResponseFormat());
 		when(responseFormatManagerMock.getResponseFormat(any(), any())).thenReturn(new ResponseFormat());
 		when(responseFormatManagerMock.getResponseFormat(any(), any(), any())).thenReturn(new ResponseFormat());
@@ -85,9 +84,9 @@
 	}
 
 	@Test
-	public void primitiveValueSuccessTest() {
+	void primitiveValueSuccessTest() {
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("integer");
@@ -97,13 +96,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isLeft());
+		assertTrue(responseEither.isLeft());
 	}
 
 	@Test
-	public void primitiveValueFailTest() {
+	void primitiveValueFailTest() {
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("integer");
@@ -112,13 +111,13 @@
 		Either<Boolean, ResponseFormat> responseEither = propertyValueConstraintValidationUtil.validatePropertyConstraints(
 			Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isRight());
+		assertTrue(responseEither.isRight());
 	}
 
 	@Test
-	public void complexWithValidValueSuccessTest() {
+	void complexWithValidValueSuccessTest() {
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("org.openecomp.datatypes.heat.network.neutron.Subnet");
@@ -128,13 +127,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 					Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isLeft());
+		assertTrue(responseEither.isLeft());
 	}
 
 	@Test
-	public void complexWithValidValueFailTest() {
+	void complexWithValidValueFailTest() {
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("org.openecomp.datatypes.heat.network.neutron.Subnet");
@@ -143,13 +142,13 @@
 		Either<Boolean, ResponseFormat> responseEither = propertyValueConstraintValidationUtil
 			.validatePropertyConstraints(Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isRight());
+		assertTrue(responseEither.isRight());
 	}
 
 	@Test
-	public void complexWithListWithPrimitiveValueSuccessTest() {
+	void complexWithListWithPrimitiveValueSuccessTest() {
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("org.openecomp.datatypes.heat.network.neutron.Subnet");
@@ -159,13 +158,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isLeft());
+		assertTrue(responseEither.isLeft());
 	}
 
 	@Test
-	public void complexWithListWithPrimitiveValueFailTest() {
+	void complexWithListWithPrimitiveValueFailTest() {
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("org.openecomp.datatypes.heat.network.neutron.Subnet");
@@ -175,13 +174,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isRight());
+		assertTrue(responseEither.isRight());
 	}
 
 	@Test
-	public void complexWithMapWithPrimitiveValueSuccessTest() {
+	void complexWithMapWithPrimitiveValueSuccessTest() {
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("org.openecomp.datatypes.heat.network.neutron.Subnet");
@@ -191,13 +190,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isLeft());
+		assertTrue(responseEither.isLeft());
 	}
 
 	@Test
-	public void complexWithMapWithPrimitiveValueFailTest() {
+	void complexWithMapWithPrimitiveValueFailTest() {
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("org.openecomp.datatypes.heat.network.neutron.Subnet");
@@ -207,13 +206,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isRight());
+		assertTrue(responseEither.isRight());
 	}
 
 	@Test
-	public void inputValidValueSuccessTest() {
+	void inputValidValueSuccessTest() {
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		InputDefinition inputDefinition = new InputDefinition();
 		inputDefinition.setInputPath("propetyName#ipv6_ra_mode");
@@ -227,13 +226,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(inputDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isLeft());
+		assertTrue(responseEither.isLeft());
 	}
 
 	@Test
-	public void inputValidValueFailTest() {
+	void inputValidValueFailTest() {
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		InputDefinition inputDefinition = new InputDefinition();
 		inputDefinition.setInputPath("propetyName#ipv6_ra_mode");
@@ -246,13 +245,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(inputDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isRight());
+		assertTrue(responseEither.isRight());
 	}
 
 	@Test
-	public void serviceConsumptionValidValueSuccessTest() {
+	void serviceConsumptionValidValueSuccessTest() {
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("org.openecomp.datatypes.heat.network.neutron.Subnet");
@@ -263,12 +262,109 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isLeft());
+		assertTrue(responseEither.isLeft());
 	}
+
 	@Test
-	public void serviceConsumptionValidValueFailTest() {
+	void listOfComplexSuccessTest() {
+		when(applicationDataTypeCache.getAll(null)).thenReturn(Either.left(dataTypeDefinitionMap));
+
+		final var propertyDefinition = new PropertyDefinition();
+		final String type = "list";
+		propertyDefinition.setType(type);
+		final SchemaDefinition schemaDefinition = new SchemaDefinition();
+		final PropertyDataDefinition schemaProperty = new PropertyDataDefinition();
+		final String schemaType = "org.openecomp.datatypes.heat.network.neutron.Subnet";
+		schemaProperty.setType(schemaType);
+		schemaDefinition.setProperty(schemaProperty);
+		propertyDefinition.setSchema(schemaDefinition);
+		final String value = "[{\"ipv6_address_mode\": \"dhcpv6-stateful\"}, {\"ipv6_address_mode\": \"dhcpv6-stateless\"}]";
+		propertyDefinition.setValue(value);
+		final String name = "listOfComplex";
+		propertyDefinition.setName(name);
+
+		Either<Boolean, ResponseFormat> responseEither =
+			propertyValueConstraintValidationUtil
+				.validatePropertyConstraints(Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
+
+		assertTrue(responseEither.isLeft());
+		//original object values should not be changed
+		assertEquals(name, propertyDefinition.getName());
+		assertEquals(type, propertyDefinition.getType());
+		assertEquals(value, propertyDefinition.getValue());
+		assertEquals(schemaType, propertyDefinition.getSchemaType());
+	}
+
+	@Test
+	void listOfComplexSuccessTest1() {
+		when(applicationDataTypeCache.getAll(null)).thenReturn(Either.left(dataTypeDefinitionMap));
+
+		final var propertyDefinition = new PropertyDefinition();
+		final String type = "list";
+		propertyDefinition.setType(type);
+		final String listSchemaType = "org.openecomp.datatypes.heat.network.neutron.Subnet";
+		final PropertyDataDefinition listSchemaProperty = new PropertyDataDefinition();
+		listSchemaProperty.setType(listSchemaType);
+		final SchemaDefinition listSchemaDefinition = new SchemaDefinition();
+		listSchemaDefinition.setProperty(listSchemaProperty);
+		final PropertyDataDefinition schemaProperty = new PropertyDataDefinition();
+		schemaProperty.setSchema(listSchemaDefinition);
+		final String schemaType = "list";
+		schemaProperty.setType(schemaType);
+		final SchemaDefinition schemaDefinition = new SchemaDefinition();
+		schemaDefinition.setProperty(schemaProperty);
+		propertyDefinition.setSchema(schemaDefinition);
+		final String value = "[[{\"ipv6_address_mode\": \"dhcpv6-stateful\"}, {\"ipv6_address_mode\": \"dhcpv6-stateless\"}], [{\"ipv6_address_mode\": \"dhcpv6-stateful\"}]]";
+		propertyDefinition.setValue(value);
+		final String name = "listOfComplex";
+		propertyDefinition.setName(name);
+
+		Either<Boolean, ResponseFormat> responseEither =
+			propertyValueConstraintValidationUtil
+				.validatePropertyConstraints(Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
+
+		assertTrue(responseEither.isLeft());
+		//original object values should not be changed
+		assertEquals(name, propertyDefinition.getName());
+		assertEquals(type, propertyDefinition.getType());
+		assertEquals(value, propertyDefinition.getValue());
+		assertEquals(schemaType, propertyDefinition.getSchemaType());
+	}
+
+	@Test
+	void mapOfComplexSuccessTest() {
+		when(applicationDataTypeCache.getAll(null)).thenReturn(Either.left(dataTypeDefinitionMap));
+
+		final var propertyDefinition = new PropertyDefinition();
+		final String type = "map";
+		propertyDefinition.setType(type);
+		final SchemaDefinition schemaDefinition = new SchemaDefinition();
+		final PropertyDataDefinition schemaProperty = new PropertyDataDefinition();
+		final String schemaType = "org.openecomp.datatypes.heat.network.neutron.Subnet";
+		schemaProperty.setType(schemaType);
+		schemaDefinition.setProperty(schemaProperty);
+		propertyDefinition.setSchema(schemaDefinition);
+		final String value = "{\"key1\": {\"ipv6_address_mode\": \"dhcpv6-stateful\"}, \"key2\": {\"ipv6_address_mode\": \"dhcpv6-stateless\"}}";
+		propertyDefinition.setValue(value);
+		final String name = "mapOfComplex";
+		propertyDefinition.setName(name);
+
+		Either<Boolean, ResponseFormat> responseEither =
+			propertyValueConstraintValidationUtil.validatePropertyConstraints(
+				Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
+
+		assertTrue(responseEither.isLeft());
+		//original object values should not be changed
+		assertEquals(name, propertyDefinition.getName());
+		assertEquals(type, propertyDefinition.getType());
+		assertEquals(value, propertyDefinition.getValue());
+		assertEquals(schemaType, propertyDefinition.getSchemaType());
+	}
+
+	@Test
+	void serviceConsumptionValidValueFailTest() {
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("org.openecomp.datatypes.heat.network.neutron.Subnet");
@@ -279,13 +375,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isRight());
+		assertTrue(responseEither.isRight());
 	}
 
 	@Test
-	public void bandwidthTypeValueSuccessTest(){
+	void bandwidthTypeValueSuccessTest(){
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("onap.datatypes.partner.bandwidth");
@@ -294,13 +390,13 @@
 
 		Either<Boolean, ResponseFormat> responseEither = propertyValueConstraintValidationUtil.validatePropertyConstraints(
 			Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
-		Assert.assertTrue(responseEither.isLeft());
+		assertTrue(responseEither.isLeft());
 	}
 
 	@Test
-	public void bandwidthTypeValueFailTest(){
+	void bandwidthTypeValueFailTest(){
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("onap.datatypes.partner.bandwidth");
@@ -310,13 +406,13 @@
 		Either<Boolean, ResponseFormat> responseEither = propertyValueConstraintValidationUtil.validatePropertyConstraints(
 			Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isRight());
+		assertTrue(responseEither.isRight());
 	}
 
 	@Test
-	public void bandwidthDownstreamValueSuccessTest(){
+	void bandwidthDownstreamValueSuccessTest(){
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("onap.datatypes.partner.bandwidth");
@@ -327,13 +423,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isLeft());
+		assertTrue(responseEither.isLeft());
 	}
 
 	@Test
-	public void bandwidthDownstreamValueFailTest(){
+	void bandwidthDownstreamValueFailTest(){
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("onap.datatypes.partner.bandwidth");
@@ -344,13 +440,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isRight());
+		assertTrue(responseEither.isRight());
 	}
 
 	@Test
-	public void bandwidthUpstreamValueSuccessTest(){
+	void bandwidthUpstreamValueSuccessTest(){
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("onap.datatypes.partner.bandwidth");
@@ -361,13 +457,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isLeft());
+		assertTrue(responseEither.isLeft());
 	}
 
 	@Test
-	public void bandwidthUpstreamValueFailTest(){
+	void bandwidthUpstreamValueFailTest(){
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("onap.datatypes.partner.bandwidth");
@@ -378,13 +474,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isRight());
+		assertTrue(responseEither.isRight());
 	}
 
 	@Test
-	public void bandwidthUnitsValueSuccessTest(){
+	void bandwidthUnitsValueSuccessTest(){
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("onap.datatypes.partner.bandwidth");
@@ -395,13 +491,13 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isLeft());
+		assertTrue(responseEither.isLeft());
 	}
 
 	@Test
-	public void bandwidthUnitsValueFailTest(){
+	void bandwidthUnitsValueFailTest(){
 		Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> either = Either.left(dataTypeDefinitionMap);
-		Mockito.when(applicationDataTypeCache.getAll(null)).thenReturn(either);
+		when(applicationDataTypeCache.getAll(null)).thenReturn(either);
 
 		PropertyDefinition propertyDefinition = new PropertyDefinition();
 		propertyDefinition.setType("onap.datatypes.partner.bandwidth");
@@ -412,16 +508,16 @@
 				propertyValueConstraintValidationUtil.validatePropertyConstraints(
 						Collections.singletonList(propertyDefinition), applicationDataTypeCache, null);
 
-		Assert.assertTrue(responseEither.isRight());
+		assertTrue(responseEither.isRight());
 	}
 
-	private void createDataTypeMap() {
+	private void createDataTypeMap() throws IOException {
 		Type constraintType = new TypeToken<PropertyConstraint>() {}.getType();
 		Type typeOfHashMap = new TypeToken<Map<String, DataTypeDefinition>>() { }.getType();
 		Gson gson = new GsonBuilder().registerTypeAdapter(constraintType,
 				new PropertyOperation.PropertyConstraintDeserialiser()).create();
 
-		dataTypeDefinitionMap = gson.fromJson(readFile(), typeOfHashMap);
+		dataTypeDefinitionMap = gson.fromJson(readDataTypeDefinitionFile(), typeOfHashMap);
 
 		DataTypeDefinition dataTypeDefinition = dataTypeDefinitionMap.get("org.openecomp.datatypes.heat.network"
 				+ ".neutron.Subnet");
@@ -448,19 +544,8 @@
 		listProperty.getSchema().setProperty(definition);
 	}
 
-	private static String readFile() {
-		StringBuilder stringBuilder = new StringBuilder();
-		File file = new File(Objects.requireNonNull(
-				PropertyValueConstraintValidationUtilTest.class.getClassLoader().getResource("types/datatypes"
-						+ "/constraintTest.json")).getFile());
-		Path logFile = Paths.get(file.getAbsolutePath());
-		try (BufferedReader reader = Files.newBufferedReader(logFile, StandardCharsets.UTF_8)) {
-			reader.lines().forEach(stringBuilder::append);
-		} catch (Exception e) {
-			Assert.fail(e.getMessage());
-			e.printStackTrace();
-		}
-		return stringBuilder.toString();
+	private static String readDataTypeDefinitionFile() throws IOException {
+		return Files.readString(Paths.get("src/test/resources/types/datatypes/constraintTest.json"));
 	}
 
 }
diff --git a/catalog-be/src/test/resources/types/datatypes/constraintTest.json b/catalog-be/src/test/resources/types/datatypes/constraintTest.json
index 9a52294..83b4253 100644
--- a/catalog-be/src/test/resources/types/datatypes/constraintTest.json
+++ b/catalog-be/src/test/resources/types/datatypes/constraintTest.json
@@ -15,6 +15,38 @@
     "modificationTime": 1550136564103,
     "toscaPresentation": {}
   },
+  "list": {
+    "derivedFrom": {
+      "name": "tosca.datatypes.Root",
+      "uniqueId": "tosca.datatypes.Root.datatype",
+      "description": "The TOSCA root Data Type all other TOSCA base Data Types derive from",
+      "creationTime": 1550136563278,
+      "modificationTime": 1550136563278,
+      "toscaPresentation": {}
+    },
+    "name": "list",
+    "uniqueId": "list.datatype",
+    "derivedFromName": "tosca.datatypes.Root",
+    "creationTime": 1550136564103,
+    "modificationTime": 1550136564103,
+    "toscaPresentation": {}
+  },
+  "map": {
+    "derivedFrom": {
+      "name": "tosca.datatypes.Root",
+      "uniqueId": "tosca.datatypes.Root.datatype",
+      "description": "The TOSCA root Data Type all other TOSCA base Data Types derive from",
+      "creationTime": 1550136563278,
+      "modificationTime": 1550136563278,
+      "toscaPresentation": {}
+    },
+    "name": "map",
+    "uniqueId": "map.datatype",
+    "derivedFromName": "tosca.datatypes.Root",
+    "creationTime": 1550136564103,
+    "modificationTime": 1550136564103,
+    "toscaPresentation": {}
+  },
   "org.openecomp.datatypes.heat.network.neutron.Subnet": {
     "derivedFrom": {
       "name": "tosca.datatypes.Root",
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java
index c06df65..6e313ed 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java
@@ -46,6 +46,9 @@
 
     public PropertyDefinition(PropertyDefinition pd) {
         super(pd);
+        if (pd.getSchema() != null && pd.getSchema().getProperty() instanceof PropertyDefinition) {
+            this.getSchema().setProperty(new PropertyDefinition(pd.getSchema().getProperty()));
+        }
         setConstraints(pd.getConstraints());
     }
 
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java
index 969d986..c885dbc 100644
--- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java
@@ -84,14 +84,16 @@
         super(pr);
     }
 
-    public PropertyDataDefinition(PropertyDataDefinition propertyDataDefinition) {
+    public PropertyDataDefinition(final PropertyDataDefinition propertyDataDefinition) {
         super();
         this.setUniqueId(propertyDataDefinition.getUniqueId());
         this.setRequired(propertyDataDefinition.isRequired());
         this.setDefaultValue(propertyDataDefinition.getDefaultValue());
         this.setDefinition(propertyDataDefinition.getDefinition());
         this.setDescription(propertyDataDefinition.getDescription());
-        this.setSchema(propertyDataDefinition.getSchema());
+        if (propertyDataDefinition.getSchema() != null) {
+            this.setSchema(new SchemaDefinition(propertyDataDefinition.getSchema()));
+        }
         this.setPassword(propertyDataDefinition.isPassword());
         this.setType(propertyDataDefinition.getType());
         this.setName(propertyDataDefinition.getName());
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/SchemaDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/SchemaDefinition.java
index 1e4fc58..17e21f0 100644
--- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/SchemaDefinition.java
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/SchemaDefinition.java
@@ -20,10 +20,14 @@
 
 package org.openecomp.sdc.be.datatypes.elements;
 
-import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
-
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
 
 /**
  * Schema allows to create new types that can be used along TOSCA definitions.
@@ -45,7 +49,25 @@
         this.setDerivedFrom(derivedFrom);
         this.setConstraints(constraints);
         this.setProperties(properties);
+    }
 
+    public SchemaDefinition(final SchemaDefinition schemaDefinition) {
+        if (schemaDefinition == null) {
+            return;
+        }
+        this.derivedFrom = schemaDefinition.getDerivedFrom();
+        if (CollectionUtils.isNotEmpty(schemaDefinition.getConstraints())) {
+            this.constraints = new ArrayList<>(schemaDefinition.getConstraints());
+        }
+        if (schemaDefinition.getProperty() != null) {
+            this.property = new PropertyDataDefinition(schemaDefinition.getProperty());
+        }
+        if (MapUtils.isNotEmpty(schemaDefinition.getProperties())) {
+            this.properties = new HashMap<>();
+            for (final Entry<String, PropertyDataDefinition> propertyEntry : schemaDefinition.getProperties().entrySet()) {
+                this.properties.put(propertyEntry.getKey(), new PropertyDataDefinition(propertyEntry.getValue()));
+            }
+        }
     }
 
     public String getDerivedFrom() {