diff options
Diffstat (limited to 'ms')
52 files changed, 1696 insertions, 153 deletions
diff --git a/ms/blueprintsprocessor/application/pom.xml b/ms/blueprintsprocessor/application/pom.xml index a5d45277d..490487687 100755 --- a/ms/blueprintsprocessor/application/pom.xml +++ b/ms/blueprintsprocessor/application/pom.xml @@ -58,6 +58,10 @@ <artifactId>restconf-executor</artifactId> </dependency> <dependency> + <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> + <artifactId>cli-executor</artifactId> + </dependency> + <dependency> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>selfservice-api</artifactId> </dependency> diff --git a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties index 2b90998b1..e34c02423 100755 --- a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties +++ b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties @@ -47,10 +47,11 @@ blueprintsprocessor.restconfEnabled=true blueprintsprocessor.restclient.sdncodl.type=basic-auth
blueprintsprocessor.restclient.sdncodl.url=http://localhost:8282/
blueprintsprocessor.restclient.sdncodl.username=admin
-blueprintsprocessor.restclient.sdncodl.password=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U - -# Executor Options -blueprintprocessor.resourceResolution.enabled=true -blueprintprocessor.netconfExecutor.enabled=true -blueprintprocessor.restConfExecutor.enabled=true +blueprintsprocessor.restclient.sdncodl.password=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
+
+# Executor Options
+blueprintprocessor.resourceResolution.enabled=true
+blueprintprocessor.netconfExecutor.enabled=true
+blueprintprocessor.restConfExecutor.enabled=true
+blueprintsprocessor.cliExecutor.enabled=true
blueprintprocessor.remoteScriptCommand.enabled=false
\ No newline at end of file diff --git a/ms/blueprintsprocessor/application/src/main/resources/application.properties b/ms/blueprintsprocessor/application/src/main/resources/application.properties index e5b1fe58f..1e0b4b8ac 100755 --- a/ms/blueprintsprocessor/application/src/main/resources/application.properties +++ b/ms/blueprintsprocessor/application/src/main/resources/application.properties @@ -51,6 +51,7 @@ blueprintsprocessor.restclient.sdncodl.password=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84v blueprintprocessor.resourceResolution.enabled=true blueprintprocessor.netconfExecutor.enabled=true blueprintprocessor.restConfExecutor.enabled=true +blueprintsprocessor.cliExecutor.enabled=true blueprintprocessor.remoteScriptCommand.enabled=true blueprintsprocessor.grpcclient.remote-python.type=token-auth diff --git a/ms/blueprintsprocessor/application/src/test/resources/application.properties b/ms/blueprintsprocessor/application/src/test/resources/application.properties index 7e462f25d..09ee651a4 100644 --- a/ms/blueprintsprocessor/application/src/test/resources/application.properties +++ b/ms/blueprintsprocessor/application/src/test/resources/application.properties @@ -44,4 +44,5 @@ security.user.name:ccsdkapps blueprintprocessor.resourceResolution.enabled=true blueprintprocessor.netconfExecutor.enabled=true blueprintprocessor.restConfExecutor.enabled=true +blueprintsprocessor.cliExecutor.enabled=true blueprintprocessor.remoteScriptCommand.enabled=false diff --git a/ms/blueprintsprocessor/functions/cli-executor/pom.xml b/ms/blueprintsprocessor/functions/cli-executor/pom.xml index af76d128b..0dd2737bf 100644 --- a/ms/blueprintsprocessor/functions/cli-executor/pom.xml +++ b/ms/blueprintsprocessor/functions/cli-executor/pom.xml @@ -21,16 +21,20 @@ <version>0.5.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> + <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> <artifactId>cli-executor</artifactId> <name>Blueprints Processor Function - CLI Executor</name> <description>Blueprints Processor Function - CLI Executor</description> <dependencies> <dependency> - <groupId>org.apache.sshd</groupId> - <artifactId>sshd-core</artifactId> + <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> + <artifactId>resource-resolution</artifactId> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> + <artifactId>ssh-lib</artifactId> </dependency> - </dependencies> diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt new file mode 100644 index 000000000..c7f35f7c8 --- /dev/null +++ b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt @@ -0,0 +1,67 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor + +import kotlinx.coroutines.runBlocking +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionService +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractScriptComponentFunction +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.SshLibConstants +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.service.BluePrintSshLibPropertyService +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile +import org.onap.ccsdk.cds.controllerblueprints.core.readNBLines +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService + +abstract class CliComponentFunction : AbstractScriptComponentFunction() { + + open fun bluePrintSshLibPropertyService(): BluePrintSshLibPropertyService = + functionDependencyInstanceAsType(SshLibConstants.SERVICE_BLUEPRINT_SSH_LIB_PROPERTY) + + open fun resourceResolutionService(): ResourceResolutionService = + functionDependencyInstanceAsType(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) + + + open suspend fun readCommandLinesFromArtifact(artifactName: String): List<String> { + val artifactDefinition = bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName) + val file = normalizedFile(bluePrintRuntimeService.bluePrintContext().rootPath, artifactDefinition.file) + return file.readNBLines() + } + + suspend fun generateMessage(artifactName: String, json: String): String { + val templateService = BluePrintTemplateService() + return templateService.generateContent(bluePrintRuntimeService, nodeTemplateName, artifactName, json, true) + } + + + fun generateMessage(artifactName: String): String { + return bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName) + } + + fun resolveFromDatabase(resolutionKey: String, artifactName: String): String = runBlocking { + resourceResolutionService().resolveFromDatabase(bluePrintRuntimeService, artifactName, resolutionKey) + } + + fun resolveAndGenerateMessage(artifactMapping: String, artifactTemplate: String): String = runBlocking { + resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName, + artifactMapping, artifactTemplate) + } + + fun resolveAndGenerateMessage(artifactPrefix: String): String = runBlocking { + resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName, + artifactPrefix, mapOf()) + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliExecutorConfiguration.kt b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliExecutorConfiguration.kt index f93020678..13afc58af 100644 --- a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliExecutorConfiguration.kt +++ b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliExecutorConfiguration.kt @@ -16,7 +16,13 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration @Configuration +@ComponentScan +@EnableConfigurationProperties +@ConditionalOnProperty(name = ["blueprintsprocessor.cliExecutor.enabled"], havingValue = "true") open class CliExecutorConfiguration
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutor.kt b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutor.kt new file mode 100644 index 000000000..0c1c52320 --- /dev/null +++ b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutor.kt @@ -0,0 +1,71 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor + +import com.fasterxml.jackson.databind.node.ArrayNode +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentFunctionScriptingService +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.SshLibConstants +import org.onap.ccsdk.cds.controllerblueprints.core.getAsString +import org.springframework.beans.factory.config.ConfigurableBeanFactory +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component + +@Component("component-cli-executor") +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +open class ComponentCliExecutor(private var componentFunctionScriptingService: ComponentFunctionScriptingService) + : AbstractComponentFunction() { + + companion object { + const val SCRIPT_TYPE = "script-type" + const val SCRIPT_CLASS_REFERENCE = "script-class-reference" + const val INSTANCE_DEPENDENCIES = "instance-dependencies" + const val RESPONSE_DATA = "response-data" + } + + private lateinit var scriptComponent: CliComponentFunction + + override suspend fun processNB(executionRequest: ExecutionServiceInput) { + + val scriptType = operationInputs.getAsString(SCRIPT_TYPE) + val scriptClassReference = operationInputs.getAsString(SCRIPT_CLASS_REFERENCE) + val instanceDependenciesNode = operationInputs[INSTANCE_DEPENDENCIES] as? ArrayNode + + val scriptDependencies: MutableList<String> = arrayListOf() + scriptDependencies.add(SshLibConstants.SERVICE_BLUEPRINT_SSH_LIB_PROPERTY) + // May be injected from model, not by default + //scriptDependencies.add(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) + + instanceDependenciesNode?.forEach { instanceName -> + scriptDependencies.add(instanceName.textValue()) + } + + scriptComponent = componentFunctionScriptingService.scriptInstance(this, scriptType, + scriptClassReference, scriptDependencies) + + + // Handles both script processing and error handling + scriptComponent.executeScript(executionServiceInput) + } + + override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { + bluePrintRuntimeService.getBluePrintError() + .addError("Failed in ComponentCliExecutor : ${runtimeException.message}") + + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts new file mode 100644 index 000000000..18d4a4797 --- /dev/null +++ b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts @@ -0,0 +1,78 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("unused") + +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor.CliComponentFunction +import org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor.ComponentCliExecutor +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive +import org.slf4j.LoggerFactory + +open class TestCliScriptFunction : CliComponentFunction() { + + private val log = LoggerFactory.getLogger(CliComponentFunction::class.java)!! + + override fun getName(): String { + return "SimpleCliConfigure" + } + + override suspend fun processNB(executionRequest: ExecutionServiceInput) { + log.info("Executing process") + } + + override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { + log.info("Executing Recovery") + } +} + + +open class Check : CliComponentFunction() { + + private val log = LoggerFactory.getLogger(CliComponentFunction::class.java)!! + + override fun getName(): String { + return "Check" + } + + override suspend fun processNB(executionRequest: ExecutionServiceInput) { + // Get the Device Information from the DSL Model + val deviceInformation = bluePrintRuntimeService.resolveDSLExpression("device-properties") + + // Get the Client Service + val sshClientService = bluePrintSshLibPropertyService().blueprintSshClientService(deviceInformation) + + sshClientService.startSessionNB() + + // Read Commands + val commands = readCommandLinesFromArtifact("command-template") + + // Execute multiple Commands + val responseLog = sshClientService.executeCommandsNB(commands, 5000) + + // Close Session + sshClientService.closeSessionNB() + + // Set the Response Data + setAttribute(ComponentCliExecutor.RESPONSE_DATA, responseLog.asJsonPrimitive()) + + log.info("Executing process") + } + + override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { + log.info("Executing Recovery") + } +} diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutorTest.kt b/ms/blueprintsprocessor/functions/cli-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutorTest.kt new file mode 100644 index 000000000..6455513f2 --- /dev/null +++ b/ms/blueprintsprocessor/functions/cli-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutorTest.kt @@ -0,0 +1,108 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.ArrayNode +import com.fasterxml.jackson.databind.node.ObjectNode +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.runBlocking +import org.junit.Test +import org.junit.runner.RunWith +import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties +import org.onap.ccsdk.cds.blueprintsprocessor.core.BlueprintPropertyConfiguration +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ActionIdentifiers +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.CommonHeader +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.StepData +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ExecutionServiceConfiguration +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.BluePrintSshLibConfiguration +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext +import org.onap.ccsdk.cds.controllerblueprints.core.service.DefaultBluePrintRuntimeService +import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.onap.ccsdk.cds.controllerblueprints.scripts.BluePrintScriptsServiceImpl +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.test.annotation.DirtiesContext +import org.springframework.test.context.ContextConfiguration +import org.springframework.test.context.TestPropertySource +import org.springframework.test.context.junit4.SpringRunner +import kotlin.test.assertNotNull + +@RunWith(SpringRunner::class) +@ContextConfiguration(classes = [CliExecutorConfiguration::class, + ExecutionServiceConfiguration::class, + BluePrintSshLibConfiguration::class, BluePrintScriptsServiceImpl::class, + BlueprintPropertyConfiguration::class, BluePrintProperties::class]) +@DirtiesContext +@TestPropertySource(properties = [], locations = ["classpath:application-test.properties"]) +class ComponentCliExecutorTest { + + @Autowired + lateinit var componentCliExecutor: ComponentCliExecutor + + @Test + fun `test CLI Component Instance`() { + runBlocking { + assertNotNull(componentCliExecutor, "failed to get ComponentCliExecutor instance") + val executionServiceInput = ExecutionServiceInput().apply { + commonHeader = CommonHeader().apply { + requestId = "1234" + } + actionIdentifiers = ActionIdentifiers().apply { + actionName = "activate" + } + payload = JacksonUtils.jsonNode("{}") as ObjectNode + } + val bluePrintRuntime = mockk<DefaultBluePrintRuntimeService>("1234") + componentCliExecutor.bluePrintRuntimeService = bluePrintRuntime + componentCliExecutor.stepName = "sample-step" + + val operationInputs = hashMapOf<String, JsonNode>() + operationInputs[BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE] = "activate-cli".asJsonPrimitive() + operationInputs[BluePrintConstants.PROPERTY_CURRENT_INTERFACE] = "interfaceName".asJsonPrimitive() + operationInputs[BluePrintConstants.PROPERTY_CURRENT_OPERATION] = "operationName".asJsonPrimitive() + operationInputs[ComponentCliExecutor.SCRIPT_TYPE] = BluePrintConstants.SCRIPT_INTERNAL.asJsonPrimitive() + operationInputs[ComponentCliExecutor.SCRIPT_CLASS_REFERENCE] = + "InternalSimpleCli_cba\$TestCliScriptFunction".asJsonPrimitive() + operationInputs[ComponentCliExecutor.INSTANCE_DEPENDENCIES] = JacksonUtils.jsonNode("[]") as ArrayNode + + val stepInputData = StepData().apply { + name = "activate-cli" + properties = operationInputs + } + executionServiceInput.stepData = stepInputData + + val blueprintContext = mockk<BluePrintContext>() + every { bluePrintRuntime.bluePrintContext() } returns blueprintContext + every { + bluePrintRuntime.resolveNodeTemplateInterfaceOperationInputs("activate-cli", + "interfaceName", "operationName") + } returns operationInputs + + val operationOutputs = hashMapOf<String, JsonNode>() + every { + bluePrintRuntime.resolveNodeTemplateInterfaceOperationOutputs("activate-cli", + "interfaceName", "operationName") + } returns operationOutputs + + componentCliExecutor.applyNB(executionServiceInput) + } + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/service/CliExecutorServiceImplTest.kt b/ms/blueprintsprocessor/functions/cli-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/service/CliExecutorServiceImplTest.kt deleted file mode 100644 index 51dd62ceb..000000000 --- a/ms/blueprintsprocessor/functions/cli-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/service/CliExecutorServiceImplTest.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright © 2019 IBM. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor.service - -import org.junit.Test -import org.junit.runner.RunWith -import org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor.api.CliExecutorService -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.test.context.ContextConfiguration -import org.springframework.test.context.junit4.SpringRunner -import kotlin.test.assertNotNull - -@RunWith(SpringRunner::class) -@ContextConfiguration(classes = [CliExecutorServiceImpl::class]) -class CliExecutorServiceImplTest { - - @Autowired - lateinit var cliExecutorService: CliExecutorService - - @Test - fun testCliExecutorService() { - assertNotNull(cliExecutorService, "failed to intilise cliExecutorService") - } -}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/test/resources/application-test.properties b/ms/blueprintsprocessor/functions/cli-executor/src/test/resources/application-test.properties new file mode 100644 index 000000000..34e07e086 --- /dev/null +++ b/ms/blueprintsprocessor/functions/cli-executor/src/test/resources/application-test.properties @@ -0,0 +1,18 @@ +# +# Copyright © 2019 IBM. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Executor Options +blueprintsprocessor.cliExecutor.enabled=true
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfExecutorConfiguration.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfExecutorConfiguration.kt new file mode 100644 index 000000000..77a2d3ba9 --- /dev/null +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfExecutorConfiguration.kt @@ -0,0 +1,28 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Configuration + +@Configuration +@ComponentScan +@EnableConfigurationProperties +@ConditionalOnProperty(name = ["blueprintprocessor.netconfExecutor.enabled"], havingValue = "true") +open class NetconfExecutorConfiguration
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/test/resources/application-test.properties b/ms/blueprintsprocessor/functions/netconf-executor/src/test/resources/application-test.properties index 6d8b62ff9..527eb8a26 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/test/resources/application-test.properties +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/test/resources/application-test.properties @@ -30,3 +30,6 @@ blueprintsprocessor.blueprintArchivePath=./target/blueprints/archive # Python executor blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_blueprints blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints + +# Executor Options +blueprintprocessor.netconfExecutor.enabled=true
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt index 51062256d..ebff47899 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt @@ -46,10 +46,10 @@ interface ResourceResolutionService { artifactNames: List<String>, properties: Map<String, Any>): MutableMap<String, String> suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String, - artifactPrefix: String, properties: Map<String, Any>): String + artifactPrefix: String, properties: Map<String, Any>): String suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String, - artifactMapping: String, artifactTemplate: String?): String + artifactMapping: String, artifactTemplate: String?): String suspend fun resolveResourceAssignments(blueprintRuntimeService: BluePrintRuntimeService<*>, resourceDefinitions: MutableMap<String, ResourceDefinition>, @@ -89,7 +89,7 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica } override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String, - artifactPrefix: String, properties: Map<String, Any>): String { + artifactPrefix: String, properties: Map<String, Any>): String { // Velocity Artifact Definition Name val artifactTemplate = "$artifactPrefix-template" @@ -110,7 +110,7 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String, - artifactMapping: String, artifactTemplate: String?): String { + artifactMapping: String, artifactTemplate: String?): String { val resolvedContent: String log.info("Resolving resource for template artifact($artifactTemplate) with resource assignment artifact($artifactMapping)") @@ -137,11 +137,9 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica // Check Template is there if (artifactTemplate != null) { - val blueprintTemplateService = BluePrintTemplateService(bluePrintRuntimeService, nodeTemplateName, artifactTemplate) - val templateContent = - bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactTemplate) - - resolvedContent = blueprintTemplateService.generateContent(templateContent, resolvedParamJsonContent) + val blueprintTemplateService = BluePrintTemplateService() + resolvedContent = blueprintTemplateService.generateContent(bluePrintRuntimeService, nodeTemplateName, + artifactTemplate, resolvedParamJsonContent) } else { resolvedContent = resolvedParamJsonContent diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt index e8b61a8fe..987390fdb 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt @@ -124,7 +124,8 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert checkNotEmpty(resourceAssignment.dictionaryName) { "resource assignment dictionary name is not defined for template key (${resourceAssignment.name})" } - checkEquals(ResourceDictionaryConstants.SOURCE_PROCESSOR_DB, resourceAssignment.dictionarySource) { + check(resourceAssignment.dictionarySource in arrayOf(ResourceDictionaryConstants.SOURCE_PROCESSOR_DB, ResourceDictionaryConstants.SOURCE_PRIMARY_DB)) + { "resource assignment source is not ${ResourceDictionaryConstants.SOURCE_PROCESSOR_DB} but it is ${resourceAssignment.dictionarySource}" } } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt index 8dbd47cc2..1cc44a2cb 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt @@ -25,9 +25,9 @@ import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.util import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintFunctionNode import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintVelocityTemplateService -import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition import org.slf4j.LoggerFactory @@ -67,25 +67,24 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig ?: throw BluePrintProcessorException("couldn't get resource definition for ($name)") } - open fun resolveInputKeyMappingVariables(inputKeyMapping: Map<String, String>): Map<String, Any> { - val resolvedInputKeyMapping = HashMap<String, Any>() + open fun resolveInputKeyMappingVariables(inputKeyMapping: Map<String, String>): Map<String, JsonNode> { + val resolvedInputKeyMapping = HashMap<String, JsonNode>() if (MapUtils.isNotEmpty(inputKeyMapping)) { for ((key, value) in inputKeyMapping) { val resultValue = raRuntimeService.getResolutionStore(value) - val expressionValue = JacksonUtils.getValue(resultValue) - log.trace("Reference dictionary key ({}), value ({})", key, expressionValue) - resolvedInputKeyMapping[key] = expressionValue + resolvedInputKeyMapping[key] = resultValue } } return resolvedInputKeyMapping } - open suspend fun resolveFromInputKeyMapping(valueToResolve: String, keyMapping: MutableMap<String, Any>): + open suspend fun resolveFromInputKeyMapping(valueToResolve: String, keyMapping: MutableMap<String, JsonNode>): String { if (valueToResolve.isEmpty() || !valueToResolve.contains("$")) { return valueToResolve } - return BluePrintVelocityTemplateService.generateContent(valueToResolve, additionalContext = keyMapping) + //TODO("Optimize to JSON Node directly without velocity").asJsonNode().toString() + return BluePrintVelocityTemplateService.generateContent(valueToResolve, keyMapping.asJsonNode().toString()) } final override suspend fun applyNB(resourceAssignment: ResourceAssignment): Boolean { diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt index 656e86169..1a943d110 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.node.NullNode import com.fasterxml.jackson.databind.node.ObjectNode +import com.fasterxml.jackson.databind.node.TextNode import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants import org.onap.ccsdk.cds.controllerblueprints.core.* @@ -122,7 +123,7 @@ class ResourceAssignmentUtils { if (isNotEmpty(it.name) && it.property != null) { val rName = it.name val type = nullToEmpty(it.property?.type).toLowerCase() - val value = it.property?.value + val value = useDefaultValueIfNull(it, rName) logger.info("Generating Resource name ($rName), type ($type), value ($value)") root.set(rName, value) } @@ -136,6 +137,15 @@ class ResourceAssignmentUtils { return result } + private fun useDefaultValueIfNull(resourceAssignment: ResourceAssignment, resourceAssignmentName: String): JsonNode { + if (resourceAssignment.property?.value == null) { + val defaultValue = "\${$resourceAssignmentName}" + return TextNode(defaultValue) + } else { + return resourceAssignment.property!!.value!! + } + } + fun transformToRARuntimeService(blueprintRuntimeService: BluePrintRuntimeService<*>, templateArtifactName: String): ResourceAssignmentRuntimeService { diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockRestResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockRestResourceResolutionProcessor.kt index eb2a7a7ed..be023307b 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockRestResourceResolutionProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockRestResourceResolutionProcessor.kt @@ -15,6 +15,7 @@ */ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.mock +import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.node.ArrayNode import com.fasterxml.jackson.databind.node.MissingNode import org.apache.commons.collections.MapUtils @@ -22,23 +23,27 @@ import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.Reso import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.RestResourceSource import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.ResourceAssignmentProcessor import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils -import org.onap.ccsdk.cds.controllerblueprints.core.* +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive +import org.onap.ccsdk.cds.controllerblueprints.core.nullToEmpty import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment import org.slf4j.LoggerFactory -import java.util.HashMap +import java.util.* class MockRestResourceResolutionProcessor(private val blueprintRestLibPropertyService: - MockBluePrintRestLibPropertyService): ResourceAssignmentProcessor() { + MockBluePrintRestLibPropertyService) : ResourceAssignmentProcessor() { private val logger = LoggerFactory.getLogger(MockRestResourceResolutionProcessor::class.java) - override fun resolveInputKeyMappingVariables(inputKeyMapping: Map<String, String>): Map<String, Any> { - val resolvedInputKeyMapping = HashMap<String, Any>() + override fun resolveInputKeyMappingVariables(inputKeyMapping: Map<String, String>): Map<String, JsonNode> { + val resolvedInputKeyMapping = HashMap<String, JsonNode>() if (MapUtils.isNotEmpty(inputKeyMapping)) { - resolvedInputKeyMapping["service-instance-id"] = "10" - resolvedInputKeyMapping["vnf_name"] = "vnf1" - resolvedInputKeyMapping["vnf-id"] = "123456" + + resolvedInputKeyMapping["service-instance-id"] = "10".asJsonPrimitive() + resolvedInputKeyMapping["vnf_name"] = "vnf1".asJsonPrimitive() + resolvedInputKeyMapping["vnf-id"] = "123456".asJsonPrimitive() } return resolvedInputKeyMapping } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceResolutionProcessorTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceResolutionProcessorTest.kt index 89674ea24..f73197e0b 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceResolutionProcessorTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceResolutionProcessorTest.kt @@ -49,7 +49,7 @@ class DatabaseResourceResolutionProcessorTest { lateinit var databaseResourceAssignmentProcessor: DatabaseResourceAssignmentProcessor @Test - fun `test database resource resolution`() { + fun `test database resource resolution processor db`() { runBlocking { val bluePrintContext = BluePrintMetadataUtils.getBluePrintContext( "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") @@ -74,4 +74,31 @@ class DatabaseResourceResolutionProcessorTest { println(processorName) } } + + @Test + fun `test database resource resolution primary db`() { + runBlocking { + val bluePrintContext = BluePrintMetadataUtils.getBluePrintContext( + "./../../../../components/model-catalog/blueprint-model/test-blueprint/capability_python") + + val resourceAssignmentRuntimeService = ResourceAssignmentRuntimeService("1234", bluePrintContext) + + databaseResourceAssignmentProcessor.raRuntimeService = resourceAssignmentRuntimeService + databaseResourceAssignmentProcessor.resourceDictionaries = ResourceAssignmentUtils + .resourceDefinitions(bluePrintContext.rootPath) + + val resourceAssignment = ResourceAssignment().apply { + name = "service-instance-id" + dictionaryName = "service-instance-id" + dictionarySource = "primary-db" + property = PropertyDefinition().apply { + type = "string" + } + } + + val processorName = databaseResourceAssignmentProcessor.applyNB(resourceAssignment) + assertNotNull(processorName, "couldn't get Database resource assignment processor name") + println(processorName) + } + } }
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt new file mode 100644 index 000000000..9b87c12eb --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt @@ -0,0 +1,79 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils + +import com.fasterxml.jackson.databind.node.TextNode +import org.junit.Test +import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition +import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment +import kotlin.test.assertEquals + +class ResourceAssignmentUtilsTest { + + @Test + fun `generateResourceDataForAssignments - positive test`() { + //given a valid resource assignment + val validResourceAssignment = createResourceAssignmentForTest("valid_value") + + //and a list containing that resource assignment + val resourceAssignmentList = listOf<ResourceAssignment>(validResourceAssignment) + + //when the values of the resources are evaluated + val outcome = ResourceAssignmentUtils.generateResourceDataForAssignments(resourceAssignmentList) + + //then the assignment should produce a valid result + val expected = "{\n" + " \"pnf-id\" : \"valid_value\"\n" + "}" + assertEquals(expected, outcome, "unexpected outcome generated") + + } + + @Test + fun `generateResourceDataForAssignments - resource without value is not resolved as null`() { + //given a valid resource assignment + val resourceAssignmentWithNullValue = createResourceAssignmentForTest(null) + + //and a list containing that resource assignment + val resourceAssignmentList = listOf<ResourceAssignment>(resourceAssignmentWithNullValue) + + //when the values of the resources are evaluated + val outcome = ResourceAssignmentUtils.generateResourceDataForAssignments(resourceAssignmentList) + + //then the assignment should produce a valid result + val expected = "{\n" + " \"pnf-id\" : \"\${pnf-id}\"\n" + "}" + assertEquals(expected, outcome, "unexpected outcome generated") + + } + + private fun createResourceAssignmentForTest(resourceValue: String?): ResourceAssignment { + val valueForTest = if (resourceValue == null) null else TextNode(resourceValue) + val resourceAssignmentForTest = ResourceAssignment().apply { + name = "pnf-id" + dictionaryName = "pnf-id" + dictionarySource = "input" + property = PropertyDefinition().apply { + type = "string" + value = valueForTest + } + } + return resourceAssignmentForTest + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/pom.xml b/ms/blueprintsprocessor/modules/commons/message-lib/pom.xml new file mode 100644 index 000000000..d423dfd06 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/message-lib/pom.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright © 2019 IBM. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ 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"> + <parent> + <artifactId>commons</artifactId> + <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> + <version>0.5.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>message-lib</artifactId> + <name>Blueprints Processor Messaging Lib</name> + <description>Blueprints Processor Messaging Lib</description> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.cds.controllerblueprints</groupId> + <artifactId>blueprint-core</artifactId> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> + <artifactId>processor-core</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.kafka</groupId> + <artifactId>spring-kafka</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.kafka</groupId> + <artifactId>spring-kafka-test</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project>
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibConfiguration.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibConfiguration.kt new file mode 100644 index 000000000..644c51860 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibConfiguration.kt @@ -0,0 +1,35 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.message + + +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Configuration + +@Configuration +@ComponentScan +@EnableConfigurationProperties +open class BluePrintMessageLibConfiguration + +class MessageLibConstants { + companion object { + const val SERVICE_BLUEPRINT_MESSAGE_LIB_PROPERTY = "blueprint-message-lib-property-service" + const val PROPERTY_MESSAGE_CLIENT_PREFIX = "blueprintsprocessor.messageclient." + const val TYPE_KAFKA_BASIC_AUTH = "kafka-basic-auth" + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/api/CliExecutorService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt index 5ad671ba4..e621ec66f 100644 --- a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/api/CliExecutorService.kt +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt @@ -14,9 +14,14 @@ * limitations under the License. */ -package org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor.api +package org.onap.ccsdk.cds.blueprintsprocessor.message -interface CliExecutorService { +open class MessageProducerProperties + +open class KafkaBasicAuthMessageProducerProperties : MessageProducerProperties() { + lateinit var bootstrapServers: String + var topic: String? = null + var clientId: String? = null }
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BluePrintMessageLibPropertyService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BluePrintMessageLibPropertyService.kt new file mode 100644 index 000000000..fb01ce179 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BluePrintMessageLibPropertyService.kt @@ -0,0 +1,84 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.message.service + +import com.fasterxml.jackson.databind.JsonNode +import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties +import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaBasicAuthMessageProducerProperties +import org.onap.ccsdk.cds.blueprintsprocessor.message.MessageLibConstants +import org.onap.ccsdk.cds.blueprintsprocessor.message.MessageProducerProperties +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.springframework.stereotype.Service + +@Service(MessageLibConstants.SERVICE_BLUEPRINT_MESSAGE_LIB_PROPERTY) +open class BluePrintMessageLibPropertyService(private var bluePrintProperties: BluePrintProperties) { + + fun blueprintMessageClientService(jsonNode: JsonNode): BlueprintMessageProducerService { + val messageClientProperties = messageClientProperties(jsonNode) + return blueprintMessageClientService(messageClientProperties) + } + + fun blueprintMessageClientService(selector: String): BlueprintMessageProducerService { + val prefix = "${MessageLibConstants.PROPERTY_MESSAGE_CLIENT_PREFIX}$selector" + val messageClientProperties = messageClientProperties(prefix) + return blueprintMessageClientService(messageClientProperties) + } + + fun messageClientProperties(prefix: String): MessageProducerProperties { + val type = bluePrintProperties.propertyBeanType("$prefix.type", String::class.java) + return when (type) { + MessageLibConstants.TYPE_KAFKA_BASIC_AUTH -> { + kafkaBasicAuthMessageClientProperties(prefix) + } + else -> { + throw BluePrintProcessorException("Message adaptor($type) is not supported") + } + } + } + + fun messageClientProperties(jsonNode: JsonNode): MessageProducerProperties { + val type = jsonNode.get("type").textValue() + return when (type) { + MessageLibConstants.TYPE_KAFKA_BASIC_AUTH -> { + JacksonUtils.readValue(jsonNode, KafkaBasicAuthMessageProducerProperties::class.java)!! + } + else -> { + throw BluePrintProcessorException("Message adaptor($type) is not supported") + } + } + } + + private fun blueprintMessageClientService(MessageProducerProperties: MessageProducerProperties) + : BlueprintMessageProducerService { + + when (MessageProducerProperties) { + is KafkaBasicAuthMessageProducerProperties -> { + return KafkaBasicAuthMessageProducerService(MessageProducerProperties) + } + else -> { + throw BluePrintProcessorException("couldn't get Message client service for") + } + } + } + + private fun kafkaBasicAuthMessageClientProperties(prefix: String): KafkaBasicAuthMessageProducerProperties { + return bluePrintProperties.propertyBeanType( + prefix, KafkaBasicAuthMessageProducerProperties::class.java) + } + +} diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerService.kt new file mode 100644 index 000000000..e33d41c09 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerService.kt @@ -0,0 +1,34 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.message.service + +import kotlinx.coroutines.runBlocking + +interface BlueprintMessageProducerService { + + fun sendMessage(message: Any): Boolean = runBlocking { + sendMessageNB(message) + } + + fun sendMessage(topic: String, message: Any): Boolean = runBlocking { + sendMessageNB(topic, message) + } + + suspend fun sendMessageNB(message: Any): Boolean + + suspend fun sendMessageNB(topic: String, message: Any): Boolean +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageProducerService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageProducerService.kt new file mode 100644 index 000000000..52ac346db --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageProducerService.kt @@ -0,0 +1,94 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.message.service + +import org.apache.kafka.clients.producer.ProducerConfig.* +import org.apache.kafka.common.serialization.StringSerializer +import org.onap.ccsdk.cds.blueprintsprocessor.message.KafkaBasicAuthMessageProducerProperties +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType +import org.slf4j.LoggerFactory +import org.springframework.kafka.core.DefaultKafkaProducerFactory +import org.springframework.kafka.core.KafkaTemplate +import org.springframework.kafka.core.ProducerFactory +import org.springframework.kafka.support.SendResult +import org.springframework.util.concurrent.ListenableFutureCallback + + +class KafkaBasicAuthMessageProducerService( + private val messageProducerProperties: KafkaBasicAuthMessageProducerProperties) + : BlueprintMessageProducerService { + + private val log = LoggerFactory.getLogger(KafkaBasicAuthMessageProducerService::class.java)!! + + private var kafkaTemplate: KafkaTemplate<String, Any>? = null + + override suspend fun sendMessageNB(message: Any): Boolean { + checkNotNull(messageProducerProperties.topic) { "default topic is not configured" } + return sendMessage(messageProducerProperties.topic!!, message) + } + + override suspend fun sendMessageNB(topic: String, message: Any): Boolean { + val serializedMessage = when (message) { + is String -> { + message + } + else -> { + message.asJsonType().toString() + } + } + val future = messageTemplate().send(topic, serializedMessage) + + future.addCallback(object : ListenableFutureCallback<SendResult<String, Any>> { + override fun onSuccess(result: SendResult<String, Any>) { + log.info("message sent successfully with offset=[${result.recordMetadata.offset()}]") + } + + override fun onFailure(ex: Throwable) { + log.error("Unable to send message", ex) + } + }) + return true + } + + + private fun producerFactory(additionalConfig: Map<String, Any>? = null): ProducerFactory<String, Any> { + log.info("Client Properties : $messageProducerProperties") + val configProps = hashMapOf<String, Any>() + configProps[BOOTSTRAP_SERVERS_CONFIG] = messageProducerProperties.bootstrapServers + configProps[KEY_SERIALIZER_CLASS_CONFIG] = StringSerializer::class.java + configProps[VALUE_SERIALIZER_CLASS_CONFIG] = StringSerializer::class.java + if (messageProducerProperties.clientId != null) { + configProps[CLIENT_ID_CONFIG] = messageProducerProperties.clientId!! + } + // TODO("Security Implementation based on type") + + // Add additional Properties + if (additionalConfig != null) { + configProps.putAll(additionalConfig) + } + return DefaultKafkaProducerFactory(configProps) + } + + fun messageTemplate(additionalConfig: Map<String, Any>? = null): KafkaTemplate<String, Any> { + log.info("Prepering templates") + if (kafkaTemplate == null) { + kafkaTemplate = KafkaTemplate(producerFactory(additionalConfig)) + } + return kafkaTemplate!! + } +} + diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerServiceTest.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerServiceTest.kt new file mode 100644 index 000000000..0f8367d7e --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageProducerServiceTest.kt @@ -0,0 +1,79 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.message.service + +import io.mockk.every +import io.mockk.mockk +import io.mockk.spyk +import kotlinx.coroutines.runBlocking +import org.junit.runner.RunWith +import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties +import org.onap.ccsdk.cds.blueprintsprocessor.core.BlueprintPropertyConfiguration +import org.onap.ccsdk.cds.blueprintsprocessor.message.BluePrintMessageLibConfiguration +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.kafka.core.KafkaTemplate +import org.springframework.kafka.support.SendResult +import org.springframework.test.annotation.DirtiesContext +import org.springframework.test.context.ContextConfiguration +import org.springframework.test.context.TestPropertySource +import org.springframework.test.context.junit4.SpringRunner +import org.springframework.util.concurrent.SettableListenableFuture +import kotlin.test.Test +import kotlin.test.assertTrue + + +@RunWith(SpringRunner::class) +@DirtiesContext +@ContextConfiguration(classes = [BluePrintMessageLibConfiguration::class, + BlueprintPropertyConfiguration::class, BluePrintProperties::class]) +@TestPropertySource(properties = +["blueprintsprocessor.messageclient.sample.type=kafka-basic-auth", + "blueprintsprocessor.messageclient.sample.bootstrapServers=127:0.0.1:9092", + "blueprintsprocessor.messageclient.sample.topic=default-topic", + "blueprintsprocessor.messageclient.sample.clientId=default-client-id" +]) +open class BlueprintMessageProducerServiceTest { + + @Autowired + lateinit var bluePrintMessageLibPropertyService: BluePrintMessageLibPropertyService + + @Test + fun testKafkaBasicAuthClientService() { + runBlocking { + val bluePrintMessageClientService = bluePrintMessageLibPropertyService + .blueprintMessageClientService("sample") as KafkaBasicAuthMessageProducerService + + val mockKafkaTemplate = mockk<KafkaTemplate<String, Any>>() + + val future = SettableListenableFuture<SendResult<String, Any>>() + //future.setException(BluePrintException("failed sending")) + + every { mockKafkaTemplate.send(any(), any()) } returns future + + val spyBluePrintMessageClientService = spyk(bluePrintMessageClientService, recordPrivateCalls = true) + + every { spyBluePrintMessageClientService.messageTemplate(any()) } returns mockKafkaTemplate + + val response = spyBluePrintMessageClientService.sendMessage("Testing message") + assertTrue(response, "failed to get command response") + } + } + +} + + + diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/resources/logback-test.xml b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/resources/logback-test.xml new file mode 100644 index 000000000..626b8f911 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/resources/logback-test.xml @@ -0,0 +1,35 @@ +<!-- + ~ Copyright © 2019 IBM. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<configuration> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <!-- encoders are assigned the type + ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> + <encoder> + <pattern>%d{HH:mm:ss.SSS} %-5level %logger{100} - %msg%n</pattern> + </encoder> + </appender> + + <logger name="org.springframework.test" level="warn"/> + <logger name="org.springframework" level="warn"/> + <logger name="org.hibernate" level="info"/> + <logger name="org.onap.ccsdk.cds.blueprintsprocessor" level="info"/> + + <root level="warn"> + <appender-ref ref="STDOUT"/> + </root> + +</configuration> diff --git a/ms/blueprintsprocessor/modules/commons/pom.xml b/ms/blueprintsprocessor/modules/commons/pom.xml index 5fdfb5064..9284e0d4e 100755 --- a/ms/blueprintsprocessor/modules/commons/pom.xml +++ b/ms/blueprintsprocessor/modules/commons/pom.xml @@ -36,6 +36,8 @@ <module>rest-lib</module> <module>dmaap-lib</module> <module>grpc-lib</module> + <module>message-lib</module> + <module>ssh-lib</module> </modules> <dependencies> <dependency> diff --git a/ms/blueprintsprocessor/modules/commons/ssh-lib/pom.xml b/ms/blueprintsprocessor/modules/commons/ssh-lib/pom.xml new file mode 100644 index 000000000..6949c4f43 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/pom.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright © 2019 IBM. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ 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"> + <parent> + <artifactId>commons</artifactId> + <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> + <version>0.5.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>ssh-lib</artifactId> + <packaging>jar</packaging> + <name>Blueprints Processor SSH Lib</name> + <description>Blueprints Processor SSH Lib</description> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.cds.controllerblueprints</groupId> + <artifactId>blueprint-core</artifactId> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> + <artifactId>processor-core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.sshd</groupId> + <artifactId>sshd-core</artifactId> + </dependency> + </dependencies> +</project>
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/BluePrintSshLibConfiguration.kt b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/BluePrintSshLibConfiguration.kt new file mode 100644 index 000000000..48e451f03 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/BluePrintSshLibConfiguration.kt @@ -0,0 +1,34 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.ssh + +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Configuration + +@Configuration +@ComponentScan +@EnableConfigurationProperties +open class BluePrintSshLibConfiguration + +class SshLibConstants { + companion object { + const val SERVICE_BLUEPRINT_SSH_LIB_PROPERTY = "blueprint-ssh-lib-property-service" + const val PROPERTY_SSH_CLIENT_PREFIX = "blueprintsprocessor.sshclient." + const val TYPE_BASIC_AUTH = "basic-auth" + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/service/CliExecutorServiceImpl.kt b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/BluePrintSshLibData.kt index 43047b38b..a70ea5588 100644 --- a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/service/CliExecutorServiceImpl.kt +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/BluePrintSshLibData.kt @@ -14,12 +14,16 @@ * limitations under the License. */ -package org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor.service +package org.onap.ccsdk.cds.blueprintsprocessor.ssh -import org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor.api.CliExecutorService -import org.springframework.stereotype.Service - -@Service -open class CliExecutorServiceImpl : CliExecutorService { +open class SshClientProperties { + lateinit var type: String + lateinit var host: String + var port: Int = 22 + var connectionTimeOut: Long = 3000 +} +open class BasicAuthSshClientProperties : SshClientProperties() { + lateinit var password: String + lateinit var username: String }
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BasicAuthSshClientService.kt b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BasicAuthSshClientService.kt new file mode 100644 index 000000000..adbde0f87 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BasicAuthSshClientService.kt @@ -0,0 +1,98 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.ssh.service + +import org.apache.sshd.client.SshClient +import org.apache.sshd.client.channel.ChannelExec +import org.apache.sshd.client.channel.ClientChannel +import org.apache.sshd.client.channel.ClientChannelEvent +import org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier +import org.apache.sshd.client.session.ClientSession +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.BasicAuthSshClientProperties +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.slf4j.LoggerFactory +import java.io.ByteArrayOutputStream +import java.util.* + + +open class BasicAuthSshClientService(private val basicAuthSshClientProperties: BasicAuthSshClientProperties) + : BlueprintSshClientService { + + private val log = LoggerFactory.getLogger(BasicAuthSshClientService::class.java)!! + + private lateinit var sshClient: SshClient + private lateinit var clientSession: ClientSession + var channel: ChannelExec? = null + + override suspend fun startSessionNB(): ClientSession { + sshClient = SshClient.setUpDefaultClient() + sshClient.serverKeyVerifier = AcceptAllServerKeyVerifier.INSTANCE + sshClient.start() + log.debug("SSH Client Service started successfully") + clientSession = sshClient.connect(basicAuthSshClientProperties.username, basicAuthSshClientProperties.host, + basicAuthSshClientProperties.port) + .verify(basicAuthSshClientProperties.connectionTimeOut) + .session + + clientSession.addPasswordIdentity(basicAuthSshClientProperties.password) + clientSession.auth().verify(basicAuthSshClientProperties.connectionTimeOut) + log.info("SSH client session($clientSession) created") + return clientSession + } + + override suspend fun executeCommandsNB(commands: List<String>, timeOut: Long): String { + val buffer = StringBuffer() + try { + commands.forEach { command -> + buffer.append("\nCommand : $command") + buffer.append("\n" + executeCommandNB(command, timeOut)) + } + } catch (e: Exception) { + throw BluePrintProcessorException("Failed to execute commands, below the output : $buffer") + } + return buffer.toString() + } + + override suspend fun executeCommandNB(command: String, timeOut: Long): String { + log.debug("Executing host($clientSession) command($command)") + + channel = clientSession.createExecChannel(command) + checkNotNull(channel) { "failed to create Channel for the command : $command" } + + //TODO("Convert to streaming ") + val outputStream = ByteArrayOutputStream() + channel!!.out = outputStream + channel!!.err = outputStream + channel!!.open().await() + val waitMask = channel!!.waitFor(Collections.unmodifiableSet(EnumSet.of(ClientChannelEvent.CLOSED)), timeOut) + if (waitMask.contains(ClientChannelEvent.TIMEOUT)) { + throw BluePrintProcessorException("Failed to retrieve command result in time: $command") + } + val exitStatus = channel!!.exitStatus + ClientChannel.validateCommandExitStatusCode(command, exitStatus!!) + return outputStream.toString() + } + + override suspend fun closeSessionNB() { + if (channel != null) + channel!!.close() + if (sshClient.isStarted) { + sshClient.stop() + } + log.debug("SSH Client Service stopped successfully") + } +} diff --git a/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BluePrintSshLibPropertyService.kt b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BluePrintSshLibPropertyService.kt new file mode 100644 index 000000000..1950b71aa --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BluePrintSshLibPropertyService.kt @@ -0,0 +1,84 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.ssh.service + +import com.fasterxml.jackson.databind.JsonNode +import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.BasicAuthSshClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.SshClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.SshLibConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.springframework.stereotype.Service + +@Service(SshLibConstants.SERVICE_BLUEPRINT_SSH_LIB_PROPERTY) +open class BluePrintSshLibPropertyService(private var bluePrintProperties: BluePrintProperties) { + + fun blueprintSshClientService(jsonNode: JsonNode): BlueprintSshClientService { + val restClientProperties = sshClientProperties(jsonNode) + return blueprintSshClientService(restClientProperties) + } + + fun blueprintSshClientService(selector: String): BlueprintSshClientService { + val prefix = "${SshLibConstants.PROPERTY_SSH_CLIENT_PREFIX}$selector" + val sshClientProperties = sshClientProperties(prefix) + return blueprintSshClientService(sshClientProperties) + } + + fun sshClientProperties(prefix: String): SshClientProperties { + val type = bluePrintProperties.propertyBeanType("$prefix.type", String::class.java) + return when (type) { + SshLibConstants.TYPE_BASIC_AUTH -> { + basicAuthSshClientProperties(prefix) + } + else -> { + throw BluePrintProcessorException("SSH adaptor($type) is not supported") + } + } + } + + fun sshClientProperties(jsonNode: JsonNode): SshClientProperties { + val type = jsonNode.get("type").textValue() + return when (type) { + SshLibConstants.TYPE_BASIC_AUTH -> { + JacksonUtils.readValue(jsonNode, + BasicAuthSshClientProperties::class.java)!! + } + else -> { + throw BluePrintProcessorException("SSH adaptor($type) is not supported") + } + } + } + + private fun blueprintSshClientService(sshClientProperties: SshClientProperties): BlueprintSshClientService { + + when (sshClientProperties) { + is BasicAuthSshClientProperties -> { + return BasicAuthSshClientService(sshClientProperties) + } + else -> { + throw BluePrintProcessorException("couldn't get SSH client service for") + } + } + } + + private fun basicAuthSshClientProperties(prefix: String): BasicAuthSshClientProperties { + return bluePrintProperties.propertyBeanType( + prefix, BasicAuthSshClientProperties::class.java) + } + +} diff --git a/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BlueprintSshClientService.kt b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BlueprintSshClientService.kt new file mode 100644 index 000000000..279e437cc --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BlueprintSshClientService.kt @@ -0,0 +1,47 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.ssh.service + +import kotlinx.coroutines.runBlocking +import org.apache.sshd.client.session.ClientSession + +interface BlueprintSshClientService { + + fun startSession(): ClientSession = runBlocking { + startSessionNB() + } + + fun executeCommands(commands: List<String>, timeOut: Long): String = runBlocking { + executeCommandsNB(commands, timeOut) + } + + fun executeCommand(command: String, timeOut: Long): String = runBlocking { + executeCommandNB(command, timeOut) + } + + fun closeSession() = runBlocking { + closeSessionNB() + } + + suspend fun startSessionNB(): ClientSession + + suspend fun executeCommandsNB(commands: List<String>, timeOut: Long): String + + suspend fun executeCommandNB(command: String, timeOut: Long): String + + suspend fun closeSessionNB() +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BluePrintSshLibPropertyServiceTest.kt b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BluePrintSshLibPropertyServiceTest.kt new file mode 100644 index 000000000..d5c99935c --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BluePrintSshLibPropertyServiceTest.kt @@ -0,0 +1,58 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.ssh.service + +import org.junit.Test +import org.junit.runner.RunWith +import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties +import org.onap.ccsdk.cds.blueprintsprocessor.core.BlueprintPropertyConfiguration +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.BasicAuthSshClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.BluePrintSshLibConfiguration +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.test.context.ContextConfiguration +import org.springframework.test.context.TestPropertySource +import org.springframework.test.context.junit4.SpringRunner +import kotlin.test.assertEquals +import kotlin.test.assertNotNull + + +@RunWith(SpringRunner::class) +@ContextConfiguration(classes = [BluePrintSshLibConfiguration::class, + BlueprintPropertyConfiguration::class, BluePrintProperties::class]) +@TestPropertySource(properties = +["blueprintsprocessor.sshclient.sample.type=basic-auth", + "blueprintsprocessor.sshclient.sample.host=127.0.0.1", + "blueprintsprocessor.sshclient.sample.port=22", + "blueprintsprocessor.sshclient.sample.password=1234", + "blueprintsprocessor.sshclient.sample.username=dummy" +]) +class BluePrintSshLibPropertyServiceTest { + + @Autowired + lateinit var bluePrintSshLibPropertyService: BluePrintSshLibPropertyService + + @Test + fun testRestClientProperties() { + val properties = bluePrintSshLibPropertyService + .sshClientProperties("blueprintsprocessor.sshclient.sample") as BasicAuthSshClientProperties + assertNotNull(properties, "failed to create property bean") + assertEquals(properties.host, "127.0.0.1", "failed to match host property") + assertEquals(properties.port, 22, "failed to match port property") + assertEquals(properties.password, "1234", "failed to match host property") + assertEquals(properties.username, "dummy", "failed to match host property") + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BlueprintSshClientServiceTest.kt b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BlueprintSshClientServiceTest.kt new file mode 100644 index 000000000..d61219215 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BlueprintSshClientServiceTest.kt @@ -0,0 +1,100 @@ +/* + * Copyright © 2019 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.ssh.service + +import kotlinx.coroutines.runBlocking +import org.apache.sshd.common.config.keys.KeyUtils.RSA_ALGORITHM +import org.apache.sshd.common.keyprovider.KeyPairProvider +import org.apache.sshd.server.SshServer +import org.apache.sshd.server.auth.password.PasswordAuthenticator +import org.apache.sshd.server.auth.pubkey.AcceptAllPublickeyAuthenticator +import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider +import org.apache.sshd.server.session.ServerSession +import org.apache.sshd.server.shell.ProcessShellCommandFactory +import org.junit.runner.RunWith +import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties +import org.onap.ccsdk.cds.blueprintsprocessor.core.BlueprintPropertyConfiguration +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.BluePrintSshLibConfiguration +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.test.context.ContextConfiguration +import org.springframework.test.context.TestPropertySource +import org.springframework.test.context.junit4.SpringRunner +import java.nio.file.Paths +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotNull + + +@RunWith(SpringRunner::class) +@ContextConfiguration(classes = [BluePrintSshLibConfiguration::class, + BlueprintPropertyConfiguration::class, BluePrintProperties::class]) +@TestPropertySource(properties = +["blueprintsprocessor.sshclient.sample.type=basic-auth", + "blueprintsprocessor.sshclient.sample.host=localhost", + "blueprintsprocessor.sshclient.sample.port=52815", + "blueprintsprocessor.sshclient.sample.username=root", + "blueprintsprocessor.sshclient.sample.password=dummyps" +]) +class BlueprintSshClientServiceTest { + + @Autowired + lateinit var bluePrintSshLibPropertyService: BluePrintSshLibPropertyService + + @Test + fun testBasicAuthSshClientService() { + runBlocking { + val sshServer = setupTestServer("localhost", 52815, "root", "dummyps") + sshServer.start() + println(sshServer) + val bluePrintSshLibPropertyService = bluePrintSshLibPropertyService.blueprintSshClientService("sample") + val sshSession = bluePrintSshLibPropertyService.startSession() + val response = bluePrintSshLibPropertyService.executeCommandsNB(arrayListOf("echo '1'", "echo '2'"), 2000) + assertNotNull(response, "failed to get command response") + bluePrintSshLibPropertyService.closeSession() + sshServer.stop(true) + } + } + + private fun setupTestServer(host: String, port: Int, userName: String, password: String): SshServer { + val sshd = SshServer.setUpDefaultServer() + sshd.port = port + sshd.host = host + sshd.keyPairProvider = createTestHostKeyProvider() + sshd.passwordAuthenticator = BogusPasswordAuthenticator(userName, password) + sshd.publickeyAuthenticator = AcceptAllPublickeyAuthenticator.INSTANCE + //sshd.shellFactory = EchoShellFactory() + sshd.commandFactory = ProcessShellCommandFactory.INSTANCE + return sshd + } + + private fun createTestHostKeyProvider(): KeyPairProvider { + val keyProvider = SimpleGeneratorHostKeyProvider() + keyProvider.path = Paths.get("target").resolve("hostkey." + RSA_ALGORITHM.toLowerCase()) + keyProvider.algorithm = RSA_ALGORITHM + return keyProvider + } +} + +class BogusPasswordAuthenticator(userName: String, password: String) : PasswordAuthenticator { + override fun authenticate(username: String, password: String, serverSession: ServerSession): Boolean { + assertEquals(username, "root", "failed to match username") + assertEquals(password, "dummyps", "failed to match password") + return true + } +} + + diff --git a/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/resources/logback-test.xml b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/resources/logback-test.xml new file mode 100644 index 000000000..626b8f911 --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/resources/logback-test.xml @@ -0,0 +1,35 @@ +<!-- + ~ Copyright © 2019 IBM. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<configuration> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <!-- encoders are assigned the type + ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> + <encoder> + <pattern>%d{HH:mm:ss.SSS} %-5level %logger{100} - %msg%n</pattern> + </encoder> + </appender> + + <logger name="org.springframework.test" level="warn"/> + <logger name="org.springframework" level="warn"/> + <logger name="org.hibernate" level="info"/> + <logger name="org.onap.ccsdk.cds.blueprintsprocessor" level="info"/> + + <root level="warn"> + <appender-ref ref="STDOUT"/> + </root> + +</configuration> diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt index 1e09bee8d..5a4f3dea4 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt @@ -140,10 +140,10 @@ class ExecutionServiceHandler(private val bluePrintPathConfiguration: BluePrintP val executionServiceOutput = ExecutionServiceOutput() executionServiceOutput.commonHeader = executionServiceInput.commonHeader executionServiceOutput.actionIdentifiers = executionServiceInput.actionIdentifiers + executionServiceOutput.payload = executionServiceInput.payload val status = Status() if (failure) { - executionServiceOutput.payload = JsonNodeFactory.instance.objectNode() setErrorStatus(errorMessage, status) } else { status.eventType = EventType.EVENT_COMPONENT_PROCESSING.name diff --git a/ms/blueprintsprocessor/parent/pom.xml b/ms/blueprintsprocessor/parent/pom.xml index 5f3e926f7..85d57b9fd 100755 --- a/ms/blueprintsprocessor/parent/pom.xml +++ b/ms/blueprintsprocessor/parent/pom.xml @@ -39,7 +39,10 @@ <sshd.version>2.2.0</sshd.version> <jsch.version>0.1.55</jsch.version> <protobuff.java.utils.version>3.6.1</protobuff.java.utils.version> + <spring.kafka.version>2.2.6.RELEASE</spring.kafka.version> + <kafka.version>2.2.0</kafka.version> <eelf.version>1.0.0</eelf.version> + <sli.version>${ccsdk.sli.core.version}</sli.version> <guava.version>27.0.1-jre</guava.version> <jython.version>2.7.1</jython.version> <springfox.swagger2.version>2.9.2</springfox.swagger2.version> @@ -62,6 +65,12 @@ <scope>import</scope> </dependency> + <dependency> + <groupId>org.springframework.kafka</groupId> + <artifactId>spring-kafka</artifactId> + <version>${spring.kafka.version}</version> + </dependency> + <!--Swagger Dependencies --> <dependency> <groupId>io.springfox</groupId> @@ -243,11 +252,22 @@ <version>${jsch.version}</version> </dependency> + <dependency> + <groupId>org.apache.kafka</groupId> + <artifactId>kafka-clients</artifactId> + <version>${kafka.version}</version> + </dependency> + <dependency> + <groupId>org.apache.kafka</groupId> + <artifactId>kafka-streams</artifactId> + <version>${kafka.version}</version> + </dependency> + <!-- SLI Version --> <dependency> <groupId>org.onap.ccsdk.sli.core</groupId> <artifactId>sli-provider</artifactId> - <version>${ccsdk.sli.core.version}</version> + <version>${sli.version}</version> <exclusions> <exclusion> <groupId>commons-lang</groupId> @@ -307,6 +327,11 @@ </dependency> <dependency> <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> + <artifactId>ssh-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId> <artifactId>dmaap-lib</artifactId> <version>${project.version}</version> </dependency> @@ -362,6 +387,11 @@ <artifactId>restconf-executor</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId> + <artifactId>cli-executor</artifactId> + <version>${project.version}</version> + </dependency> <!-- Controller Blueprints Application Dependency --> <dependency> @@ -435,6 +465,15 @@ <version>${grpc.version}</version> <scope>test</scope> </dependency> + + <!-- Spring Kafka --> + <dependency> + <groupId>org.springframework.kafka</groupId> + <artifactId>spring-kafka-test</artifactId> + <version>${spring.kafka.version}</version> + <scope>test</scope> + </dependency> + </dependencies> </dependencyManagement> diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt index 0e45232f2..583fc9d4d 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt @@ -122,6 +122,18 @@ fun JsonNode.rootFieldsToMap(): MutableMap<String, JsonNode> { } } +fun JsonNode.removeNullNode() { + val it = this.iterator() + while (it.hasNext()) { + val child = it.next() + if (child.isNull) { + it.remove() + } else { + child.removeNullNode() + } + } +} + fun MutableMap<String, JsonNode>.putJsonElement(key: String, value: Any) { val convertedValue = value.asJsonType() diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BlueprintTemplateService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BlueprintTemplateService.kt index ec1542cd3..86bf3ff56 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BlueprintTemplateService.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BlueprintTemplateService.kt @@ -18,21 +18,43 @@ package org.onap.ccsdk.cds.controllerblueprints.core.interfaces import com.fasterxml.jackson.core.io.CharTypes import com.fasterxml.jackson.databind.node.JsonNodeFactory import com.fasterxml.jackson.databind.node.TextNode +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService interface BlueprintTemplateService { /** * Generate dynamique content using Velocity Template or Jinja template * + * @param bluePrintRuntimeService blueprint runtime + * @param nodeTemplateName node template + * @param artifactName Artifact Name + * @param jsonData json string data content to mash + * @param ignoreJsonNull Ignore Null value in the JSON content + * @param additionalContext (Key, value) mutable map for additional variables + * @return Content result + * + **/ + suspend fun generateContent(bluePrintRuntimeService: BluePrintRuntimeService<*>, + nodeTemplateName: String, + artifactName: String, + jsonData: String = "", + ignoreJsonNull: Boolean = false, + additionalContext: MutableMap<String, Any> = mutableMapOf()): String + + + /** + * Generate dynamique content using Velocity Template or Jinja template + * * @param template template string content - * @param json json string content + * @param templateType template type + * @param jsonData json string data content to mash * @param ignoreJsonNull Ignore Null value in the JSON content * @param additionalContext (Key, value) mutable map for additional variables * @return Content result * **/ - suspend fun generateContent(template: String, json: String = "", ignoreJsonNull: Boolean = false, - additionalContext: MutableMap<String, Any> = mutableMapOf()): String + suspend fun generateContent(template: String, templateType: String, jsonData: String = "", ignoreJsonNull: Boolean = false, + additionalContext: MutableMap<String, Any> = mutableMapOf()): String } /** diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintJinjaTemplateService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintJinjaTemplateService.kt index f835cbe52..912667e0a 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintJinjaTemplateService.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintJinjaTemplateService.kt @@ -21,14 +21,13 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.hubspot.jinjava.Jinjava import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintJsonNodeFactory -import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintTemplateService -import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.onap.ccsdk.cds.controllerblueprints.core.removeNullNode -object BluePrintJinjaTemplateService: BlueprintTemplateService { +object BluePrintJinjaTemplateService { - override suspend fun generateContent(template: String, json: String, ignoreJsonNull: Boolean, - additionalContext: MutableMap<String, Any>): String { + fun generateContent(template: String, json: String, ignoreJsonNull: Boolean, + additionalContext: MutableMap<String, Any>): String { // Load template val jinJava = Jinjava() val mapper = ObjectMapper() @@ -40,7 +39,7 @@ object BluePrintJinjaTemplateService: BlueprintTemplateService { val jsonNode = mapper.readValue<JsonNode>(json, JsonNode::class.java) ?: throw BluePrintProcessorException("couldn't get json node from json") if (ignoreJsonNull) - JacksonUtils.removeJsonNullNode(jsonNode) + jsonNode.removeNullNode() jsonNode.fields().forEach { entry -> additionalContext[entry.key] = entry.value } diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintVelocityTemplateService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintVelocityTemplateService.kt index 4b6905bff..43e6d221f 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintVelocityTemplateService.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintVelocityTemplateService.kt @@ -26,35 +26,50 @@ import org.apache.velocity.VelocityContext import org.apache.velocity.app.Velocity import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintJsonNodeFactory -import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintTemplateService -import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.onap.ccsdk.cds.controllerblueprints.core.removeNullNode import java.io.StringWriter -object BluePrintVelocityTemplateService: BlueprintTemplateService { +object BluePrintVelocityTemplateService { /** - * Generate Content from Velocity Template and JSON Content or property map. + * Generate Content from Velocity Template and JSON Content with injected API */ - override suspend fun generateContent(template: String, json: String, ignoreJsonNull: Boolean, additionalContext: - MutableMap<String, Any>): String { - Velocity.init() + fun generateContent(template: String, json: String, ignoreJsonNull: Boolean = false, + additionalContext: MutableMap<String, Any> = mutableMapOf()): String { + + // Customized Object Mapper to remove String double quotes val mapper = ObjectMapper() val nodeFactory = BluePrintJsonNodeFactory() mapper.nodeFactory = nodeFactory + val jsonNode: JsonNode? = if (json.isNotEmpty()) { + mapper.readValue(json, JsonNode::class.java) + ?: throw BluePrintProcessorException("couldn't get json node from json") + } else { + null + } + return generateContent(template, jsonNode, ignoreJsonNull, additionalContext) + } + + /** + * Generate Content from Velocity Template and JSON Node with injected API + */ + fun generateContent(template: String, jsonNode: JsonNode?, ignoreJsonNull: Boolean = false, + additionalContext: MutableMap<String, Any> = mutableMapOf()): String { + + Velocity.init() + val velocityContext = VelocityContext() velocityContext.put("StringUtils", StringUtils::class.java) velocityContext.put("BooleanUtils", BooleanUtils::class.java) // Add the Custom Velocity Context API - additionalContext.forEach { name, value -> velocityContext.put(name, value) } + additionalContext.forEach { (name, value) -> velocityContext.put(name, value) } // Add the JSON Data to the context - if (json.isNotEmpty()) { - val jsonNode = mapper.readValue<JsonNode>(json, JsonNode::class.java) - ?: throw BluePrintProcessorException("couldn't get json node from json") + if (jsonNode != null) { if (ignoreJsonNull) - JacksonUtils.removeJsonNullNode(jsonNode) + jsonNode.removeNullNode() jsonNode.fields().forEach { entry -> velocityContext.put(entry.key, entry.value) } @@ -64,6 +79,6 @@ object BluePrintVelocityTemplateService: BlueprintTemplateService { Velocity.evaluate(velocityContext, stringWriter, "TemplateData", template) stringWriter.flush() return stringWriter.toString() + } } - diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BlueprintTemplateService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BlueprintTemplateService.kt index 73457b986..45e2678ed 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BlueprintTemplateService.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BlueprintTemplateService.kt @@ -20,19 +20,26 @@ import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintTemplateService import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils -class BluePrintTemplateService(val bluePrintRuntimeService: BluePrintRuntimeService<*>, - val nodeTemplateName: String, val artifactName: String): - BlueprintTemplateService { +class BluePrintTemplateService : BlueprintTemplateService { + + override suspend fun generateContent(bluePrintRuntimeService: BluePrintRuntimeService<*>, + nodeTemplateName: String, artifactName: String, jsonData: String, + ignoreJsonNull: Boolean, additionalContext: MutableMap<String, Any>): String { - override suspend fun generateContent(template: String, json: String, ignoreJsonNull: Boolean, additionalContext: MutableMap<String, Any>): String { val artifactDefinition = bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName) val templateType = artifactDefinition.type + val template = bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName) + return generateContent(template, templateType, jsonData, ignoreJsonNull, additionalContext) + } + + override suspend fun generateContent(template: String, templateType: String, jsonData: String, ignoreJsonNull: Boolean, + additionalContext: MutableMap<String, Any>): String { return when (templateType) { BluePrintConstants.ARTIFACT_JINJA_TYPE_NAME -> { - BluePrintJinjaTemplateService.generateContent(template, json, ignoreJsonNull, additionalContext) + BluePrintJinjaTemplateService.generateContent(template, jsonData, ignoreJsonNull, additionalContext) } BluePrintConstants.ARTIFACT_VELOCITY_TYPE_NAME -> { - BluePrintVelocityTemplateService.generateContent(template, json, ignoreJsonNull, additionalContext) + BluePrintVelocityTemplateService.generateContent(template, jsonData, ignoreJsonNull, additionalContext) } else -> { throw BluePrintProcessorException("Unknown Artifact type, expecting ${BluePrintConstants.ARTIFACT_JINJA_TYPE_NAME}" + @@ -41,9 +48,11 @@ class BluePrintTemplateService(val bluePrintRuntimeService: BluePrintRuntimeServ } } - suspend fun generateContentFromFiles(templatePath: String, jsonPath: String, ignoreJsonNull: Boolean, additionalContext: MutableMap<String, Any>): String { + suspend fun generateContentFromFiles(templatePath: String, templateType: String, jsonPath: String, + ignoreJsonNull: Boolean, + additionalContext: MutableMap<String, Any>): String { val json = JacksonUtils.getClassPathFileContent(jsonPath) val template = JacksonUtils.getClassPathFileContent(templatePath) - return generateContent(template, json, ignoreJsonNull, additionalContext) + return generateContent(template, templateType, json, ignoreJsonNull, additionalContext) } }
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt index 7b5f181da..5e9fd6207 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt @@ -58,19 +58,6 @@ class JacksonUtils { return objectMapper.treeToValue(node, valueType) } - fun removeJsonNullNode(node: JsonNode) { - val it = node.iterator() - while (it.hasNext()) { - val child = it.next() - if (child.isNull) { - it.remove() - } else { - removeJsonNullNode(child) - } - } - } - - fun getContent(fileName: String): String = runBlocking { try { normalizedFile(fileName).readNBText() diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateServiceTest.kt b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateServiceTest.kt index e4227180b..6f961c8ed 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateServiceTest.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateServiceTest.kt @@ -21,10 +21,12 @@ package org.onap.ccsdk.cds.controllerblueprints.core.service import kotlinx.coroutines.runBlocking import org.junit.Test import org.junit.runner.RunWith +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.springframework.test.context.junit4.SpringRunner import kotlin.test.BeforeTest +import kotlin.test.assertEquals import kotlin.test.assertNotNull @RunWith(SpringRunner::class) @@ -40,13 +42,13 @@ class BluePrintTemplateServiceTest { @Test fun testVelocityGeneratedContent() { - runBlocking { - val template = JacksonUtils.getClassPathFileContent("templates/base-config-velocity-template.vtl") - val json = JacksonUtils.getClassPathFileContent("templates/base-config-data-velocity.json") + runBlocking { + val template = JacksonUtils.getClassPathFileContent("templates/base-config-velocity-template.vtl") + val json = JacksonUtils.getClassPathFileContent("templates/base-config-data-velocity.json") - val content = BluePrintVelocityTemplateService.generateContent(template, json) - assertNotNull(content, "failed to generate content for velocity template") - } + val content = BluePrintVelocityTemplateService.generateContent(template, json) + assertNotNull(content, "failed to generate content for velocity template") + } } @@ -68,13 +70,12 @@ class BluePrintTemplateServiceTest { @Test fun testVelocityGeneratedContentFromFiles() { runBlocking { - val bluePrintTemplateService = BluePrintTemplateService(blueprintRuntime, - "resource-assignment", "baseconfig-template") + val bluePrintTemplateService = BluePrintTemplateService() val templateFile = "templates/base-config-velocity-template.vtl" val jsonFile = "templates/base-config-data-velocity.json" val content = bluePrintTemplateService.generateContentFromFiles( - templateFile, jsonFile, false, mutableMapOf()) + templateFile, BluePrintConstants.ARTIFACT_VELOCITY_TYPE_NAME, jsonFile, false, mutableMapOf()) assertNotNull(content, "failed to generate content for velocity template") } @@ -86,17 +87,50 @@ class BluePrintTemplateServiceTest { var element: MutableMap<String, Any> = mutableMapOf() element["additional_array"] = arrayListOf(hashMapOf("name" to "Element1", "location" to "Region0"), hashMapOf("name" to "Element2", "location" to "Region1")) - val bluePrintTemplateService = BluePrintTemplateService(blueprintRuntime, - "resource-assignment", "another-template") + val bluePrintTemplateService = BluePrintTemplateService() val templateFile = "templates/base-config-jinja-template.jinja" val jsonFile = "templates/base-config-data-jinja.json" val content = bluePrintTemplateService.generateContentFromFiles( - templateFile, + templateFile, BluePrintConstants.ARTIFACT_JINJA_TYPE_NAME, jsonFile, false, element) assertNotNull(content, "failed to generate content for velocity template") } } + + @Test + fun `no value variable should evaluate to default value - standalone template mesh test`() { + runBlocking { + val template = JacksonUtils.getClassPathFileContent("templates/default-variable-value-velocity-template.vtl") + val json = JacksonUtils.getClassPathFileContent("templates/default-variable-value-data.json") + + val content = BluePrintVelocityTemplateService.generateContent(template, json) + //first line represents a variable whose value was successfully retrieved, second line contains a variable + // whose value could not be evaluated + val expected = "sample-hostname\n\${node0_backup_router_address}" + assertEquals(expected, content, "No value variable should use default value") + } + } + + @Test + fun `no value variable should evaluate to default value - blueprint processing test`() { + runBlocking { + val bluePrintTemplateService = BluePrintTemplateService() + + val templateFile = "templates/default-variable-value-velocity-template.vtl" + val jsonFile = "templates/default-variable-value-data.json" + + val content = bluePrintTemplateService.generateContentFromFiles(templateFile, + BluePrintConstants.ARTIFACT_VELOCITY_TYPE_NAME, jsonFile, false, mutableMapOf()) + + //first line represents a variable whose value was successfully retrieved, second line contains a variable + // whose value could not be evaluated + val expected = "sample-hostname\n\${node0_backup_router_address}" + assertEquals(expected, content, "No value variable should use default value") + } + + } + } diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/default-variable-value-data.json b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/default-variable-value-data.json new file mode 100755 index 000000000..940ca8d73 --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/default-variable-value-data.json @@ -0,0 +1,3 @@ +{ + "node0_hostname": "sample-hostname" +} diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/default-variable-value-velocity-template.vtl b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/default-variable-value-velocity-template.vtl new file mode 100755 index 000000000..ce2458e2e --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/default-variable-value-velocity-template.vtl @@ -0,0 +1,2 @@ +$node0_hostname +${node0_backup_router_address}
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/resource-dict/load/resource_dictionary/vnf-name.json b/ms/controllerblueprints/modules/resource-dict/load/resource_dictionary/vnf-name.json index 4c0320aca..bcfea9f24 100644 --- a/ms/controllerblueprints/modules/resource-dict/load/resource_dictionary/vnf-name.json +++ b/ms/controllerblueprints/modules/resource-dict/load/resource_dictionary/vnf-name.json @@ -7,21 +7,41 @@ "type" : "string" }, "sources" : { - "primary-config-data" : { - "type" : "source-rest", - "properties" : { - "type" : "JSON", - "url-path" : "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf_name", - "path" : "/param/0/value", - "expression-type" : "JSON_POINTER", - "input-key-mapping" : { - "service-instance-id" : "service-instance-id", - "vnf-id" : "vnf-id" + "primary-config-data": { + "type": "source-rest", + "properties": { + "type": "JSON", + "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-name/vnf-data/vnf-topology/vnf-parameters-data/param/vnf-name", + "path": "/param/0/value", + "input-key-mapping": { + "service-instance-id": "service-instance-id", + "vnf-name": "vnf-name" }, - "output-key-mapping" : { - "vnf-name" : "value" + "output-key-mapping": { + "vnf-name": "value" }, - "key-dependencies" : [ "service-instance-id", "vnf-id" ] + "key-dependencies": [ + "service-instance-id", + "vnf-name" + ] + } + }, + "primary-aai-data": { + "type": "source-rest", + "properties": { + "type": "JSON", + "verb": "GET", + "url-path": "/aai/v14/network/generic-vnfs/generic-vnf/$vnf-id", + "path": "", + "input-key-mapping": { + "vnf-id": "vnf-id" + }, + "output-key-mapping": { + "vnf-name": "vnf-name" + }, + "key-dependencies": [ + "vnf-id" + ] } } } diff --git a/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt b/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt index d06d5db9a..b4c29dec3 100644 --- a/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt +++ b/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt @@ -23,9 +23,11 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.onap.ccsdk.cds.controllerblueprints.TestApplication +import org.onap.ccsdk.cds.controllerblueprints.core.compress import org.onap.ccsdk.cds.controllerblueprints.core.deleteDir import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintEnhancerService import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintValidatorService +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName import org.onap.ccsdk.cds.controllerblueprints.service.load.ModelTypeLoadService import org.onap.ccsdk.cds.controllerblueprints.service.load.ResourceDictionaryLoadService @@ -113,6 +115,10 @@ class BluePrintEnhancerServiceImplTest { val valid = bluePrintValidatorService.validateBluePrints(targetPath) Assert.assertTrue("blueprint($basePath) validation failed ", valid) + // Enable this to get the enhanced zip file +// val compressFile = normalizedFile("target/blueprints/enrichment", "$targetDirName.zip") +// normalizedFile(targetPath).compress(compressFile) + deleteDir(targetPath) } } |