diff options
Diffstat (limited to 'ms/blueprintsprocessor/functions')
32 files changed, 1340 insertions, 486 deletions
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 deleted file mode 100644 index 65d1c3eee..000000000 --- a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt +++ /dev/null @@ -1,56 +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 - -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() - } - - 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(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/ComponentCliExecutor.kt b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutor.kt index 0c1c52320..e1d8825ba 100644 --- 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 @@ -16,12 +16,8 @@ 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.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentScriptExecutor import org.springframework.beans.factory.config.ConfigurableBeanFactory import org.springframework.context.annotation.Scope import org.springframework.stereotype.Component @@ -29,43 +25,4 @@ 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 + : ComponentScriptExecutor(componentFunctionScriptingService)
\ 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/ScriptComponentExtensions.kt b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ScriptComponentExtensions.kt new file mode 100644 index 000000000..81f1fd821 --- /dev/null +++ b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ScriptComponentExtensions.kt @@ -0,0 +1,22 @@ +/* + * 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 + +/** + * Register the CLI module exposed dependency + */ + 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 index 0955ace79..e62374747 100644 --- 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 @@ -17,22 +17,23 @@ @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.blueprintsprocessor.services.execution.AbstractScriptComponentFunction +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentScriptExecutor +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.sshClientService import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive -import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService import org.slf4j.LoggerFactory -open class TestCliScriptFunction : CliComponentFunction() { +open class TestCliScriptFunction : AbstractScriptComponentFunction() { - private val log = LoggerFactory.getLogger(CliComponentFunction::class.java)!! + private val log = LoggerFactory.getLogger(TestCliScriptFunction::class.java.canonicalName)!! override fun getName(): String { return "SimpleCliConfigure" } override suspend fun processNB(executionRequest: ExecutionServiceInput) { - log.info("Executing process") + log.info("Executing process ...") } override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { @@ -41,9 +42,9 @@ open class TestCliScriptFunction : CliComponentFunction() { } -open class Check : CliComponentFunction() { +open class Check : AbstractScriptComponentFunction() { - private val log = LoggerFactory.getLogger(CliComponentFunction::class.java)!! + private val log = LoggerFactory.getLogger(AbstractScriptComponentFunction::class.java)!! override fun getName(): String { return "Check" @@ -54,12 +55,12 @@ open class Check : CliComponentFunction() { val deviceInformation = bluePrintRuntimeService.resolveDSLExpression("device-properties") // Get the Client Service - val sshClientService = bluePrintSshLibPropertyService().blueprintSshClientService(deviceInformation) + val sshClientService = BluePrintDependencyService.sshClientService(deviceInformation) sshClientService.startSessionNB() // Read Commands - val commands = readCommandLinesFromArtifact("command-template") + val commands = readLinesFromArtifact("command-template") // Execute multiple Commands val responseLog = sshClientService.executeCommandsNB(commands, 5000) @@ -68,7 +69,7 @@ open class Check : CliComponentFunction() { sshClientService.closeSessionNB() // Set the Response Data - setAttribute(ComponentCliExecutor.RESPONSE_DATA, responseLog.asJsonPrimitive()) + setAttribute(ComponentScriptExecutor.RESPONSE_DATA, responseLog.asJsonPrimitive()) log.info("Executing process") } 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 index 6455513f2..658092f0a 100644 --- 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 @@ -17,7 +17,6 @@ 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 @@ -30,11 +29,13 @@ 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.ComponentScriptExecutor 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.BluePrintDependencyService 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 @@ -49,7 +50,7 @@ import kotlin.test.assertNotNull @ContextConfiguration(classes = [CliExecutorConfiguration::class, ExecutionServiceConfiguration::class, BluePrintSshLibConfiguration::class, BluePrintScriptsServiceImpl::class, - BlueprintPropertyConfiguration::class, BluePrintProperties::class]) + BlueprintPropertyConfiguration::class, BluePrintProperties::class, BluePrintDependencyService::class]) @DirtiesContext @TestPropertySource(properties = [], locations = ["classpath:application-test.properties"]) class ComponentCliExecutorTest { @@ -78,10 +79,9 @@ class ComponentCliExecutorTest { 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] = + operationInputs[ComponentScriptExecutor.SCRIPT_TYPE] = BluePrintConstants.SCRIPT_INTERNAL.asJsonPrimitive() + operationInputs[ComponentScriptExecutor.SCRIPT_CLASS_REFERENCE] = "InternalSimpleCli_cba\$TestCliScriptFunction".asJsonPrimitive() - operationInputs[ComponentCliExecutor.INSTANCE_DEPENDENCIES] = JacksonUtils.jsonNode("[]") as ArrayNode val stepInputData = StepData().apply { name = "activate-cli" diff --git a/ms/blueprintsprocessor/functions/netconf-executor/pom.xml b/ms/blueprintsprocessor/functions/netconf-executor/pom.xml index a46e7433d..ca5423432 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/pom.xml +++ b/ms/blueprintsprocessor/functions/netconf-executor/pom.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - ~ Copyright © 2017-2018 AT&T Intellectual Property. + ~ Copyright © 2017-2019 AT&T, Bell Canada. ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. @@ -32,12 +32,6 @@ <artifactId>resource-resolution</artifactId> </dependency> <dependency> - <groupId>org.codehaus.jettison</groupId> - <artifactId>jettison</artifactId> - <version>${jettison.version}</version> - <scope>provided</scope> - </dependency> - <dependency> <groupId>org.apache.sshd</groupId> <artifactId>sshd-core</artifactId> </dependency> diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt index 4cec6a2bf..5e0b4a117 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt @@ -17,51 +17,48 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor -import com.fasterxml.jackson.databind.JsonNode import kotlinx.coroutines.runBlocking -import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo 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.controllerblueprints.core.utils.JacksonUtils +@Deprecated("Methods defined as extension function of AbstractComponentFunction") abstract class NetconfComponentFunction : AbstractScriptComponentFunction() { + @Deprecated(" Use resourceResolutionService method directly", + replaceWith = ReplaceWith("resourceResolutionService()", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resourceResolutionService")) open fun resourceResolutionService(): ResourceResolutionService = functionDependencyInstanceAsType(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) // Called from python script + @Deprecated(" Use netconfDeviceInfo method directly", + replaceWith = ReplaceWith("netconfDeviceInfo(requirementName)", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.netconfDeviceInfo")) fun initializeNetconfConnection(requirementName: String): NetconfDevice { - val deviceInfo = deviceProperties(requirementName) + val deviceInfo = netconfDeviceInfo(requirementName) return NetconfDevice(deviceInfo) } + @Deprecated(" Use artifactContent method directly", + replaceWith = ReplaceWith("artifactContent(artifactName)", + "org.onap.ccsdk.cds.blueprintsprocessor.services.execution.artifactContent")) fun generateMessage(artifactName: String): String { return bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName) } + @Deprecated(" Use storedContentFromResolvedArtifact method directly", + replaceWith = ReplaceWith("storedContentFromResolvedArtifact(resolutionKey, artifactName)", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.storedContentFromResolvedArtifact")) fun resolveFromDatabase(resolutionKey: String, artifactName: String): String = runBlocking { resourceResolutionService().resolveFromDatabase(bluePrintRuntimeService, artifactName, resolutionKey) } + @Deprecated(" Use contentFromResolvedArtifact method directly", + replaceWith = ReplaceWith("resolveAndGenerateMessage(artifactPrefix)", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resolveAndGenerateMessage")) fun resolveAndGenerateMessage(artifactPrefix: String): String = runBlocking { resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName, artifactPrefix, mapOf()) } - - private fun deviceProperties(requirementName: String): DeviceInfo { - - val blueprintContext = bluePrintRuntimeService.bluePrintContext() - - val requirement = blueprintContext.nodeTemplateRequirement(nodeTemplateName, requirementName) - - val capabilityProperties = bluePrintRuntimeService.resolveNodeTemplateCapabilityProperties(requirement - .node!!, requirement.capability!!) - - return deviceProperties(capabilityProperties) - } - - private fun deviceProperties(capabilityProperty: MutableMap<String, JsonNode>): DeviceInfo { - return JacksonUtils.getInstanceFromMap(capabilityProperty, DeviceInfo::class.java) - } }
\ 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/ScriptComponentExtensions.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/ScriptComponentExtensions.kt new file mode 100644 index 000000000..bac211ab2 --- /dev/null +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/ScriptComponentExtensions.kt @@ -0,0 +1,53 @@ +/* + * 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 com.fasterxml.jackson.databind.JsonNode +import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo +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.AbstractComponentFunction +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService +import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils + +/** + * Register the Netconf module exposed dependency + */ +fun BluePrintDependencyService.netconfClientService(): ResourceResolutionService = + instance(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) + + +fun AbstractComponentFunction.netconfDevice(requirementName: String): NetconfDevice { + val deviceInfo = netconfDeviceInfo(requirementName) + return NetconfDevice(deviceInfo) +} + +fun AbstractComponentFunction.netconfDeviceInfo(requirementName: String): DeviceInfo { + + val blueprintContext = bluePrintRuntimeService.bluePrintContext() + + val requirement = blueprintContext.nodeTemplateRequirement(nodeTemplateName, requirementName) + + val capabilityProperties = bluePrintRuntimeService.resolveNodeTemplateCapabilityProperties(requirement + .node!!, requirement.capability!!) + + return netconfDeviceInfo(capabilityProperties) +} + +private fun AbstractComponentFunction.netconfDeviceInfo(capabilityProperty: MutableMap<String, JsonNode>): DeviceInfo { + return JacksonUtils.getInstanceFromMap(capabilityProperty, DeviceInfo::class.java) +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt index 2de22424e..c45fb881f 100644 --- a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt +++ b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt @@ -16,6 +16,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.python.executor +import com.fasterxml.jackson.databind.JsonNode import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.* import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ExecutionServiceConstant @@ -75,8 +76,19 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic val dynamicProperties = getOptionalOperationInput(INPUT_DYNAMIC_PROPERTIES) val packages = getOptionalOperationInput(INPUT_PACKAGES)?.returnNullIfMissing() - val args = getOptionalOperationInput(INPUT_ARGUMENT_PROPERTIES)?.returnNullIfMissing() - ?.rootFieldsToMap()?.toSortedMap()?.values?.map { it.textValue() }?.joinToString(" ") + val argsNode = getOptionalOperationInput(INPUT_ARGUMENT_PROPERTIES)?.returnNullIfMissing() + + // This prevents unescaping values, as well as quoting the each parameter, in order to allow for spaces in values + var args = "" + argsNode?.fields()?.forEach { + if (it.value.isValueNode) { + args = "$args ${it.value}" + } else { + it.value.fields().forEach { item -> + args = "$args ${item.value}" + } + } + } val command = getOperationInput(INPUT_COMMAND).asText() var scriptCommand = command.replace(pythonScript.name, pythonScript.absolutePath) diff --git a/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt b/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt index 166d7b136..31aa7c7c1 100644 --- a/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt +++ b/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt @@ -48,11 +48,12 @@ class ComponentRemotePythonExecutorTest { val componentRemotePythonExecutor = ComponentRemotePythonExecutor(remoteScriptExecutionService) - val executionServiceInput = JacksonUtils.readValueFromClassPathFile("payload/requests/sample-activate-request.json", + val executionServiceInput = + JacksonUtils.readValueFromClassPathFile("payload/requests/sample-activate-request.json", ExecutionServiceInput::class.java)!! val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("123456-1000", - "./../../../../components/model-catalog/blueprint-model/test-blueprint/remote_scripts") + "./../../../../components/model-catalog/blueprint-model/test-blueprint/remote_scripts") val stepMetaData: MutableMap<String, JsonNode> = hashMapOf() stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, "execute-remote-python") @@ -76,14 +77,17 @@ class ComponentRemotePythonExecutorTest { fun testComponentRemotePythonExecutorProcessNB() { runBlocking { val remoteScriptExecutionService = - MockRemoteScriptExecutionService() + MockRemoteScriptExecutionService() val componentRemotePythonExecutor = ComponentRemotePythonExecutor( - remoteScriptExecutionService) + remoteScriptExecutionService) val bluePrintRuntime = mockk<DefaultBluePrintRuntimeService>( - "123456-1000") - val input = getMockedOutput(bluePrintRuntime) + "123456-1000") + + every { bluePrintRuntime.setNodeTemplateAttributeValue(any(), any(), any()) } answers {} + + val input = getMockedOutput(bluePrintRuntime) componentRemotePythonExecutor.bluePrintRuntimeService = - bluePrintRuntime + bluePrintRuntime componentRemotePythonExecutor.applyNB(input) } } @@ -96,13 +100,13 @@ class ComponentRemotePythonExecutorTest { val stepMetaData: MutableMap<String, JsonNode> = hashMapOf() stepMetaData.putJsonElement( - BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, - "execute-remote-python") + BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, + "execute-remote-python") stepMetaData.putJsonElement( - BluePrintConstants.PROPERTY_CURRENT_INTERFACE, - "ComponentRemotePythonExecutor") + BluePrintConstants.PROPERTY_CURRENT_INTERFACE, + "ComponentRemotePythonExecutor") stepMetaData.putJsonElement( - BluePrintConstants.PROPERTY_CURRENT_OPERATION, "process") + BluePrintConstants.PROPERTY_CURRENT_OPERATION, "process") val mapper = ObjectMapper() val rootNode = mapper.createObjectNode() @@ -111,13 +115,13 @@ class ComponentRemotePythonExecutorTest { val operationalInputs: MutableMap<String, JsonNode> = hashMapOf() operationalInputs.putJsonElement( - BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, - "execute-remote-python") + BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, + "execute-remote-python") operationalInputs.putJsonElement( - BluePrintConstants.PROPERTY_CURRENT_INTERFACE, - "ComponentRemotePythonExecutor") + BluePrintConstants.PROPERTY_CURRENT_INTERFACE, + "ComponentRemotePythonExecutor") operationalInputs.putJsonElement( - BluePrintConstants.PROPERTY_CURRENT_OPERATION, "process") + BluePrintConstants.PROPERTY_CURRENT_OPERATION, "process") operationalInputs.putJsonElement("endpoint-selector", "aai") operationalInputs.putJsonElement("dynamic-properties", rootNode) operationalInputs.putJsonElement("command", "./run.sh") @@ -125,8 +129,8 @@ class ComponentRemotePythonExecutorTest { every { svc.resolveNodeTemplateInterfaceOperationInputs( - "execute-remote-python", - "ComponentRemotePythonExecutor", "process") + "execute-remote-python", + "ComponentRemotePythonExecutor", "process") } returns operationalInputs val stepInputData = StepData().apply { @@ -135,42 +139,42 @@ class ComponentRemotePythonExecutorTest { } val executionServiceInput = JacksonUtils - .readValueFromClassPathFile( - "payload/requests/sample-remote-python-request.json", - ExecutionServiceInput::class.java)!! + .readValueFromClassPathFile( + "payload/requests/sample-remote-python-request.json", + ExecutionServiceInput::class.java)!! executionServiceInput.stepData = stepInputData val operationOutputs = hashMapOf<String, JsonNode>() every { svc.resolveNodeTemplateInterfaceOperationOutputs( - "execute-remote-python", - "ComponentRemotePythonExecutor", "process") + "execute-remote-python", + "ComponentRemotePythonExecutor", "process") } returns operationOutputs val bluePrintRuntimeService = BluePrintMetadataUtils - .getBluePrintRuntime("123456-1000", - "./../../../../components/model-" + - "catalog/blueprint-model/test-blueprint/" + - "remote_scripts") + .getBluePrintRuntime("123456-1000", + "./../../../../components/model-" + + "catalog/blueprint-model/test-blueprint/" + + "remote_scripts") every { svc.resolveNodeTemplateArtifactDefinition( - "execute-remote-python", "component-script") - } returns bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition( "execute-remote-python", "component-script") + } returns bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition( + "execute-remote-python", "component-script") every { svc.setNodeTemplateAttributeValue( - "execute-remote-python", "prepare-environment-logs", - "prepared successfully".asJsonPrimitive()) + "execute-remote-python", "prepare-environment-logs", + "prepared successfully".asJsonPrimitive()) } returns Unit every { svc.setNodeTemplateAttributeValue( - "execute-remote-python", - "execute-command-logs", "N/A".asJsonPrimitive()) + "execute-remote-python", + "execute-command-logs", "N/A".asJsonPrimitive()) } returns Unit every { svc.setNodeTemplateAttributeValue( - "execute-remote-python", - "execute-command-logs", - "processed successfully".asJsonPrimitive()) + "execute-remote-python", + "execute-command-logs", + "processed successfully".asJsonPrimitive()) } returns Unit every { diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt index 7c2c11c06..ee7c31ad2 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt @@ -20,6 +20,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution import com.fasterxml.jackson.databind.node.JsonNodeFactory import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode import org.onap.ccsdk.cds.controllerblueprints.core.asObjectNode import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils @@ -34,24 +35,38 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re override suspend fun processNB(executionRequest: ExecutionServiceInput) { - val occurrence = getOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE) - val key = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY) - val storeResult = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT) - val resourceId = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID) - val resourceType = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE) - + val occurrence = getOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE).asInt() + val resolutionKey = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY)?.asText() ?: "" + val storeResult = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)?.asBoolean() ?: false + val resourceId = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID)?.asText() ?: "" + val resourceType = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE)?.asText() ?: "" val properties: MutableMap<String, Any> = mutableMapOf() - properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = storeResult?.asBoolean() ?: false - properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] = key?.asText() ?: "" - properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId?.asText() ?: "" - properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType?.asText() ?: "" + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = storeResult + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] = resolutionKey + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = occurrence + + val jsonResponse = JsonNodeFactory.instance.objectNode() + + // validate inputs if we need to store the resource and template resolution. + if (storeResult) { + if (resolutionKey.isNotEmpty() && (resourceId.isNotEmpty() || resourceType.isNotEmpty())) { + throw BluePrintProcessorException("Can't proceed with the resolution: either provide resolution-key OR combination of resource-id and resource-type.") + } else if ((resourceType.isNotEmpty() && resourceId.isEmpty()) || (resourceType.isEmpty() && resourceId.isNotEmpty())) { + throw BluePrintProcessorException("Can't proceed with the resolution: both resource-id and resource-type should be provided, one of them is missing.") + } else if (resourceType.isEmpty() && resourceId.isEmpty() && resolutionKey.isEmpty()) { + throw BluePrintProcessorException("Can't proceed with the resolution: can't persist resolution without a correlation key. " + + "Either provide a resolution-key OR combination of resource-id and resource-type OR set `storeResult` to false.") + } + } val artifactPrefixNamesNode = getOperationInput(ResourceResolutionConstants.INPUT_ARTIFACT_PREFIX_NAMES) val artifactPrefixNames = JacksonUtils.getListFromJsonNode(artifactPrefixNamesNode, String::class.java) - val jsonResponse = JsonNodeFactory.instance.objectNode() - for (j in 1..occurrence.asInt()) { + for (j in 1..occurrence) { + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = j val response = resourceResolutionService.resolveResources(bluePrintRuntimeService, nodeTemplateName, @@ -59,11 +74,12 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re properties) // provide indexed result in output if we have multiple resolution - if (occurrence.asInt() != 1) { - jsonResponse.set(key?.asText() + "-" + j, response.asJsonNode()) + if (occurrence != 1) { + jsonResponse.set(Integer.toString(j), response.asJsonNode()) } else { jsonResponse.setAll(response.asObjectNode()) } + } // Set Output Attributes diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt index 929e9e8df..fb32aa78b 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt @@ -24,7 +24,7 @@ object ResourceResolutionConstants { const val INPUT_ARTIFACT_PREFIX_NAMES = "artifact-prefix-names" const val OUTPUT_ASSIGNMENT_PARAMS = "assignment-params" const val FILE_NAME_RESOURCE_DEFINITION_TYPES = "resources_definition_types.json" - const val RESOURCE_RESOLUTION_INPUT_KEY = "resolution-key" + const val RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY = "resolution-key" const val RESOURCE_RESOLUTION_INPUT_STORE_RESULT = "store-result" const val RESOURCE_RESOLUTION_INPUT_OCCURRENCE = "occurrence" const val RESOURCE_RESOLUTION_INPUT_RESOURCE_ID = "resource-id" 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 b1482934f..0e97267da 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 @@ -20,11 +20,14 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolution import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionDBService -import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionResultService +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolutionService 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.BluePrintConstants import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService @@ -58,7 +61,7 @@ interface ResourceResolutionService { @Service(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) open class ResourceResolutionServiceImpl(private var applicationContext: ApplicationContext, - private var resolutionResultService: ResourceResolutionResultService, + private var templateResolutionDBService: TemplateResolutionService, private var blueprintTemplateService: BluePrintTemplateService, private var resourceResolutionDBService: ResourceResolutionDBService) : ResourceResolutionService { @@ -74,22 +77,30 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica override suspend fun resolveFromDatabase(bluePrintRuntimeService: BluePrintRuntimeService<*>, artifactTemplate: String, resolutionKey: String): String { - return resolutionResultService.read(bluePrintRuntimeService, artifactTemplate, resolutionKey) + return templateResolutionDBService.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName( + bluePrintRuntimeService, + artifactTemplate, + resolutionKey) } override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String, artifactNames: List<String>, properties: Map<String, Any>): MutableMap<String, String> { + + val resourceAssignmentRuntimeService = + ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService, artifactNames.toString()) + val resolvedParams: MutableMap<String, String> = hashMapOf() artifactNames.forEach { artifactName -> - val resolvedContent = resolveResources(bluePrintRuntimeService, nodeTemplateName, + val resolvedContent = resolveResources(resourceAssignmentRuntimeService, nodeTemplateName, artifactName, properties) resolvedParams[artifactName] = resolvedContent } return resolvedParams } + override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String, artifactPrefix: String, properties: Map<String, Any>): String { @@ -109,6 +120,13 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica as? MutableList<ResourceAssignment> ?: throw BluePrintProcessorException("couldn't get Dictionary Definitions") + if (isToStore(properties)) { + val existingResourceResolution = isNewResolution(bluePrintRuntimeService, properties, artifactPrefix) + if (existingResourceResolution.isNotEmpty()) { + updateResourceAssignmentWithExisting(existingResourceResolution, resourceAssignments) + } + } + // Get the Resource Dictionary Name val resourceDefinitions: MutableMap<String, ResourceDefinition> = ResourceAssignmentUtils .resourceDefinitions(bluePrintRuntimeService.bluePrintContext().rootPath) @@ -126,10 +144,9 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica resolvedContent = blueprintTemplateService.generateContent(bluePrintRuntimeService, nodeTemplateName, artifactTemplate, resolvedParamJsonContent) - if (properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT) - && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean) { - resolutionResultService.write(properties, resolvedContent, bluePrintRuntimeService, artifactPrefix) - log.info("template resolution saved into database successfully : ($properties)") + if (isToStore(properties)) { + templateResolutionDBService.write(properties, resolvedContent, bluePrintRuntimeService, artifactPrefix) + log.info("Template resolution saved into database successfully : ($properties)") } return resolvedContent @@ -147,20 +164,19 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica properties: Map<String, Any>) { val bulkSequenced = BulkResourceSequencingUtils.process(resourceAssignments) - val resourceAssignmentRuntimeService = - ResourceAssignmentUtils.transformToRARuntimeService(blueprintRuntimeService, artifactPrefix) + val resourceAssignmentRuntimeService = blueprintRuntimeService as ResourceAssignmentRuntimeService coroutineScope { bulkSequenced.forEach { batchResourceAssignments -> // Execute Non Dependent Assignments in parallel ( ie asynchronously ) - val deferred = batchResourceAssignments.filter { it.name != "*" && it.name != "start" } + val deferred = batchResourceAssignments + .filter { it.name != "*" && it.name != "start" } + .filter { it.status != BluePrintConstants.STATUS_SUCCESS } .map { resourceAssignment -> async { val dictionaryName = resourceAssignment.dictionaryName val dictionarySource = resourceAssignment.dictionarySource - /** - * Get the Processor name - */ + val processorName = processorName(dictionaryName!!, dictionarySource!!, resourceDefinitions) val resourceAssignmentProcessor = @@ -175,13 +191,12 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica // Invoke Apply Method resourceAssignmentProcessor.applyNB(resourceAssignment) - if (properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT) - && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean) { + if (isToStore(properties)) { resourceResolutionDBService.write(properties, blueprintRuntimeService, artifactPrefix, resourceAssignment) - log.info("resolution saved into database successfully : ($resourceAssignment)") + log.info("Resource resolution saved into database successfully : ($resourceAssignment)") } // Set errors from RA @@ -199,7 +214,6 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica } - /** * If the Source instance is "input", then it is not mandatory to have source Resource Definition, So it can * derive the default input processor. @@ -230,4 +244,74 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica return processorName } + + // Check whether to store or not the resolution of resource and template + private fun isToStore(properties: Map<String, Any>): Boolean { + return properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT) + && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean + } + + // Check whether resolution already exist in the database for the specified resolution-key or resourceId/resourceType + private suspend fun isNewResolution(bluePrintRuntimeService: BluePrintRuntimeService<*>, + properties: Map<String, Any>, + artifactPrefix: String): List<ResourceResolution> { + val occurrence = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] as Int + val resolutionKey = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] as String + val resourceId = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] as String + val resourceType = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] as String + + if (resolutionKey.isNotEmpty()) { + val existingResourceAssignments = + resourceResolutionDBService.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence( + bluePrintRuntimeService, + resolutionKey, + occurrence, + artifactPrefix) + if (existingResourceAssignments.isNotEmpty()) { + log.info("Resolution with resolutionKey=($resolutionKey) already exist - will resolve all resources not already resolved.", + resolutionKey) + } + return existingResourceAssignments + } else if (resourceId.isNotEmpty() && resourceType.isNotEmpty()) { + val existingResourceAssignments = + resourceResolutionDBService.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence( + bluePrintRuntimeService, + resourceId, + resourceType, + + occurrence, + artifactPrefix) + if (existingResourceAssignments.isNotEmpty()) { + log.info("Resolution with resourceId=($resourceId) and resourceType=($resourceType) already exist - will resolve " + + "all resources not already resolved.") + } + return existingResourceAssignments + } + return emptyList() + } + + // Update the resource assignment list with the status of the resource that have already been resolved + private fun updateResourceAssignmentWithExisting(resourceResolutionList: List<ResourceResolution>, + resourceAssignmentList: MutableList<ResourceAssignment>) { + resourceResolutionList.forEach { resourceResolution -> + if (resourceResolution.status == BluePrintConstants.STATUS_SUCCESS) { + resourceAssignmentList.forEach { + if (compareOne(resourceResolution, it)) { + log.info("Resource ({}) already resolve: value=({})", it.name, resourceResolution.value) + it.property!!.value = resourceResolution.value!!.asJsonPrimitive() + it.status = resourceResolution.status + } + } + } + } + } + + // Comparision between what we have in the database vs what we have to assign. + private fun compareOne(resourceResolution: ResourceResolution, resourceAssignment: ResourceAssignment): Boolean { + return (resourceResolution.name == resourceAssignment.name + && resourceResolution.dictionaryName == resourceAssignment.dictionaryName + && resourceResolution.dictionarySource == resourceAssignment.dictionarySource + && resourceResolution.dictionaryVersion == resourceAssignment.version) + } + } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ScriptComponentExtensions.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ScriptComponentExtensions.kt new file mode 100644 index 000000000..ab01b15b7 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ScriptComponentExtensions.kt @@ -0,0 +1,57 @@ +/* + * 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.resource.resolution + +import kotlinx.coroutines.runBlocking +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService + + +/** + * Register the Resolution module exposed dependency + */ +fun BluePrintDependencyService.resourceResolutionService(): ResourceResolutionService = + instance(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) + + +suspend fun AbstractComponentFunction.storedContentFromResolvedArtifactNB(resolutionKey: String, + artifactName: String): String { + return BluePrintDependencyService.resourceResolutionService() + .resolveFromDatabase(bluePrintRuntimeService, artifactName, resolutionKey) +} + +/** + * Return resolved and mashed artifact content for artifact prefix [artifactPrefix] + */ +suspend fun AbstractComponentFunction.contentFromResolvedArtifactNB(artifactPrefix: String): String { + return BluePrintDependencyService.resourceResolutionService() + .resolveResources(bluePrintRuntimeService, nodeTemplateName, artifactPrefix, mapOf()) +} + + +/** + * Blocking Methods called from Jython Scripts + */ + +fun AbstractComponentFunction.storedContentFromResolvedArtifact(resolutionKey: String, artifactName: String) + : String = runBlocking { + storedContentFromResolvedArtifactNB(resolutionKey, artifactName) +} + +fun AbstractComponentFunction.contentFromResolvedArtifact(artifactPrefix: String): String = runBlocking { + contentFromResolvedArtifactNB(artifactPrefix) +} diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt index 767a1feaf..baabfd913 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt @@ -17,13 +17,14 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db import com.fasterxml.jackson.annotation.JsonFormat -import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModelProperty import org.hibernate.annotations.Proxy import org.springframework.data.annotation.LastModifiedDate import org.springframework.data.jpa.domain.support.AuditingEntityListener import java.io.Serializable import java.util.* import javax.persistence.Column +import javax.persistence.ElementCollection import javax.persistence.Entity import javax.persistence.EntityListeners import javax.persistence.Id @@ -38,47 +39,67 @@ import javax.persistence.TemporalType @Proxy(lazy = false) class ResourceResolution : Serializable { - @Id - @Column(name = "resource_resolution_id") - var id: String? = null - - @Column(name = "resolution_key", nullable = false) - var resolutionKey: String? = null - - @Column(name = "resource_type", nullable = false) - var resourceType: String? = null - - @Column(name = "resource_id", nullable = false) - var resourceId: String? = null - + @get:ApiModelProperty(value = "Name of the CBA.", required = true) @Column(name = "blueprint_name", nullable = false) var blueprintName: String? = null + @get:ApiModelProperty(value = "Version of the CBA.", required = true) @Column(name = "blueprint_version", nullable = false) var blueprintVersion: String? = null + @get:ApiModelProperty(value = "Artifact name for which to retrieve a resolved resource.", required = true) @Column(name = "artifact_name", nullable = false) var artifactName: String? = null + @get:ApiModelProperty(value = "Name of the resource.", required = true) + @Column(name = "name", nullable = false) + var name: String? = null + + @get:ApiModelProperty(value = "Value of the resolution.", required = true) + @Lob + @Column(name = "value", nullable = false) + var value: String? = null + + @get:ApiModelProperty(value = "Whether success of failure.", required = true) @Column(name = "status", nullable = false) var status: String? = null - @Column(name = "name", nullable = false) - var name: String? = null + @get:ApiModelProperty(value = "Resolution Key uniquely identifying the resolution of a given artifact within a CBA.", + required = true) + @Column(name = "resolution_key", nullable = false) + var resolutionKey: String? = null + + @get:ApiModelProperty(value = "Resolution type.", required = true, example = "ServiceInstance, VfModule, VNF") + @Column(name = "resource_type", nullable = false) + var resourceType: String? = null + + @get:ApiModelProperty(value = "ID associated with the resolution type in the inventory system.", required = true) + @Column(name = "resource_id", nullable = false) + var resourceId: String? = null + + @get:ApiModelProperty(value = "If resolution occurred multiple time, this field provides the index.", + required = true) + @Column(name = "occurrence", nullable = false) + var occurrence: Int = 0 - @Column(name = "dictionary_vname", nullable = false) + @get:ApiModelProperty(value = "Name of the data dictionary used for the resolution.", required = true) + @Column(name = "dictionary_name", nullable = false) var dictionaryName: String? = null + @get:ApiModelProperty(value = "Source associated with the data dictionary used for the resolution.", + required = true) @Column(name = "dictionary_status", nullable = false) var dictionarySource: String? = null + @get:ApiModelProperty(value = "Version of the data dictionary used for the resolution.", required = true) @Column(name = "dictionary_version", nullable = false) var dictionaryVersion: Int = 0 - @Lob - @Column(name = "value", nullable = false) - var value: String? = null + @Id + @Column(name = "resource_resolution_id") + var id: String? = null + @get:ApiModelProperty(value = "Creation date of the resolution.", required = true) @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") @LastModifiedDate @Temporal(TemporalType.TIMESTAMP) diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt index 81239be30..5335b14b1 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt @@ -24,7 +24,7 @@ import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeServ import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment import org.slf4j.LoggerFactory -import org.springframework.dao.DataIntegrityViolationException +import org.springframework.dao.EmptyResultDataAccessException import org.springframework.stereotype.Service import java.util.* @@ -33,6 +33,49 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso private val log = LoggerFactory.getLogger(ResourceResolutionDBService::class.toString()) + suspend fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence( + bluePrintRuntimeService: BluePrintRuntimeService<*>, key: String, + occurrence: Int, artifactPrefix: String): List<ResourceResolution> { + return try { + val metadata = bluePrintRuntimeService.bluePrintContext().metadata!! + + val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!! + val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!! + + resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence( + blueprintName, + blueprintVersion, + artifactPrefix, + key, + occurrence) + } catch (e: EmptyResultDataAccessException) { + emptyList() + } + } + + suspend fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence( + bluePrintRuntimeService: BluePrintRuntimeService<*>, resourceId: String, + resourceType: String, occurrence: Int, + artifactPrefix: String): List<ResourceResolution> { + return try { + + val metadata = bluePrintRuntimeService.bluePrintContext().metadata!! + + val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!! + val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!! + + resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence( + blueprintName, + blueprintVersion, + artifactPrefix, + resourceId, + resourceType, + occurrence) + } catch (e: EmptyResultDataAccessException) { + emptyList() + } + } + suspend fun readValue(blueprintName: String, blueprintVersion: String, artifactPrefix: String, @@ -62,14 +105,15 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso suspend fun readWithResourceIdAndResourceType(blueprintName: String, blueprintVersion: String, resourceId: String, - resourceType: String): List<ResourceResolution> = withContext(Dispatchers.IO) { - - resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType( - blueprintName, - blueprintVersion, - resourceId, - resourceType) - } + resourceType: String): List<ResourceResolution> = + withContext(Dispatchers.IO) { + + resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType( + blueprintName, + blueprintVersion, + resourceId, + resourceType) + } suspend fun write(properties: Map<String, Any>, bluePrintRuntimeService: BluePrintRuntimeService<*>, @@ -80,12 +124,11 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!! val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!! - val resolutionKey = - properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY].toString() - val resourceType = - properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE].toString() - val resourceId = - properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID].toString() + + val resolutionKey = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] as String + val resourceId = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] as String + val resourceType = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] as String + val occurrence = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] as Int write(blueprintName, blueprintVersion, @@ -93,7 +136,8 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso resourceId, resourceType, artifactPrefix, - resourceAssignment) + resourceAssignment, + occurrence) } suspend fun write(blueprintName: String, @@ -102,17 +146,23 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso resourceId: String, resourceType: String, artifactPrefix: String, - resourceAssignment: ResourceAssignment): ResourceResolution = withContext(Dispatchers.IO) { + resourceAssignment: ResourceAssignment, + occurrence: Int = 0): ResourceResolution = withContext(Dispatchers.IO) { val resourceResolution = ResourceResolution() resourceResolution.id = UUID.randomUUID().toString() resourceResolution.artifactName = artifactPrefix + resourceResolution.occurrence = occurrence resourceResolution.blueprintVersion = blueprintVersion resourceResolution.blueprintName = blueprintName resourceResolution.resolutionKey = resolutionKey resourceResolution.resourceType = resourceType resourceResolution.resourceId = resourceId - resourceResolution.value = JacksonUtils.getValue(resourceAssignment.property?.value!!).toString() + if (BluePrintConstants.STATUS_SUCCESS == resourceAssignment.status) { + resourceResolution.value = JacksonUtils.getValue(resourceAssignment.property?.value!!).toString() + } else { + resourceResolution.value = "" + } resourceResolution.name = resourceAssignment.name resourceResolution.dictionaryName = resourceAssignment.dictionaryName resourceResolution.dictionaryVersion = resourceAssignment.version diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt index d2cbf8411..429041e14 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt @@ -34,4 +34,19 @@ interface ResourceResolutionRepository : JpaRepository<ResourceResolution, Strin blueprintVersion: String, resourceId: String, resourceType: String): List<ResourceResolution> + + fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence( + blueprintName: String?, + blueprintVersion: String?, + artifactName: String, + resolutionKey: String, + occurrence: Int): List<ResourceResolution> + + fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence( + blueprintName: String?, + blueprintVersion: String?, + artifactName: String, + resourceId: String, + resourceType: String, + occurrence: Int): List<ResourceResolution> }
\ 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/db/ResourceResolutionResultRepository.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultRepository.kt deleted file mode 100644 index efc130a84..000000000 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultRepository.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2019 Bell Canada. - * - * 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.resource.resolution.db - -import org.springframework.data.jpa.repository.JpaRepository - -interface ResourceResolutionResultRepository : JpaRepository<ResourceResolutionResult, String> { - - fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(key: String, blueprintName: String?, - blueprintVersion: String?, - artifactName: String): ResourceResolutionResult -} diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultService.kt deleted file mode 100644 index ebb34ba4a..000000000 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultService.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2019 Bell Canada. - * Modifications 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.resource.resolution.db - -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants -import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants -import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException -import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService -import org.springframework.dao.DataIntegrityViolationException -import org.springframework.stereotype.Service -import java.util.* - -@Service -class ResourceResolutionResultService(private val resourceResolutionRepository: ResourceResolutionResultRepository) { - - suspend fun read(bluePrintRuntimeService: BluePrintRuntimeService<*>, artifactPrefix: String, - resolutionKey: String): String = withContext(Dispatchers.IO) { - - val metadata = bluePrintRuntimeService.bluePrintContext().metadata!! - - val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION] - val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME] - - resourceResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName( - resolutionKey, - blueprintName, - blueprintVersion, - artifactPrefix).result!! - } - - suspend fun write(properties: Map<String, Any>, result: String, bluePrintRuntimeService: BluePrintRuntimeService<*>, - artifactPrefix: String) = withContext(Dispatchers.IO) { - - val metadata = bluePrintRuntimeService.bluePrintContext().metadata!! - - val resourceResolutionResult = ResourceResolutionResult() - resourceResolutionResult.id = UUID.randomUUID().toString() - resourceResolutionResult.artifactName = artifactPrefix - resourceResolutionResult.blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION] - resourceResolutionResult.blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME] - resourceResolutionResult.resolutionKey = - properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY].toString() - resourceResolutionResult.result = result - - try { - resourceResolutionRepository.saveAndFlush(resourceResolutionResult) - } catch (ex: DataIntegrityViolationException) { - throw BluePrintException("Failed to store resource resolution result.", ex) - } - } - - suspend fun readByKey(resolutionResultId: String): String = withContext(Dispatchers.IO) { - - resourceResolutionRepository.getOne(resolutionResultId).result!! - } - - suspend fun deleteByKey(resolutionResultId: String): Unit = withContext(Dispatchers.IO) { - - val row = resourceResolutionRepository.getOne(resolutionResultId) - resourceResolutionRepository.delete(row) - resourceResolutionRepository.flush() - } -}
\ 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/db/ResourceResolutionResult.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt index c9b747e59..70aadb4b1 100755 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResult.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt @@ -17,6 +17,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db import com.fasterxml.jackson.annotation.JsonFormat +import io.swagger.annotations.ApiModelProperty import org.hibernate.annotations.Proxy import org.springframework.data.annotation.LastModifiedDate import org.springframework.data.jpa.domain.support.AuditingEntityListener @@ -33,30 +34,50 @@ import javax.persistence.TemporalType @EntityListeners(AuditingEntityListener::class) @Entity -@Table(name = "RESOURCE_RESOLUTION_RESULT") +@Table(name = "TEMPLATE_RESOLUTION") @Proxy(lazy = false) -class ResourceResolutionResult : Serializable { - - @Id - @Column(name = "resource_resolution_result_id") - var id: String? = null - - @Column(name = "resolution_key", nullable = false) - var resolutionKey: String? = null +class TemplateResolution : Serializable { + @get:ApiModelProperty(value = "Name of the CBA.", required = true) @Column(name = "blueprint_name", nullable = false) var blueprintName: String? = null + @get:ApiModelProperty(value = "Version of the CBA.", required = true) @Column(name = "blueprint_version", nullable = false) var blueprintVersion: String? = null + @get:ApiModelProperty(value = "Artifact name for which to retrieve a resolved resource.", required = true) @Column(name = "artifact_name", nullable = false) var artifactName: String? = null + @get:ApiModelProperty(value = "Rendered template.", required = true) @Lob @Column(name = "result", nullable = false) var result: String? = null + @get:ApiModelProperty(value = "Resolution Key uniquely identifying the resolution of a given artifact within a CBA.", + required = true) + @Column(name = "resolution_key", nullable = false) + var resolutionKey: String? = null + + @get:ApiModelProperty(value = "Resolution type.", required = true, example = "ServiceInstance, VfModule, VNF") + @Column(name = "resource_type", nullable = false) + var resourceType: String? = null + + @get:ApiModelProperty(value = "ID associated with the resolution type in the inventory system.", required = true) + @Column(name = "resource_id", nullable = false) + var resourceId: String? = null + + @get:ApiModelProperty(value = "If resolution occurred multiple time, this field provides the index.", + required = true) + @Column(name = "occurrence", nullable = false) + var occurrence: Int = 0 + + @Id + @Column(name = "template_resolution_id") + var id: String? = null + + @get:ApiModelProperty(value = "Creation date of the resolution.", required = true) @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") @LastModifiedDate @Temporal(TemporalType.TIMESTAMP) diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt new file mode 100644 index 000000000..440663f25 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2019 Bell Canada. + * + * 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.resource.resolution.db + +import org.springframework.data.jpa.repository.JpaRepository +import javax.transaction.Transactional + +interface TemplateResolutionRepository : JpaRepository<TemplateResolution, String> { + + fun findByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + resourceId: String, + resourceType: String, + blueprintName: String?, + blueprintVersion: String?, + artifactName: String, + occurrence: Int): TemplateResolution ? + + fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + key: String, + blueprintName: String?, + blueprintVersion: String?, + artifactName: String, + occurrence: Int): TemplateResolution ? + + @Transactional + fun deleteByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + resourceId: String, + resourceType: String, + blueprintName: String?, + blueprintVersion: String?, + artifactName: String, + occurrence: Int) + + @Transactional + fun deleteByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + key: String, + blueprintName: String?, + blueprintVersion: String?, + artifactName: String, + occurrence: Int) +} diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt new file mode 100644 index 000000000..55f7e770b --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2019 Bell Canada. + * + * 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.resource.resolution.db + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService +import org.slf4j.LoggerFactory +import org.springframework.dao.DataIntegrityViolationException +import org.springframework.dao.EmptyResultDataAccessException +import org.springframework.stereotype.Service +import java.util.* + +@Service +class TemplateResolutionService(private val templateResolutionRepository: TemplateResolutionRepository) { + + private val log = LoggerFactory.getLogger(TemplateResolutionService::class.toString()) + + suspend fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName( + bluePrintRuntimeService: BluePrintRuntimeService<*>, + artifactPrefix: String, + resolutionKey: String): String = + withContext(Dispatchers.IO) { + + val metadata = bluePrintRuntimeService.bluePrintContext().metadata!! + + val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!! + val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!! + + findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(blueprintName, + blueprintVersion, + artifactPrefix, + resolutionKey) + } + + suspend fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(blueprintName: String, + blueprintVersion: String, + artifactPrefix: String, + resolutionKey: String, + occurrence: Int = 0): String = + withContext(Dispatchers.IO) { + + templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + resolutionKey, + blueprintName, + blueprintVersion, + artifactPrefix, + occurrence)?.result ?: throw EmptyResultDataAccessException(1) + } + + suspend fun findByResoureIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactName(blueprintName: String, + blueprintVersion: String, + artifactPrefix: String, + resourceId: String, + resourceType: String, + occurrence: Int = 0): String = + withContext(Dispatchers.IO) { + + templateResolutionRepository.findByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + resourceId, + resourceType, + blueprintName, + blueprintVersion, + artifactPrefix, + occurrence)?.result!! + } + + suspend fun write(properties: Map<String, Any>, + result: String, bluePrintRuntimeService: BluePrintRuntimeService<*>, + artifactPrefix: String): TemplateResolution = withContext(Dispatchers.IO) { + + val metadata = bluePrintRuntimeService.bluePrintContext().metadata!! + + val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!! + val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!! + val resolutionKey = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] as String + val resourceId = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] as String + val resourceType = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] as String + val occurrence = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] as Int + + write(blueprintName, + blueprintVersion, + artifactPrefix, + result, + occurrence, + resolutionKey, + resourceId, + resourceType) + } + + suspend fun write(blueprintName: String, blueprintVersion: String, artifactPrefix: String, + template: String, occurrence: Int = 0, resolutionKey: String = "", resourceId: String = "", + resourceType: String = ""): TemplateResolution = + withContext(Dispatchers.IO) { + + val resourceResolutionResult = TemplateResolution() + resourceResolutionResult.id = UUID.randomUUID().toString() + resourceResolutionResult.artifactName = artifactPrefix + resourceResolutionResult.blueprintVersion = blueprintVersion + resourceResolutionResult.blueprintName = blueprintName + resourceResolutionResult.resolutionKey = resolutionKey + resourceResolutionResult.resourceId = resourceId + resourceResolutionResult.resourceType = resourceType + resourceResolutionResult.result = template + resourceResolutionResult.occurrence = occurrence + + // Overwrite template resolution-key of resourceId/resourceType already existant + if (resolutionKey.isNotEmpty()) { + templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + resolutionKey, blueprintName, blueprintVersion, artifactPrefix, occurrence)?.let { + log.info("Overwriting template resolution for blueprintName=($blueprintVersion), blueprintVersion=($blueprintName), " + + "artifactName=($artifactPrefix) and resolutionKey=($resolutionKey)") + templateResolutionRepository.deleteByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + resolutionKey, + blueprintName, + blueprintVersion, + artifactPrefix, + occurrence) + } + } else if (resourceId.isNotEmpty() && resourceType.isNotEmpty()) { + templateResolutionRepository.findByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + resourceId, resourceType, blueprintName, blueprintVersion, artifactPrefix, occurrence)?.let { + log.info("Overwriting template resolution for blueprintName=($blueprintVersion), blueprintVersion=($blueprintName), " + + "artifactName=($artifactPrefix), resourceId=($resourceId) and resourceType=($resourceType)") + templateResolutionRepository.deleteByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + resourceId, + resourceType, + blueprintName, + blueprintVersion, + artifactPrefix, + occurrence) + } + } + try { + templateResolutionRepository.saveAndFlush(resourceResolutionResult) + } catch (ex: DataIntegrityViolationException) { + throw BluePrintException("Failed to store resource api result.", ex) + } + } +}
\ 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/processor/CapabilityResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt index 7a8d6ec5c..49cb83e09 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt @@ -20,6 +20,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.pro import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.CapabilityResourceSource import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentFunctionScriptingService import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils @@ -82,6 +83,7 @@ open class CapabilityResourceResolutionProcessor(private val applicationContext: override suspend fun recoverNB(runtimeException: RuntimeException, resourceAssignment: ResourceAssignment) { raRuntimeService.getBluePrintError() .addError("Failed in CapabilityResourceResolutionProcessor : ${runtimeException.message}") + ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, runtimeException.message) } suspend fun scriptInstance(scriptType: String, scriptClassReference: String, instanceDependencies: List<String>) 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 39ffe5ea9..1abcea825 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 @@ -93,6 +93,7 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig } catch (runtimeException: RuntimeException) { log.error("failed in ${getName()} : ${runtimeException.message}", runtimeException) recoverNB(runtimeException, resourceAssignment) + return false } return true } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponentTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponentTest.kt index 3a30ae90e..39076b4f5 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponentTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponentTest.kt @@ -1,9 +1,5 @@ /* - * Copyright © 2017-2018 AT&T Intellectual Property. - * - * Modifications Copyright © 2018 IBM. - * - * Modifications Copyright © 2019 IBM, Bell Canada. + * Copyright © 2018 Bell Canada * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,98 +17,150 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution import com.fasterxml.jackson.databind.JsonNode +import io.mockk.coEvery +import io.mockk.every +import io.mockk.mockk import kotlinx.coroutines.runBlocking +import org.junit.Before 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.ExecutionServiceInput -import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.StepData -import org.onap.ccsdk.cds.blueprintsprocessor.core.utils.PayloadUtils -import org.onap.ccsdk.cds.blueprintsprocessor.db.BluePrintDBLibConfiguration -import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.* -import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants -import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode -import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration -import org.onap.ccsdk.cds.controllerblueprints.core.putJsonElement -import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintError +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.EnableAutoConfiguration -import org.springframework.context.annotation.ComponentScan -import org.springframework.test.context.ContextConfiguration -import org.springframework.test.context.TestPropertySource -import org.springframework.test.context.junit4.SpringRunner - -@RunWith(SpringRunner::class) -@ContextConfiguration(classes = [ResourceResolutionServiceImpl::class, - InputResourceResolutionProcessor::class, DefaultResourceResolutionProcessor::class, - DatabaseResourceAssignmentProcessor::class, RestResourceResolutionProcessor::class, - CapabilityResourceResolutionProcessor::class, - BlueprintPropertyConfiguration::class, BluePrintProperties::class, - BluePrintDBLibConfiguration::class, BluePrintLoadConfiguration::class]) -@TestPropertySource(locations = ["classpath:application-test.properties"]) -@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"]) -@EnableAutoConfiguration +import java.lang.RuntimeException +import kotlin.test.assertEquals +import kotlin.test.fail + class ResourceResolutionComponentTest { - @Autowired - lateinit var resourceResolutionComponent: ResourceResolutionComponent + private val resourceResolutionService = mockk<ResourceResolutionService>() + private val resourceResolutionComponent = ResourceResolutionComponent(resourceResolutionService) - @Test - fun testProcess() { - runBlocking { + private val resolutionKey = "resolutionKey" + private val resourceId = "1" + private val resourceType = "ServiceInstance" + private val occurrence = 1 + private val props = mutableMapOf<String, JsonNode>() + private val bluePrintRuntimeService = mockk<BluePrintRuntimeService<*>>() + private val artifactNames = listOf("template") + private val nodeTemplateName = "nodeTemplateName" - val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234", - "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") + private val executionRequest = ExecutionServiceInput() - val executionServiceInput = JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json", - ExecutionServiceInput::class.java)!! - // Prepare Inputs - PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService, executionServiceInput.payload, "resource-assignment") + @Before + fun setup() { - val stepMetaData: MutableMap<String, JsonNode> = hashMapOf() - stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, "resource-assignment") - stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_INTERFACE, "ResourceResolutionComponent") - stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_OPERATION, "process") - bluePrintRuntimeService.put("resource-assignment-step-inputs", stepMetaData.asJsonNode()) + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = true.asJsonPrimitive() + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] = resolutionKey.asJsonPrimitive() + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId.asJsonPrimitive() + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType.asJsonPrimitive() + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = occurrence.asJsonPrimitive() + props[ResourceResolutionConstants.INPUT_ARTIFACT_PREFIX_NAMES] = JacksonUtils.jsonNodeFromObject(artifactNames) - resourceResolutionComponent.bluePrintRuntimeService = bluePrintRuntimeService - val stepInputData = StepData().apply { - name = "resource-assignment" - properties = stepMetaData + resourceResolutionComponent.operationInputs = props + resourceResolutionComponent.bluePrintRuntimeService = bluePrintRuntimeService + resourceResolutionComponent.nodeTemplateName = nodeTemplateName + + resourceResolutionComponent.executionServiceInput = executionRequest + resourceResolutionComponent.processId = "12" + resourceResolutionComponent.workflowName = "workflow" + resourceResolutionComponent.stepName = "step" + resourceResolutionComponent.interfaceName = "interfaceName" + resourceResolutionComponent.operationName = "operationName" + } + + @Test + fun processNBWithResolutionKeyAndResourceIdAndResourceTypeTestException() { + runBlocking { + try { + resourceResolutionComponent.processNB(executionRequest) + } catch (e: BluePrintProcessorException) { + assertEquals("Can't proceed with the resolution: either provide resolution-key OR combination of resource-id and resource-type.", + e.message) + return@runBlocking } - executionServiceInput.stepData = stepInputData - resourceResolutionComponent.applyNB(executionServiceInput) + fail() } } @Test - fun testRecover() { + fun processNBWithResourceIdTestException() { + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] = "".asJsonPrimitive() + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = "".asJsonPrimitive() + + runBlocking { + try { + resourceResolutionComponent.processNB(executionRequest) + } catch (e: BluePrintProcessorException) { + assertEquals("Can't proceed with the resolution: both resource-id and resource-type should be provided, one of them is missing.", + e.message) + return@runBlocking + } + fail() + } + } + + @Test + fun processNBWithEmptyResourceTypeResourceIdResolutionKeyTestException() { + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] = "".asJsonPrimitive() + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = "".asJsonPrimitive() + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = "".asJsonPrimitive() + runBlocking { - val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234", - "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") + try { + resourceResolutionComponent.processNB(executionRequest) + } catch (e: BluePrintProcessorException) { + assertEquals("Can't proceed with the resolution: can't persist resolution without a correlation key. " + + "Either provide a resolution-key OR combination of resource-id and resource-type OR set `storeResult` to false.", + e.message) + return@runBlocking + } + fail() + } + } - val executionServiceInput = JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json", - ExecutionServiceInput::class.java)!! + @Test + fun processNBTest() { + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] = "".asJsonPrimitive() - // Prepare Inputs - PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService, executionServiceInput.payload, "resource-assignment") + val properties = mutableMapOf<String, Any>() + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = true + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = occurrence - val stepMetaData: MutableMap<String, JsonNode> = hashMapOf() - stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, "resource-assignment") - stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_INTERFACE, "ResourceResolutionComponent") - stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_OPERATION, "process") - bluePrintRuntimeService.put("resource-assignment-step-inputs", stepMetaData.asJsonNode()) + coEvery { + resourceResolutionService.resolveResources(any<BluePrintRuntimeService<*>>(), + any<String>(), + any<List<String>>(), + any<MutableMap<String, Any>>()) + } returns mutableMapOf() + every { bluePrintRuntimeService.setNodeTemplateAttributeValue(any(), any(), any()) } returns Unit - resourceResolutionComponent.bluePrintRuntimeService = bluePrintRuntimeService - val stepInputData = StepData().apply { - name = "resource-assignment" - properties = stepMetaData - } - executionServiceInput.stepData = stepInputData - resourceResolutionComponent.recoverNB(RuntimeException("TEST PASSED"), executionServiceInput) + + runBlocking { + resourceResolutionComponent.processNB(executionRequest) + } + +// FIXME add verification +// coVerify { +// resourceResolutionService.resolveResources(eq(bluePrintRuntimeService), +// eq(nodeTemplateName), eq(artifactNames), eq(properties)) +// } + } + + @Test + fun testRecover() { + runBlocking { + val blueprintError = BluePrintError() + val exception = RuntimeException("message") + every { bluePrintRuntimeService.getBluePrintError() } returns blueprintError + resourceResolutionComponent.recoverNB(exception, executionRequest) + + assertEquals(1, blueprintError.errors.size) } } }
\ 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/ResourceResolutionServiceTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt index 4a3e75cde..f1ad03054 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt @@ -20,6 +20,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution import kotlinx.coroutines.runBlocking import org.junit.Assert +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties @@ -28,6 +29,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInpu import org.onap.ccsdk.cds.blueprintsprocessor.core.utils.PayloadUtils import org.onap.ccsdk.cds.blueprintsprocessor.db.BluePrintDBLibConfiguration import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.* +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils @@ -63,12 +65,27 @@ class ResourceResolutionServiceTest { @Autowired lateinit var resourceResolutionService: ResourceResolutionService + private val props = hashMapOf<String, Any>() + private val resolutionKey = "resolutionKey" + private val resourceId = "1" + private val resourceType = "ServiceInstance" + private val occurrence = 0 + + @Before + fun setup() { + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = true + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] = resolutionKey + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = occurrence + } + @Test fun testRegisteredSource() { val sources = resourceResolutionService.registeredResourceSources() assertNotNull(sources, "failed to get registered sources") assertTrue(sources.containsAll(arrayListOf("source-input", "source-default", "source-processor-db", - "source-rest")), "failed to get registered sources : $sources") + "source-rest")), "failed to get registered sources : $sources") } @Test @@ -79,15 +96,27 @@ class ResourceResolutionServiceTest { Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService) val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234", - "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") + "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") - val executionServiceInput = JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json", + val executionServiceInput = + JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json", ExecutionServiceInput::class.java)!! + + val resourceAssignmentRuntimeService = + ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService, + "testResolveResource") + + // Prepare Inputs - PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService, executionServiceInput.payload, "resource-assignment") + PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService, + executionServiceInput.payload, + "resource-assignment") - resourceResolutionService.resolveResources(bluePrintRuntimeService, "resource-assignment", "baseconfig", mapOf()) + resourceResolutionService.resolveResources(resourceAssignmentRuntimeService, + "resource-assignment", + "baseconfig", + props) } } @@ -99,17 +128,23 @@ class ResourceResolutionServiceTest { Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService) val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234", - "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") + "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") - val executionServiceInput = JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json", + val executionServiceInput = + JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json", ExecutionServiceInput::class.java)!! val artefactNames = listOf("baseconfig", "another") // Prepare Inputs - PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService, executionServiceInput.payload, "resource-assignment") - - resourceResolutionService.resolveResources(bluePrintRuntimeService, "resource-assignment", artefactNames, mapOf()) + PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService, + executionServiceInput.payload, + "resource-assignment") + + resourceResolutionService.resolveResources(bluePrintRuntimeService, + "resource-assignment", + artefactNames, + props) } } @@ -121,17 +156,61 @@ class ResourceResolutionServiceTest { Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService) val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234", - "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") + "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") - val executionServiceInput = JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json", + val executionServiceInput = + JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json", ExecutionServiceInput::class.java)!! + val resourceAssignmentRuntimeService = + ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService, + "testResolveResourcesWithMappingAndTemplate") + val artifactPrefix = "another" // Prepare Inputs - PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService, executionServiceInput.payload, "resource-assignment") + PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService, + executionServiceInput.payload, + "resource-assignment") + + resourceResolutionService.resolveResources(resourceAssignmentRuntimeService, + "resource-assignment", + artifactPrefix, + props) + } + } + + + @Test + fun testResolveResourcesWithResourceIdAndResourceType() { - resourceResolutionService.resolveResources(bluePrintRuntimeService, "resource-assignment", artifactPrefix, mapOf<String, String>()) + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] = "" + + runBlocking { + Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService) + + val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234", + "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") + + val executionServiceInput = + JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json", + ExecutionServiceInput::class.java)!! + + val resourceAssignmentRuntimeService = + ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService, + "testResolveResourcesWithMappingAndTemplate") + + val artifactPrefix = "another" + + // Prepare Inputs + PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService, + executionServiceInput.payload, + "resource-assignment") + + resourceResolutionService.resolveResources(resourceAssignmentRuntimeService, + "resource-assignment", + artifactPrefix, + props) } } } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBServiceTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBServiceTest.kt new file mode 100644 index 000000000..dcf2e64a5 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBServiceTest.kt @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2019 Bell Canada. + * + * 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.resource.resolution.db + +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.runBlocking +import org.junit.Before +import org.junit.Test +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants +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.resource.dict.ResourceAssignment +import org.springframework.dao.EmptyResultDataAccessException +import kotlin.test.assertEquals + +open class ResourceResolutionDBServiceTest { + + private val resourceResolutionRepository = mockk<ResourceResolutionRepository>() + + private val resourceResolutionDBService = ResourceResolutionDBService(resourceResolutionRepository) + + private val resolutionKey = "resolutionKey" + private val resourceId = "1" + private val resourceType = "ServiceInstance" + private val occurrence = 0 + private val artifactPrefix = "template" + private val blueprintName = "blueprintName" + private val blueprintVersion = "1.0.0" + private val metadata = hashMapOf<String, String>() + private val props = hashMapOf<String, Any>() + private val bluePrintContext = mockk<BluePrintContext>() + private val bluePrintRuntimeService = mockk<DefaultBluePrintRuntimeService>() + + @Before + fun setup() { + metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION] = blueprintVersion + metadata[BluePrintConstants.METADATA_TEMPLATE_NAME] = blueprintName + + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] = resolutionKey + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = occurrence + + every { bluePrintContext.metadata } returns metadata + + every { bluePrintRuntimeService.bluePrintContext() } returns bluePrintContext + } + + @Test + fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrenceTest() { + + val rr1 = ResourceResolution() + val rr2 = ResourceResolution() + + val list = listOf(rr1, rr2) + every { + resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence( + any(), any(), any(), any(), any()) + } returns list + runBlocking { + + val res = + resourceResolutionDBService.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence( + bluePrintRuntimeService, resolutionKey, occurrence, artifactPrefix) + + assertEquals(2, res.size) + } + } + + @Test + fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrenceTestException() { + every { + resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence( + any(), any(), any(), any(), any()) + } throws EmptyResultDataAccessException(1) + runBlocking { + val res = + resourceResolutionDBService.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence( + bluePrintRuntimeService, resolutionKey, occurrence, artifactPrefix) + + assert(res.isEmpty()) + } + } + + @Test + fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrenceTest() { + + val rr1 = ResourceResolution() + val rr2 = ResourceResolution() + val list = listOf(rr1, rr2) + every { + resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence( + any(), any(), any(), any(), any(), any()) + } returns list + runBlocking { + + val res = + resourceResolutionDBService.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence( + bluePrintRuntimeService, resourceId, resourceType, occurrence, artifactPrefix) + + assertEquals(2, res.size) + } + } + + @Test + fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrenceTestException() { + every { + resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence( + any(), any(), any(), any(), any(), any()) + } throws EmptyResultDataAccessException(1) + runBlocking { + val res = + resourceResolutionDBService.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence( + bluePrintRuntimeService, resourceId, resourceType, occurrence, artifactPrefix) + + assert(res.isEmpty()) + } + } + + @Test + fun readValueTest() { + val rr = ResourceResolution() + rr.name = "bob" + rr.value = "testValue" + every { + resourceResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndName( + any(), any(), any(), any(), any()) + } returns rr + runBlocking { + val res = + resourceResolutionDBService.readValue( + blueprintName, blueprintVersion, artifactPrefix, resolutionKey, "bob") + + assertEquals(rr.name, res.name) + assertEquals(rr.value, res.value) + } + } + + @Test + fun readWithResolutionKeyTest() { + val rr1 = ResourceResolution() + val rr2 = ResourceResolution() + val list = listOf(rr1, rr2) + every { + resourceResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName( + any(), any(), any(), any()) + } returns list + runBlocking { + val res = + resourceResolutionDBService.readWithResolutionKey( + blueprintName, blueprintVersion, artifactPrefix, resolutionKey) + assertEquals(2, res.size) + } + } + + @Test + fun readWithResourceIdAndResourceTypeTest() { + val rr1 = ResourceResolution() + val rr2 = ResourceResolution() + val list = listOf(rr1, rr2) + every { + resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType( + any(), any(), any(), any()) + } returns list + runBlocking { + val res = + resourceResolutionDBService.readWithResourceIdAndResourceType( + blueprintName, blueprintVersion, resourceId, resourceType) + assertEquals(2, res.size) + } + } + + @Test + fun writeTest() { + val resourceResolution = ResourceResolution() + val resourceAssignment = ResourceAssignment() + resourceAssignment.property?.status = BluePrintConstants.STATUS_SUCCESS + resourceAssignment.property?.value = "result".asJsonPrimitive() + resourceAssignment.dictionarySource = "ddSource" + resourceAssignment.dictionaryName = "ddName" + resourceAssignment.version = 1 + resourceAssignment.name = "test" + every { + resourceResolutionRepository.saveAndFlush(any<ResourceResolution>()) + } returns resourceResolution + runBlocking { + val res = + resourceResolutionDBService.write( + props, bluePrintRuntimeService, artifactPrefix, resourceAssignment) + + assertEquals(resourceResolution, res) + } + } +}
\ 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/db/TemplateResolutionServiceTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionServiceTest.kt new file mode 100644 index 000000000..48c6f02ef --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionServiceTest.kt @@ -0,0 +1,137 @@ +package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db + +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.runBlocking +import org.junit.Before +import org.junit.Test +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext +import org.onap.ccsdk.cds.controllerblueprints.core.service.DefaultBluePrintRuntimeService +import org.springframework.dao.EmptyResultDataAccessException +import kotlin.test.assertEquals + +class TemplateResolutionServiceTest { + + private val templateResolutionRepository = mockk<TemplateResolutionRepository>() + + private val templateResolutionService = TemplateResolutionService(templateResolutionRepository) + + private val resolutionKey = "resolutionKey" + private val resourceId = "1" + private val resourceType = "ServiceInstance" + private val occurrence = 0 + private val artifactPrefix = "template" + private val blueprintName = "blueprintName" + private val blueprintVersion = "1.0.0" + private val result = "result" + private val metadata = hashMapOf<String, String>() + private val props = hashMapOf<String, Any>() + private val bluePrintContext = mockk<BluePrintContext>() + private val bluePrintRuntimeService = mockk<DefaultBluePrintRuntimeService>() + + @Before + fun setup() { + metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION] = blueprintVersion + metadata[BluePrintConstants.METADATA_TEMPLATE_NAME] = blueprintName + + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] = resolutionKey + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = occurrence + + every { bluePrintContext.metadata } returns metadata + + every { bluePrintRuntimeService.bluePrintContext() } returns bluePrintContext + } + + @Test + fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameTest() { + val tr = TemplateResolution() + tr.result = "res" + runBlocking { + every { + templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + any(), any(), any(), any(), any()) + } returns tr + val res = + templateResolutionService.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName( + bluePrintRuntimeService, artifactPrefix, resolutionKey) + assertEquals(tr.result, res) + } + } + + @Test(expected = EmptyResultDataAccessException::class) + fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameTestException() { + val tr = TemplateResolution() + runBlocking { + every { + templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + any(), any(), any(), any(), any()) + } returns tr + templateResolutionService.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName( + bluePrintRuntimeService, artifactPrefix, resolutionKey) + } + } + + @Test + fun writeWithResolutionKeyTest() { + val tr = TemplateResolution() + runBlocking { + every { templateResolutionRepository.saveAndFlush(any<TemplateResolution>()) } returns tr + every { + templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + any(), any(), any(), any(), any()) + } returns null + val res = templateResolutionService.write(props, result, bluePrintRuntimeService, artifactPrefix) + assertEquals(tr, res) + } + } + + @Test + fun writeWithResolutionKeyExistingTest() { + val tr = TemplateResolution() + runBlocking { + every { templateResolutionRepository.saveAndFlush(any<TemplateResolution>()) } returns tr + every { + templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + any(), any(), any(), any(), any()) + } returns tr + every { + templateResolutionRepository.deleteByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + any(), any(), any(), any(), any()) + } returns Unit + val res = templateResolutionService.write(props, result, bluePrintRuntimeService, artifactPrefix) + verify { + templateResolutionRepository.deleteByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + eq(resolutionKey), eq(blueprintName), eq(blueprintVersion), eq(artifactPrefix), eq(occurrence)) + } + assertEquals(tr, res) + } + } + + @Test + fun writeWithResourceIdResourceTypeExistingTest() { + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] = "" + val tr = TemplateResolution() + runBlocking { + every { templateResolutionRepository.saveAndFlush(any<TemplateResolution>()) } returns tr + every { + templateResolutionRepository.findByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + any(), any(), any(), any(), any(), any()) + } returns tr + every { + templateResolutionRepository.deleteByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + any(), any(), any(), any(), any(), any()) + } returns Unit + val res = templateResolutionService.write(props, result, bluePrintRuntimeService, artifactPrefix) + verify { + templateResolutionRepository.deleteByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence( + eq(resourceId), eq(resourceType), eq(blueprintName), eq(blueprintVersion), eq(artifactPrefix), eq(occurrence)) + } + assertEquals(tr, res) + } + } +}
\ 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/mock/MockRestResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockRestResourceResolutionProcessor.kt index be023307b..e80663094 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 @@ -98,7 +98,7 @@ class MockRestResourceResolutionProcessor(private val blueprintRestLibPropertySe } } catch (e: Exception) { ResourceAssignmentUtils.setFailedResourceDataValue(executionRequest, e.message) - throw BluePrintProcessorException("Failed in template key ($executionRequest) assignments with: ${e.message}", + throw BluePrintProcessorException("Failed in template resolutionKey ($executionRequest) assignments with: ${e.message}", e) } } 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 f73197e0b..153e88937 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 @@ -71,34 +71,6 @@ class DatabaseResourceResolutionProcessorTest { val processorName = databaseResourceAssignmentProcessor.applyNB(resourceAssignment) assertNotNull(processorName, "couldn't get Database resource assignment processor name") - 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/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfComponentFunction.kt b/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfComponentFunction.kt index b2064cb54..ede833cfb 100644 --- a/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfComponentFunction.kt +++ b/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfComponentFunction.kt @@ -25,28 +25,42 @@ import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPrope import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractScriptComponentFunction - +@Deprecated("Methods defined as extension function of AbstractComponentFunction") abstract class RestconfComponentFunction : AbstractScriptComponentFunction() { + @Deprecated("Defined in AbstractScriptComponentFunction extension class") open fun bluePrintRestLibPropertyService(): BluePrintRestLibPropertyService = functionDependencyInstanceAsType(RestLibConstants.SERVICE_BLUEPRINT_REST_LIB_PROPERTY) + @Deprecated(" Use resourceResolutionService method directly", + replaceWith = ReplaceWith("resourceResolutionService()", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resourceResolutionService")) open fun resourceResolutionService(): ResourceResolutionService = functionDependencyInstanceAsType(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) + @Deprecated("Defined in AbstractScriptComponentFunction extension class") fun restClientService(selector: String): BlueprintWebClientService { return bluePrintRestLibPropertyService().blueprintWebClientService(selector) } + @Deprecated(" Use storedContentFromResolvedArtifact method directly", + replaceWith = ReplaceWith("storedContentFromResolvedArtifact(resolutionKey, artifactName)", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.storedContentFromResolvedArtifact")) fun resolveFromDatabase(resolutionKey: String, artifactName: String): String = runBlocking { resourceResolutionService().resolveFromDatabase(bluePrintRuntimeService, artifactName, resolutionKey) } + @Deprecated(" Use artifactContent method directly", + replaceWith = ReplaceWith("artifactContent(artifactName)", + "org.onap.ccsdk.cds.blueprintsprocessor.services.execution.artifactContent")) fun generateMessage(artifactName: String): String { return bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName) } + @Deprecated(" Use contentFromResolvedArtifact method directly", + replaceWith = ReplaceWith("resolveAndGenerateMessage(artifactPrefix)", + "org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resolveAndGenerateMessage")) fun resolveAndGenerateMessage(artifactPrefix: String): String = runBlocking { resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName, artifactPrefix, mapOf()) diff --git a/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/ScriptComponentExtensions.kt b/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/ScriptComponentExtensions.kt new file mode 100644 index 000000000..9fc685e19 --- /dev/null +++ b/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/ScriptComponentExtensions.kt @@ -0,0 +1,36 @@ +/* + * 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.restconf.executor + +/** + * Register the Restconf module exposed dependency + */ + + +/** + * Generic Mount function + */ + + +/** + * Generic Configure function + */ + + +/** + * Generic Unmount function + */
\ No newline at end of file |