Add support for workflow validation

Also, add support for mock in Kotlin using
https://mockk.io/

Change-Id: Ia85e1180e09e9d08a02de515b1cc4158c3bccd5c
Issue-ID: CCSDK-717
Signed-off-by: Alexis de Talhouët <adetalhouet89@gmail.com>
diff --git a/components/core/pom.xml b/components/core/pom.xml
index 8b6c524..631ee00 100644
--- a/components/core/pom.xml
+++ b/components/core/pom.xml
@@ -52,11 +52,17 @@
             <groupId>org.yaml</groupId>

             <artifactId>snakeyaml</artifactId>

         </dependency>

+        <!--Testing dependencies-->
         <dependency>

             <groupId>org.jetbrains.kotlin</groupId>

             <artifactId>kotlin-test-junit</artifactId>

             <scope>test</scope>

         </dependency>

+        <dependency>
+            <groupId>io.mockk</groupId>
+            <artifactId>mockk</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>

 

 </project>

diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BluePrintModel.kt b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BluePrintModel.kt
index 9767b2e..663c1fe 100644
--- a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BluePrintModel.kt
+++ b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BluePrintModel.kt
@@ -502,7 +502,7 @@
 A Node Template specifies the occurrence of a manageable software component as part of an application’s topology model which is defined in a TOSCA Service Template.  A Node template is an instance of a specified Node Type and can provide customized properties, constraints or operations which override the defaults provided by its Node Type and its implementations.

  */

 

-class NodeTemplate {

+open class NodeTemplate {
     @get:JsonIgnore

     var id: String? = null

     var description: String? = null

diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintContext.kt b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintContext.kt
index bc1f4b4..1a6d096 100644
--- a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintContext.kt
+++ b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintContext.kt
@@ -148,7 +148,7 @@
     val 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()

diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/validation/BluePrintWorkflowValidatorImpl.kt b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/validation/BluePrintWorkflowValidatorImpl.kt
index 1a138c3..f55449e 100644
--- a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/validation/BluePrintWorkflowValidatorImpl.kt
+++ b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/validation/BluePrintWorkflowValidatorImpl.kt
@@ -19,7 +19,10 @@
 import com.att.eelf.configuration.EELFLogger
 import com.att.eelf.configuration.EELFManager
 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
+import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeTemplate
 import org.onap.ccsdk.apps.controllerblueprints.core.data.Workflow
+import org.onap.ccsdk.apps.controllerblueprints.core.format
 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintTypeValidatorService
 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintWorkflowValidator
 import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintRuntimeService
@@ -42,14 +45,35 @@
 
         // Step Validation Start
         paths.add("steps")
-        workflow.steps?.forEach { stepName, _ ->
+        workflow.steps?.forEach { stepName, step ->
             paths.add(stepName)
             paths.joinToString(BluePrintConstants.PATH_DIVIDER)
-            // TODO("Step Validation")
+
+            // Validate target
+            step.target?.let {
+                try {
+                    val nodeTemplate = bluePrintRuntimeService.bluePrintContext().nodeTemplateByName(it)
+
+                    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}'"
+                    }
+                } catch (e: Exception) {
+                    bluePrintRuntimeService.getBluePrintError()
+                            .addError("Failed to validate Workflow($workflowName)'s step($stepName)'s " +
+                                    "definition", paths.joinToString(BluePrintConstants.PATH_DIVIDER), e.message!!)
+                }
+            }
             paths.removeAt(paths.lastIndex)
         }
         paths.removeAt(paths.lastIndex)
         // Step Validation Ends
         paths.removeAt(paths.lastIndex)
+
+        workflow.inputs?.let {
+            bluePrintTypeValidatorService.validatePropertyDefinitions(bluePrintRuntimeService, workflow.inputs!!)
+        }
     }
 }
\ No newline at end of file
diff --git a/components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/validation/BluePrintValidatorServiceImplTest.kt b/components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/validation/BluePrintValidatorServiceImplTest.kt
index c98f2ac..344b0cc 100644
--- a/components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/validation/BluePrintValidatorServiceImplTest.kt
+++ b/components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/validation/BluePrintValidatorServiceImplTest.kt
@@ -16,28 +16,86 @@
 
 package org.onap.ccsdk.apps.controllerblueprints.core.validation
 
+import io.mockk.every
+import io.mockk.mockk
+import org.junit.Ignore
 import org.junit.Test
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintError
+import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeTemplate
+import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeType
+import org.onap.ccsdk.apps.controllerblueprints.core.data.Step
+import org.onap.ccsdk.apps.controllerblueprints.core.data.Workflow
 import org.onap.ccsdk.apps.controllerblueprints.core.mock.MockBluePrintTypeValidatorService
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintContext
+import org.onap.ccsdk.apps.controllerblueprints.core.service.DefaultBluePrintRuntimeService
 import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintMetadataUtils
+import kotlin.test.assertEquals
 import kotlin.test.assertTrue
 
 class BluePrintValidatorServiceImplTest {
 
-    val blueprintBasePath: String = ("./../model-catalog/blueprint-model/starter-blueprint/baseconfiguration")
-
+    private val blueprintBasePath: String = ("./../model-catalog/blueprint-model/starter-blueprint/baseconfiguration")
+    private val bluePrintRuntime = BluePrintMetadataUtils.getBluePrintRuntime("1234", blueprintBasePath)
+    private val mockBluePrintTypeValidatorService = MockBluePrintTypeValidatorService()
+    private val defaultBluePrintValidatorService = BluePrintValidatorServiceImpl(mockBluePrintTypeValidatorService)
+    private val workflowValidator = BluePrintWorkflowValidatorImpl(mockBluePrintTypeValidatorService)
 
     @Test
     fun testValidateOfType() {
-        val bluePrintRuntime = BluePrintMetadataUtils.getBluePrintRuntime("1234", blueprintBasePath)
-
-        val mockBluePrintTypeValidatorService = MockBluePrintTypeValidatorService()
-
-        val defaultBluePrintValidatorService = BluePrintValidatorServiceImpl(mockBluePrintTypeValidatorService)
-
         val valid = defaultBluePrintValidatorService.validateBluePrints(bluePrintRuntime)
-
         assertTrue(valid, "failed in blueprint Validation")
-
     }
+
+    @Test
+    fun testValidateWorkflowFailToFoundNodeTemplate() {
+        val workflowName = "resource-assignment"
+
+        val step = Step()
+        step.target = "TestCaseFailNoNodeTemplate"
+        val workflow = Workflow()
+        workflow.steps = mutableMapOf("test" to step)
+        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 : could't get node template for the name(TestCaseFailNoNodeTemplate)", bluePrintRuntime.getBluePrintError().errors[0])
+    }
+
+    @Test
+    fun testValidateWorkflowFailNodeTemplateNotDgGeneric() {
+        val workflowName = "resource-assignment"
+        val nodeTemplateName = "resource-assignment-process"
+
+        val nodeTemplate = mockk<NodeTemplate>()
+        every { nodeTemplate.type } returns "TestNodeType"
+
+        val nodeType = mockk<NodeType>()
+        every { nodeType.derivedFrom } returns "tosca.nodes.TEST"
+
+        val blueprintContext = mockk<BluePrintContext>()
+        every { blueprintContext.nodeTemplateByName(nodeTemplateName) } returns nodeTemplate
+        every { blueprintContext.nodeTemplateNodeType(nodeTemplateName) } returns nodeType
+
+        val bluePrintRuntime = mockk<DefaultBluePrintRuntimeService>("1234")
+
+        every { bluePrintRuntime.getBluePrintError() } returns BluePrintError()
+        every { bluePrintRuntime.bluePrintContext() } returns blueprintContext
+
+        val step = Step()
+        step.target = nodeTemplateName
+        val workflow = Workflow()
+        workflow.steps = mutableMapOf("test" to step)
+        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])
+    }
+
+    @Test
+    fun testValidateWorkflowSuccess() {
+        val workflowName = "resource-assignment"
+        workflowValidator.validate(bluePrintRuntime, workflowName, bluePrintRuntime.bluePrintContext().workflowByName(workflowName))
+    }
+
 }
 
diff --git a/components/parent/pom.xml b/components/parent/pom.xml
index 1c49aed..71e2bec 100644
--- a/components/parent/pom.xml
+++ b/components/parent/pom.xml
@@ -16,7 +16,8 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.onap.ccsdk.apps</groupId>
@@ -40,7 +41,7 @@
         <springfox.swagger2.version>2.9.2</springfox.swagger2.version>
         <h2database.version>1.4.197</h2database.version>
         <onap.logger.slf4j>1.2.2</onap.logger.slf4j>
-        <powermock.version>1.7.4</powermock.version>
+        <mockk.version>1.9</mockk.version>
     </properties>
     <dependencyManagement>
         <dependencies>
@@ -189,9 +190,9 @@
 
             <!-- Testing Dependencies -->
             <dependency>
-                <groupId>org.powermock</groupId>
-                <artifactId>powermock-api-mockito2</artifactId>
-                <version>${powermock.version}</version>
+                <groupId>io.mockk</groupId>
+                <artifactId>mockk</artifactId>
+                <version>${mockk.version}</version>
                 <scope>test</scope>
             </dependency>
             <dependency>