import org.onap.ccsdk.apps.controllerblueprints.core.data.*\r
 import com.att.eelf.configuration.EELFLogger\r
 import com.att.eelf.configuration.EELFManager\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils\r
 import java.io.Serializable\r
 \r
 /**\r
 \r
     @Throws(BluePrintException::class)\r
     override fun validateBlueprint(bluePrintContext: BluePrintContext, properties: MutableMap<String, Any>) {\r
-        validateBlueprint(bluePrintContext.serviceTemplate,properties)\r
+        validateBlueprint(bluePrintContext.serviceTemplate, properties)\r
     }\r
 \r
     @Throws(BluePrintException::class)\r
         paths.add("nodeTypes")\r
         nodeTypes.forEach { nodeTypeName, nodeType ->\r
             // Validate Single Node Type\r
-            validateNodeType(nodeTypeName,nodeType)\r
+            validateNodeType(nodeTypeName, nodeType)\r
         }\r
         paths.removeAt(paths.lastIndex)\r
     }\r
         message.appendln("--> Node Type :" + paths.joinToString(separator))\r
         val derivedFrom: String = nodeType.derivedFrom\r
         //Check Derived From\r
-        checkValidNodeTypesDerivedFrom(derivedFrom)\r
+        checkValidNodeTypesDerivedFrom(nodeTypeName, derivedFrom)\r
 \r
         nodeType.properties?.let { validatePropertyDefinitions(nodeType.properties!!) }\r
         nodeType.interfaces?.let { validateInterfaceDefinitions(nodeType.interfaces!!) }\r
         paths.removeAt(paths.lastIndex)\r
     }\r
 \r
+    @Throws(BluePrintException::class)\r
+    open fun checkValidNodeTypesDerivedFrom(nodeTypeName: String, derivedFrom: String) {\r
+        check(BluePrintTypes.validNodeTypeDerivedFroms.contains(derivedFrom)) {\r
+            throw BluePrintException(format("Failed to get node type ({})'s  derived from({}) definition ", nodeTypeName, derivedFrom))\r
+        }\r
+    }\r
+\r
     @Throws(BluePrintException::class)\r
     open fun validateTopologyTemplate(topologyTemplate: TopologyTemplate) {\r
         paths.add("topology")\r
     }\r
 \r
     @Throws(BluePrintException::class)\r
-    open fun validateNodeTemplate(nodeTemplateName : String, nodeTemplate: NodeTemplate) {\r
+    open fun validateNodeTemplate(nodeTemplateName: String, nodeTemplate: NodeTemplate) {\r
         paths.add(nodeTemplateName)\r
         message.appendln("---> Node Template :" + paths.joinToString(separator))\r
         val type: String = nodeTemplate.type\r
         paths.removeAt(paths.lastIndex)\r
     }\r
 \r
+    @Throws(BluePrintException::class)\r
+    open fun validateArtifactDefinitions(artifacts: MutableMap<String, ArtifactDefinition>) {\r
+        paths.add("artifacts")\r
+        artifacts.forEach { artifactDefinitionName, artifactDefinition ->\r
+            paths.add(artifactDefinitionName)\r
+            message.appendln("Validating artifact " + paths.joinToString(separator))\r
+            val type: String = artifactDefinition.type\r
+                    ?: throw BluePrintException("type is missing for artifact definition :" + artifactDefinitionName)\r
+            // Check Artifact Type\r
+            checkValidArtifactType(artifactDefinitionName, type)\r
+\r
+            val file: String = artifactDefinition.file\r
+                    ?: throw BluePrintException(format("file is missing for artifact definition : {}", artifactDefinitionName))\r
+\r
+            paths.removeAt(paths.lastIndex)\r
+        }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
     @Throws(BluePrintException::class)\r
     open fun validateWorkFlows(workflows: MutableMap<String, Workflow>) {\r
         paths.add("workflows")\r
     }\r
 \r
     @Throws(BluePrintException::class)\r
-    open fun validateWorkFlow(workflowName:String, workflow: Workflow) {\r
+    open fun validateWorkFlow(workflowName: String, workflow: Workflow) {\r
         paths.add(workflowName)\r
         message.appendln("---> Workflow :" + paths.joinToString(separator))\r
         // Step Validation Start\r
         properties.forEach { propertyName, propertyAssignment ->\r
             val propertyDefinition: PropertyDefinition = nodeTypeProperties[propertyName]\r
                     ?: throw BluePrintException(format("failed to get definition for the property ({})", propertyName))\r
-            // Check and Validate if Expression Node\r
-            val expressionData = BluePrintExpressionService.getExpressionData(propertyAssignment)\r
-            if (!expressionData.isExpression) {\r
-                checkPropertyValue(propertyDefinition, propertyAssignment)\r
-            }\r
+\r
+            validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)\r
+\r
         }\r
     }\r
 \r
     @Throws(BluePrintException::class)\r
-    open fun validateArtifactDefinitions(artifacts: MutableMap<String, ArtifactDefinition>) {\r
-        paths.add("artifacts")\r
-        artifacts.forEach { artifactName, artifactDefinition ->\r
-            paths.add(artifactName)\r
-            message.appendln("Validating artifact " + paths.joinToString(separator))\r
-            val type: String = artifactDefinition.type\r
-                    ?: throw BluePrintException("type is missing for artifact definition :" + artifactName)\r
-            // Check Artifact Type\r
-            checkValidArtifactType(type)\r
-\r
-            val file: String = artifactDefinition.file\r
-                    ?: throw BluePrintException(format("file is missing for artifact definition : {}", artifactName))\r
-\r
-            paths.removeAt(paths.lastIndex)\r
+    open fun validatePropertyAssignment(propertyName: String, propertyDefinition: PropertyDefinition,\r
+                                        propertyAssignment: JsonNode) {\r
+        // Check and Validate if Expression Node\r
+        val expressionData = BluePrintExpressionService.getExpressionData(propertyAssignment)\r
+        if (!expressionData.isExpression) {\r
+            checkPropertyValue(propertyName, propertyDefinition, propertyAssignment)\r
         }\r
-        paths.removeAt(paths.lastIndex)\r
     }\r
 \r
     @Throws(BluePrintException::class)\r
     }\r
 \r
     @Throws(BluePrintException::class)\r
-    open fun checkValidNodeType(nodeType : String) {\r
+    open fun checkValidArtifactType(artifactDefinitionName: String, artifactTypeName: String) {\r
+\r
+        val artifactType = serviceTemplate.artifactTypes?.get(artifactTypeName)\r
+                ?: throw BluePrintException(format("Failed to artifact type for artifact definition : {}", artifactDefinitionName))\r
 \r
+        checkValidArtifactTypeDerivedFrom(artifactTypeName, artifactType.derivedFrom)\r
     }\r
 \r
     @Throws(BluePrintException::class)\r
-    open fun checkValidArtifactType(artifactType: String) {\r
-\r
-        serviceTemplate.artifactTypes?.containsKey(artifactType)\r
-                ?: throw BluePrintException(format("Failed to node type definition for artifact definition : {}", artifactType))\r
+    open fun checkValidArtifactTypeDerivedFrom(artifactTypeName: String, derivedFrom: String) {\r
+        check(BluePrintTypes.validArtifactTypeDerivedFroms.contains(derivedFrom)) {\r
+            throw BluePrintException(format("Failed to get artifact type ({})'s  derived from({}) definition ", artifactTypeName, derivedFrom))\r
+        }\r
     }\r
 \r
     @Throws(BluePrintException::class)\r
-    open fun checkValidNodeTypesDerivedFrom(derivedFrom: String) {\r
-\r
+    open fun checkValidDataTypeDerivedFrom(dataTypeName: String, derivedFrom: String) {\r
+        check(BluePrintTypes.validDataTypeDerivedFroms.contains(derivedFrom)) {\r
+            throw BluePrintException(format("Failed to get data type ({})'s  derived from({}) definition ", dataTypeName, derivedFrom))\r
+        }\r
     }\r
 \r
-    private fun checkPropertyValue(propertyDefinition: PropertyDefinition, jsonNode: JsonNode) {\r
-        //log.info("validating path ({}), Property {}, value ({})", paths, propertyDefinition, jsonNode)\r
-    }\r
+    open fun checkPropertyValue(propertyName: String, propertyDefinition: PropertyDefinition, propertyAssignment: JsonNode) {\r
+        val propertyType = propertyDefinition.type\r
+        val isValid: Boolean\r
+\r
+        if (BluePrintTypes.validPrimitiveTypes().contains(propertyType)) {\r
+            isValid = JacksonUtils.checkJsonNodeValueOfPrimitiveType(propertyType, propertyAssignment)\r
+\r
+        } else if (BluePrintTypes.validCollectionTypes().contains(propertyType)) {\r
+\r
+            isValid = JacksonUtils.checkJsonNodeValueOfCollectionType(propertyType, propertyAssignment)\r
+            val entrySchemaType = propertyDefinition.entrySchema?.type\r
+                    ?: throw BluePrintException(format("Failed to get Entry Schema type for the collection property ({})", propertyName))\r
+\r
+            if (!BluePrintTypes.validPropertyTypes().contains(entrySchemaType)) {\r
+                checkPropertyDataType(entrySchemaType, propertyName)\r
+            }\r
 \r
-    private fun checkPropertyDataType(dataType: String, propertyName: String): Boolean {\r
-        if (checkDataType(dataType)) {\r
-            return true\r
         } else {\r
-            throw BluePrintException(format("Data type ({}) for the property ({}) not found", dataType, propertyName))\r
+            checkPropertyDataType(propertyType, propertyName)\r
+            isValid = true\r
+        }\r
+\r
+        check(isValid) {\r
+            throw BluePrintException(format("property({}) defined of type({}) is not compatable with the value ({})",\r
+                    propertyName, propertyType, propertyAssignment))\r
         }\r
     }\r
 \r
+    private fun checkPropertyDataType(dataType: String, propertyName: String) {\r
+\r
+        val dataType = serviceTemplate.dataTypes?.get(dataType)\r
+                ?: throw BluePrintException(format("Data type ({}) for the property ({}) not found", dataType, propertyName))\r
+\r
+        checkValidDataTypeDerivedFrom(propertyName, dataType.derivedFrom)\r
+\r
+    }\r
+\r
     private fun checkPrimitiveOrComplex(dataType: String, propertyName: String): Boolean {\r
         if (BluePrintTypes.validPrimitiveTypes().contains(dataType) || checkDataType(dataType)) {\r
             return true\r
         return serviceTemplate.dataTypes?.containsKey(key) ?: false\r
     }\r
 \r
-    private fun checkNodeType(key: String): Boolean {\r
-        return serviceTemplate.nodeTypes?.containsKey(key) ?: false\r
-    }\r
-\r
 }
\ No newline at end of file