Add workflow node template enrichment 02/82502/1
authorMuthuramalingam, Brinda Santh <brindasanth@in.ibm.com>
Fri, 15 Mar 2019 21:07:19 +0000 (17:07 -0400)
committerMuthuramalingam, Brinda Santh <brindasanth@in.ibm.com>
Fri, 15 Mar 2019 21:07:19 +0000 (17:07 -0400)
Change-Id: I15c2db6ab81bae2176d1606157f13416c1fac660
Issue-ID: CCSDK-1168
Signed-off-by: Muthuramalingam, Brinda Santh <brindasanth@in.ibm.com>
19 files changed:
components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/artifact_types.json [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/component_invoke.json [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/data_types.json [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/node_types.json [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/policy_types.json [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/relationship_types.json [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/resources_definition_types.json [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/component_invoke/TOSCA-Metadata/TOSCA.meta [new file with mode: 0644]
components/model-catalog/definition-type/starter-type/node_type/component-netconf-executor.json
components/model-catalog/definition-type/starter-type/node_type/component-sample-executor.json [new file with mode: 0644]
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintContext.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintRuntimeService.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintRuntimeUtils.kt
ms/controllerblueprints/modules/blueprint-validation/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/validation/BluePrintNodeTemplateValidatorImpl.kt
ms/controllerblueprints/modules/blueprint-validation/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/validation/BluePrintWorkflowValidatorImpl.kt
ms/controllerblueprints/modules/blueprint-validation/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/validation/BluePrintDesignTimeValidatorServiceTest.kt
ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/enhancer/BluePrintWorkflowEnhancerImpl.kt
ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/enhancer/ResourceDefinitionEnhancerService.kt
ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt

diff --git a/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/artifact_types.json b/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/artifact_types.json
new file mode 100644 (file)
index 0000000..eadc848
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "artifact_types" : { }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/component_invoke.json b/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/component_invoke.json
new file mode 100644 (file)
index 0000000..eeb9815
--- /dev/null
@@ -0,0 +1,88 @@
+{
+  "tosca_definitions_version": "controller_blueprint_1_0_0",
+  "metadata": {
+    "template_author": "Brinda Santh <brindasanth@in.ibm.com>",
+    "template_name": "component_invoke",
+    "template_version": "1.0.0",
+    "template_tags": "brinda, component_invoke"
+  },
+  "imports": [
+    {
+      "file": "Definitions/data_types.json"
+    },
+    {
+      "file": "Definitions/relationship_types.json"
+    },
+    {
+      "file": "Definitions/artifact_types.json"
+    },
+    {
+      "file": "Definitions/node_types.json"
+    },
+    {
+      "file": "Definitions/policy_types.json"
+    }
+  ],
+  "topology_template": {
+    "workflows": {
+      "component-invoke": {
+        "steps": {
+          "activate-process": {
+            "description": "Sample Component Invocation flow",
+            "target": "sample-component",
+            "activities": [
+              {
+                "call_operation": "sample-component"
+              }
+            ]
+          }
+        },
+        "inputs": {
+          "request-id": {
+            "required": true,
+            "type": "string"
+          },
+          "action-name": {
+            "required": true,
+            "type": "string"
+          },
+          "scope-type": {
+            "required": true,
+            "type": "string"
+          },
+          "hostname": {
+            "required": true,
+            "type": "string"
+          }
+        }
+      }
+    },
+    "node_templates": {
+      "sample-component": {
+        "type": "component-sample-executor",
+        "interfaces": {
+          "ComponentSampleExecutor": {
+            "operations": {
+              "process": {
+                "inputs": {
+                  "sample-property": "sample-value",
+                  "sample-list-property": [
+                    "json-parser-service"
+                  ],
+                  "dynamic-properties": {
+                    "prop1": "prop1-value",
+                    "prop2": "prop2-value"
+                  }
+                },
+                "outputs": {
+                  "response-data": "",
+                  "status": ""
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/data_types.json b/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/data_types.json
new file mode 100644 (file)
index 0000000..8c304c4
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "data_types" : { }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/node_types.json b/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/node_types.json
new file mode 100644 (file)
index 0000000..1e02cef
--- /dev/null
@@ -0,0 +1,54 @@
+{
+  "node_types": {
+    "component-sample-executor": {
+      "description": "This is Sample Component API",
+      "version": "1.0.0",
+      "interfaces": {
+        "ComponentSampleExecutor": {
+          "operations": {
+            "process": {
+              "inputs": {
+                "sample-property": {
+                  "description": "Sample Property.",
+                  "required": true,
+                  "type": "string"
+                },
+                "sample-list-property": {
+                  "description": "Dependent Step Components NodeTemplate name.",
+                  "required": true,
+                  "type": "list",
+                  "entry_schema": {
+                    "type": "string"
+                  }
+                },
+                "dynamic-properties": {
+                  "description": "Dynamic Json Content or DSL Json reference.",
+                  "required": false,
+                  "type": "json"
+                }
+              },
+              "outputs": {
+                "response-data": {
+                  "description": "Execution Response Data in JSON format.",
+                  "required": false,
+                  "type": "string"
+                },
+                "status": {
+                  "description": "Status of the Component Execution ( success or failure )",
+                  "required": true,
+                  "type": "string"
+                }
+              }
+            }
+          }
+        }
+      },
+      "derived_from": "tosca.nodes.Component"
+    },
+    "tosca.nodes.Component": {
+      "description": "This is default Component Node",
+      "version": "1.0.0",
+      "derived_from": "tosca.nodes.Root"
+    }
+  }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/policy_types.json b/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/policy_types.json
new file mode 100644 (file)
index 0000000..1e44cc7
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "policy_types" : { }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/relationship_types.json b/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/relationship_types.json
new file mode 100644 (file)
index 0000000..4ddd7a5
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "relationship_types" : { }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/resources_definition_types.json b/components/model-catalog/blueprint-model/test-blueprint/component_invoke/Definitions/resources_definition_types.json
new file mode 100644 (file)
index 0000000..6f31cf5
--- /dev/null
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/component_invoke/TOSCA-Metadata/TOSCA.meta b/components/model-catalog/blueprint-model/test-blueprint/component_invoke/TOSCA-Metadata/TOSCA.meta
new file mode 100644 (file)
index 0000000..a7c130a
--- /dev/null
@@ -0,0 +1,5 @@
+TOSCA-Meta-File-Version: 1.0.0
+CSAR-Version: 1.0
+Created-By: Brinda Santh <brindasanth@in.ibm.com>
+Entry-Definitions: Definitions/component_invoke.json
+Template-Tags: Brinda Santh, component_invoke
\ No newline at end of file
index 7e429c0..3233d21 100644 (file)
                 }\r
               ]\r
             },\r
-            "dynamic-properties": {
-              "description": "Resolvable dynamic property.",
-              "required": false,
-              "type": "string"
-            },
             "script-class-reference": {\r
               "description": "Kotlin Script class name or jython script name.",\r
               "required": true,\r
diff --git a/components/model-catalog/definition-type/starter-type/node_type/component-sample-executor.json b/components/model-catalog/definition-type/starter-type/node_type/component-sample-executor.json
new file mode 100644 (file)
index 0000000..68b3ebd
--- /dev/null
@@ -0,0 +1,45 @@
+{
+  "description": "This is Sample Component API",
+  "version": "1.0.0",
+  "interfaces": {
+    "ComponentSampleExecutor": {
+      "operations": {
+        "process": {
+          "inputs": {
+            "sample-property": {
+              "description": "Sample Property.",
+              "required": true,
+              "type": "string"
+            },
+            "sample-list-property": {
+              "required": true,
+              "description": "Dependent Step Components NodeTemplate name.",
+              "type": "list",
+              "entry_schema": {
+                "type": "string"
+              }
+            },
+            "dynamic-properties": {
+              "description": "Dynamic Json Content or DSL Json reference.",
+              "required": false,
+              "type": "json"
+            }
+          },
+          "outputs": {
+            "response-data": {
+              "description": "Execution Response Data in JSON format.",
+              "required": false,
+              "type": "string"
+            },
+            "status": {
+              "description": "Status of the Component Execution ( success or failure )",
+              "required": true,
+              "type": "string"
+            }
+          }
+        }
+      }
+    }
+  },
+  "derived_from": "tosca.nodes.Component"
+}
\ No newline at end of file
index e2211f7..ca86c96 100644 (file)
@@ -44,15 +44,15 @@ class BluePrintContext(val serviceTemplate: ServiceTemplate) {
      */
     var entryDefinition = ""
 
-    val imports: List<ImportDefinition>? = serviceTemplate.imports
+    fun imports(): List<ImportDefinition>? = serviceTemplate.imports
 
-    val dslDefinitions = serviceTemplate.dslDefinitions
+    fun dslDefinitions() = serviceTemplate.dslDefinitions
 
     val metadata: MutableMap<String, String>? = serviceTemplate.metadata
 
-    val dataTypes: MutableMap<String, DataType>? = serviceTemplate.dataTypes
+    fun dataTypes(): MutableMap<String, DataType>? = serviceTemplate.dataTypes
 
-    val inputs: MutableMap<String, PropertyDefinition>? = serviceTemplate.topologyTemplate?.inputs
+    fun inputs(): MutableMap<String, PropertyDefinition>? = serviceTemplate.topologyTemplate?.inputs
 
     fun blueprintJson(pretty: Boolean = false): String = print("json", pretty)
 
@@ -70,9 +70,9 @@ class BluePrintContext(val serviceTemplate: ServiceTemplate) {
             ?: throw BluePrintException("could't get template author from meta data")
 
     // Workflow
-    val workflows: MutableMap<String, Workflow>? = serviceTemplate.topologyTemplate?.workflows
+    fun workflows(): MutableMap<String, Workflow>? = serviceTemplate.topologyTemplate?.workflows
 
-    fun workflowByName(workFlowName: String): Workflow = workflows?.get(workFlowName)
+    fun workflowByName(workFlowName: String): Workflow = workflows()?.get(workFlowName)
             ?: throw BluePrintException("could't get workflow($workFlowName)")
 
     fun workflowInputs(workFlowName: String) = workflowByName(workFlowName).inputs
@@ -99,27 +99,27 @@ class BluePrintContext(val serviceTemplate: ServiceTemplate) {
     }
 
     // DSL
-    fun dslPropertiesByName(name: String): JsonNode = dslDefinitions?.get(name)
+    fun dslPropertiesByName(name: String): JsonNode = dslDefinitions()?.get(name)
             ?: throw BluePrintException("could't get policy type for the dsl($name)")
 
     // Data Type
-    fun dataTypeByName(name: String): DataType? = dataTypes?.get(name)
+    fun dataTypeByName(name: String): DataType? = dataTypes()?.get(name)
 
     // Artifact Type
-    val artifactTypes: MutableMap<String, ArtifactType>? = serviceTemplate.artifactTypes
+    fun artifactTypes(): MutableMap<String, ArtifactType>? = serviceTemplate.artifactTypes
 
     // Policy Types
-    val policyTypes: MutableMap<String, PolicyType>? = serviceTemplate.policyTypes
+    fun policyTypes(): MutableMap<String, PolicyType>? = serviceTemplate.policyTypes
 
-    fun policyTypeByName(policyName: String) = policyTypes?.get(policyName)
+    fun policyTypeByName(policyName: String) = policyTypes()?.get(policyName)
             ?: throw BluePrintException("could't get policy type for the name($policyName)")
 
     fun policyTypesDerivedFrom(name: String): MutableMap<String, PolicyType>? {
-        return policyTypes?.filterValues { policyType -> policyType.derivedFrom == name }?.toMutableMap()
+        return policyTypes()?.filterValues { policyType -> policyType.derivedFrom == name }?.toMutableMap()
     }
 
     fun policyTypesTarget(target: String): MutableMap<String, PolicyType>? {
-        return policyTypes?.filterValues { it.targets.contains(target) }?.toMutableMap()
+        return policyTypes()?.filterValues { it.targets.contains(target) }?.toMutableMap()
     }
 
     fun policyTypesTargetNDerivedFrom(target: String, derivedFrom: String): MutableMap<String, PolicyType>? {
@@ -129,14 +129,14 @@ class BluePrintContext(val serviceTemplate: ServiceTemplate) {
     }
 
     // Node Type Methods
-    val nodeTypes: MutableMap<String, NodeType>? = serviceTemplate.nodeTypes
+    fun nodeTypes(): MutableMap<String, NodeType>? = serviceTemplate.nodeTypes
 
     fun nodeTypeByName(name: String): NodeType =
-            nodeTypes?.get(name)
+            nodeTypes()?.get(name)
                     ?: throw BluePrintException("could't get node type for the name($name)")
 
     fun nodeTypeDerivedFrom(name: String): MutableMap<String, NodeType>? {
-        return nodeTypes?.filterValues { nodeType -> nodeType.derivedFrom == name }?.toMutableMap()
+        return nodeTypes()?.filterValues { nodeType -> nodeType.derivedFrom == name }?.toMutableMap()
     }
 
     fun nodeTypeInterface(nodeTypeName: String, interfaceName: String): InterfaceDefinition {
@@ -163,13 +163,13 @@ class BluePrintContext(val serviceTemplate: ServiceTemplate) {
     }
 
     // Node Template Methods
-    val nodeTemplates: MutableMap<String, NodeTemplate>? = serviceTemplate.topologyTemplate?.nodeTemplates
+    fun nodeTemplates(): MutableMap<String, NodeTemplate>? = serviceTemplate.topologyTemplate?.nodeTemplates
 
     fun nodeTemplateByName(name: String): NodeTemplate =
-            nodeTemplates?.get(name) ?: throw BluePrintException("could't get node template for the name($name)")
+            nodeTemplates()?.get(name) ?: throw BluePrintException("could't get node template for the name($name)")
 
     fun nodeTemplateForNodeType(name: String): MutableMap<String, NodeTemplate>? {
-        return nodeTemplates?.filterValues { nodeTemplate -> nodeTemplate.type == name }?.toMutableMap()
+        return nodeTemplates()?.filterValues { nodeTemplate -> nodeTemplate.type == name }?.toMutableMap()
     }
 
     fun nodeTemplateNodeType(nodeTemplateName: String): NodeType {
index c582807..c16d1ec 100644 (file)
@@ -488,7 +488,7 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
 
     override fun assignInputs(jsonNode: JsonNode) {
         log.info("assignInputs from input JSON ({})", jsonNode.toString())
-        bluePrintContext.inputs?.forEach { propertyName, property ->
+        bluePrintContext.inputs()?.forEach { propertyName, property ->
             val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)
                     ?: NullNode.getInstance()
             setInputValue(propertyName, property, valueNode)
index c37d8ee..d20fc55 100644 (file)
@@ -49,7 +49,7 @@ object BluePrintRuntimeUtils {
 
     fun assignInputs(bluePrintContext: BluePrintContext, jsonNode: JsonNode, context: MutableMap<String, JsonNode>) {
         log.info("assignInputs from input JSON ({})", jsonNode.toString())
-        bluePrintContext.inputs?.forEach { propertyName, _ ->
+        bluePrintContext.inputs()?.forEach { propertyName, _ ->
             val valueNode: JsonNode = jsonNode.at("/".plus(propertyName)) ?: NullNode.getInstance()
 
             val path = BluePrintConstants.PATH_INPUTS.plus(BluePrintConstants.PATH_DIVIDER).plus(propertyName)
index ded1f38..601ba4f 100644 (file)
@@ -247,6 +247,8 @@ open class BluePrintNodeTemplateValidatorImpl(private val bluePrintTypeValidator
         if (BluePrintTypes.validPrimitiveTypes().contains(propertyType)) {
             isValid = JacksonUtils.checkJsonNodeValueOfPrimitiveType(propertyType, propertyAssignment)
 
+        } else if (BluePrintTypes.validComplexTypes().contains(propertyType)) {
+            isValid = true
         } else if (BluePrintTypes.validCollectionTypes().contains(propertyType)) {
 
             val entrySchemaType = propertyDefinition.entrySchema?.type
index 851a7c6..519358b 100644 (file)
@@ -58,9 +58,10 @@ open class BluePrintWorkflowValidatorImpl(private val bluePrintTypeValidatorServ
 
                     val nodeTypeDerivedFrom = bluePrintRuntimeService.bluePrintContext().nodeTemplateNodeType(it).derivedFrom
 
-                    check(nodeTypeDerivedFrom == BluePrintConstants.MODEL_TYPE_NODE_DG) {
-                        "NodeType(${nodeTemplate.type}) derived from is '$nodeTypeDerivedFrom', Expected is " +
-                                "'${BluePrintConstants.MODEL_TYPE_NODE_DG}'"
+                    check(nodeTypeDerivedFrom == BluePrintConstants.MODEL_TYPE_NODE_DG
+                            || nodeTypeDerivedFrom == BluePrintConstants.MODEL_TYPE_NODE_COMPONENT) {
+                        "NodeType(${nodeTemplate.type}) derived from is '$nodeTypeDerivedFrom', Expected " +
+                                "'${BluePrintConstants.MODEL_TYPE_NODE_DG}' or '${BluePrintConstants.MODEL_TYPE_NODE_COMPONENT}'"
                     }
                 } catch (e: Exception) {
                     bluePrintRuntimeService.getBluePrintError()
index 3fc918e..d844d1e 100644 (file)
@@ -90,7 +90,9 @@ class BluePrintDesignTimeValidatorServiceTest {
         workflowValidator.validate(bluePrintRuntime, workflowName, workflow)
 
         assertEquals(1, bluePrintRuntime.getBluePrintError().errors.size)
-        assertEquals("Failed to validate Workflow(resource-assignment)'s step(test)'s definition : resource-assignment/steps/test : NodeType(TestNodeType) derived from is 'tosca.nodes.TEST', Expected is 'tosca.nodes.DG'", bluePrintRuntime.getBluePrintError().errors[0])
+        assertEquals("Failed to validate Workflow(resource-assignment)'s step(test)'s definition : " +
+                "resource-assignment/steps/test : NodeType(TestNodeType) derived from is 'tosca.nodes.TEST', " +
+                "Expected 'tosca.nodes.DG' or 'tosca.nodes.Component'", bluePrintRuntime.getBluePrintError().errors[0])
     }
 
     @Test
index 9fbf091..fc9ee50 100644 (file)
@@ -82,8 +82,27 @@ open class BluePrintWorkflowEnhancerImpl(private val bluePrintRepoService: BlueP
 
     private fun enhanceStepTargets(name: String, workflow: Workflow) {
 
-        // Get the first Step Target NodeTemplate name( Since that is the DG Node Template)
-        val dgNodeTemplateName = bluePrintContext.workflowFirstStepNodeTemplate(name)
+        // Get the first Step Target NodeTemplate name( It may be Component or DG Node Template)
+        val firstNodeTemplateName = bluePrintContext.workflowFirstStepNodeTemplate(name)
+
+        val derivedFrom = bluePrintContext.nodeTemplateNodeType(firstNodeTemplateName).derivedFrom
+
+        when {
+            derivedFrom.startsWith(BluePrintConstants.MODEL_TYPE_NODE_COMPONENT, true) -> {
+                // DO Nothing
+            }
+            derivedFrom.startsWith(BluePrintConstants.MODEL_TYPE_NODE_DG, true) -> {
+                enhanceDGStepTargets(name, workflow, firstNodeTemplateName)
+            }
+            else -> {
+                throw BluePrintProcessorException("couldn't execute workflow($name) step mapped " +
+                        "to node template($firstNodeTemplateName) derived from($derivedFrom)")
+            }
+        }
+
+    }
+
+    private fun enhanceDGStepTargets(name: String, workflow: Workflow, dgNodeTemplateName: String) {
 
         val dgNodeTemplate = bluePrintContext.nodeTemplateByName(dgNodeTemplateName)
 
index 6171687..816b356 100644 (file)
@@ -75,7 +75,7 @@ class ResourceDefinitionEnhancerServiceImpl(private val resourceDefinitionRepoSe
     // Get all the Mapping files from all node templates.
     private fun getAllResourceMappingFiles(blueprintContext: BluePrintContext): List<String>? {
 
-        return blueprintContext.nodeTemplates?.mapNotNull { nodeTemplateMap ->
+        return blueprintContext.nodeTemplates()?.mapNotNull { nodeTemplateMap ->
 
             // Return only Mapping Artifact File Names
             nodeTemplateMap.value.artifacts?.filter { artifactDefinitionMap ->
index 919d202..48183f4 100644 (file)
@@ -64,30 +64,34 @@ class BluePrintEnhancerServiceImplTest {
     fun testEnhancementAndValidation() {
 
         val basePath = "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration"
-
-        val targetPath = Paths.get("target", "bp-enhance").toUri().path
-        
-        val bluePrintContext = bluePrintEnhancerService.enhance(basePath, targetPath)
-        Assert.assertNotNull("failed to get blueprintContext ", bluePrintContext)
-
-        // Validate the Generated BluePrints
-        val valid = bluePrintValidatorService.validateBluePrints(targetPath)
-        Assert.assertTrue("blueprint validation failed ", valid)
+        testComponentInvokeEnhancementAndValidation(basePath, "base-enhance")
     }
 
     @Test
     @Throws(Exception::class)
-    fun testEnhancementAndValidation2() {
+    fun testComponentInvokeEnhancementAndValidation() {
+        val basePath = "./../../../../components/model-catalog/blueprint-model/test-blueprint/component_invoke"
+        testComponentInvokeEnhancementAndValidation(basePath, "component-enhance")
+    }
 
+    @Test
+    @Throws(Exception::class)
+    fun testGoldenEnhancementAndValidation() {
         val basePath = "./../../../../components/model-catalog/blueprint-model/test-blueprint/golden"
+        testComponentInvokeEnhancementAndValidation(basePath, "golden-enhance")
+    }
 
-        val targetPath = Paths.get("target", "bp-enhance").toUri().path
+
+    private fun testComponentInvokeEnhancementAndValidation(basePath: String, targetDirName: String) {
+
+        val targetPath = Paths.get("target", targetDirName).toUri().path
 
         val bluePrintContext = bluePrintEnhancerService.enhance(basePath, targetPath)
         Assert.assertNotNull("failed to get blueprintContext ", bluePrintContext)
 
         // Validate the Generated BluePrints
         val valid = bluePrintValidatorService.validateBluePrints(targetPath)
-        Assert.assertTrue("blueprint validation failed ", valid)
+        Assert.assertTrue("blueprint($basePath) validation failed ", valid)
     }
+
 }
\ No newline at end of file