diff options
Diffstat (limited to 'ms/blueprintsprocessor/functions')
11 files changed, 650 insertions, 18 deletions
diff --git a/ms/blueprintsprocessor/functions/pom.xml b/ms/blueprintsprocessor/functions/pom.xml index 24cc352c9..3f948061f 100755 --- a/ms/blueprintsprocessor/functions/pom.xml +++ b/ms/blueprintsprocessor/functions/pom.xml @@ -47,6 +47,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.mock-server</groupId> + <artifactId>mockserver-netty</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <scope>test</scope> 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 new file mode 100644 index 000000000..6437cdf03 --- /dev/null +++ b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt @@ -0,0 +1,134 @@ +/* + * 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.python.executor + +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 +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.RemoteScriptExecutionService +import org.onap.ccsdk.cds.controllerblueprints.command.api.ResponseStatus +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode +import org.onap.ccsdk.cds.controllerblueprints.core.checkFileExists +import org.onap.ccsdk.cds.controllerblueprints.core.checkNotBlank +import org.onap.ccsdk.cds.controllerblueprints.core.data.OperationAssignment +import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile +import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.config.ConfigurableBeanFactory +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component +import java.lang.Exception + +@ConditionalOnBean(name = [ExecutionServiceConstant.SERVICE_GRPC_REMOTE_SCRIPT_EXECUTION]) +@Component("component-remote-python-executor") +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +open class ComponentRemotePythonExecutor(private val remoteScriptExecutionService: RemoteScriptExecutionService) + : AbstractComponentFunction() { + + private val log = LoggerFactory.getLogger(ComponentRemotePythonExecutor::class.java)!! + + companion object { + const val INPUT_ENDPOINT_SELECTOR = "endpoint-selector" + const val INPUT_DYNAMIC_PROPERTIES = "dynamic-properties" + const val INPUT_COMMAND = "command" + } + + override suspend fun processNB(executionRequest: ExecutionServiceInput) { + + log.info("Processing : $operationInputs") + + val bluePrintContext = bluePrintRuntimeService.bluePrintContext() + val blueprintName = bluePrintContext.name() + val blueprintVersion = bluePrintContext.version() + + val operationAssignment: OperationAssignment = bluePrintContext + .nodeTemplateInterfaceOperation(nodeTemplateName, interfaceName, operationName) + + val artifactName: String = operationAssignment.implementation?.primary + ?: throw BluePrintProcessorException("missing primary field to get artifact name for node template ($nodeTemplateName)") + + val artifactDefinition = + bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName) + + checkNotBlank(artifactDefinition.file) { "couldn't get python script path($artifactName)" } + + val pythonScript = normalizedFile(bluePrintContext.rootPath, artifactDefinition.file) + + checkFileExists(pythonScript) { "python script(${pythonScript.absolutePath}) doesn't exists" } + + val endPointSelector = getOperationInput(INPUT_ENDPOINT_SELECTOR) + val dynamicProperties = getOperationInput(INPUT_DYNAMIC_PROPERTIES) + val command = getOperationInput(INPUT_COMMAND).asText() + + // TODO("Python execution command and Resolve some expressions with dynamic properties") + val scriptCommand = command.replace(pythonScript.name, pythonScript.absolutePath) + + val dependencies = operationAssignment.implementation?.dependencies + + try { + // Open GRPC Connection + remoteScriptExecutionService.init(endPointSelector.asText()) + + var executionLogs = "" + + // If dependencies are defined, then install in remote server + if (dependencies != null && dependencies.isNotEmpty()) { + val prepareEnvInput = PrepareRemoteEnvInput(requestId = processId, + remoteIdentifier = RemoteIdentifier(blueprintName = blueprintName, + blueprintVersion = blueprintVersion), + remoteScriptType = RemoteScriptType.PYTHON, + packages = dependencies + ) + val prepareEnvOutput = remoteScriptExecutionService.prepareEnv(prepareEnvInput) + executionLogs = prepareEnvOutput.response + setOutput(executionLogs) + check(prepareEnvOutput.status == StatusType.SUCCESS) { + "failed to get prepare remote env response status for requestId(${prepareEnvInput.requestId})" + } + } + + val remoteExecutionInput = RemoteScriptExecutionInput( + requestId = processId, + remoteIdentifier = RemoteIdentifier(blueprintName = blueprintName, blueprintVersion = blueprintVersion), + remoteScriptType = RemoteScriptType.PYTHON, + command = scriptCommand) + val remoteExecutionOutput = remoteScriptExecutionService.executeCommand(remoteExecutionInput) + executionLogs += remoteExecutionOutput.response + setOutput(executionLogs) + check(remoteExecutionOutput.status == StatusType.SUCCESS) { + "failed to get prepare remote command response status for requestId(${remoteExecutionOutput.requestId})" + } + + } catch (e: Exception) { + log.error("", e) + } finally { + remoteScriptExecutionService.close() + } + } + + private fun setOutput(executionLogs: String) { + bluePrintRuntimeService.setNodeTemplateAttributeValue(nodeTemplateName, + "execution-logs", JacksonUtils.jsonNodeFromObject(executionLogs)) + } + + override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { + bluePrintRuntimeService.getBluePrintError() + .addError("Failed in ComponentJythonExecutor : ${runtimeException.message}") + } +}
\ No newline at end of file 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 new file mode 100644 index 000000000..7cd5d5cac --- /dev/null +++ b/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt @@ -0,0 +1,91 @@ +/* + * 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.python.executor + +import com.fasterxml.jackson.databind.JsonNode +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.runBlocking +import org.junit.Test +import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.* +import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.RemoteScriptExecutionService +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.putJsonElement +import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils +import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import kotlin.test.assertEquals +import kotlin.test.assertNotNull + + +class ComponentRemotePythonExecutorTest { + + @Test + fun testComponentRemotePythonExecutor() { + runBlocking { + val remoteScriptExecutionService = MockRemoteScriptExecutionService() + + val componentRemotePythonExecutor = ComponentRemotePythonExecutor(remoteScriptExecutionService) + + 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") + + val stepMetaData: MutableMap<String, JsonNode> = hashMapOf() + stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, "execute-remote-python") + stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_INTERFACE, "ComponentRemotePythonExecutor") + stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_OPERATION, "process") + componentRemotePythonExecutor.bluePrintRuntimeService = bluePrintRuntimeService + val stepInputData = StepData().apply { + name = "execute-remote-python" + properties = stepMetaData + } + executionServiceInput.stepData = stepInputData + componentRemotePythonExecutor.applyNB(executionServiceInput) + } + + } +} + +class MockRemoteScriptExecutionService : RemoteScriptExecutionService { + override suspend fun init(selector: String) { + } + + override suspend fun prepareEnv(prepareEnvInput: PrepareRemoteEnvInput): RemoteScriptExecutionOutput { + assertEquals(prepareEnvInput.requestId, "123456-1000", "failed to match request id") + assertEquals(prepareEnvInput.remoteScriptType, RemoteScriptType.PYTHON, "failed to match script type") + assertNotNull(prepareEnvInput.packages, "failed to get packages") + + val remoteScriptExecutionOutput = mockk<RemoteScriptExecutionOutput>() + every { remoteScriptExecutionOutput.status } returns StatusType.SUCCESS + return remoteScriptExecutionOutput + } + + override suspend fun executeCommand(remoteExecutionInput: RemoteScriptExecutionInput): RemoteScriptExecutionOutput { + assertEquals(remoteExecutionInput.requestId, "123456-1000", "failed to match request id") + assertEquals(remoteExecutionInput.remoteScriptType, RemoteScriptType.PYTHON, "failed to match script type") + + val remoteScriptExecutionOutput = mockk<RemoteScriptExecutionOutput>() + every { remoteScriptExecutionOutput.status } returns StatusType.SUCCESS + return remoteScriptExecutionOutput + } + + override suspend fun close() { + + } +}
\ 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/RestResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt index 9852e3438..2d726d487 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt @@ -101,7 +101,7 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS } } - private fun blueprintWebClientService(resourceAssignment: ResourceAssignment, + fun blueprintWebClientService(resourceAssignment: ResourceAssignment, restResourceSource: RestResourceSource): BlueprintWebClientService { return if (isNotEmpty(restResourceSource.endpointSelector)) { val restPropertiesJson = raRuntimeService.resolveDSLExpression(restResourceSource.endpointSelector!!) @@ -195,12 +195,8 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS checkNotEmpty(resourceAssignment.dictionaryName) { "resource assignment dictionary name is not defined for template key (${resourceAssignment.name})" } - checkEquals(ResourceDictionaryConstants.SOURCE_PRIMARY_CONFIG_DATA, resourceAssignment.dictionarySource) { - "resource assignment source is not ${ResourceDictionaryConstants.SOURCE_PRIMARY_CONFIG_DATA} but it is " + - "${resourceAssignment.dictionarySource}" - } - checkNotEmpty(resourceAssignment.dictionaryName) { - "resource assignment dictionary name is not defined for template key (${resourceAssignment.name})" + checkNotEmpty(resourceAssignment.dictionarySource) { + "resource assignment dictionary source is not defined for template key (${resourceAssignment.name})" } } @@ -208,5 +204,4 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS raRuntimeService.getBluePrintError().addError(runtimeException.message!!) } - }
\ 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 3f251b104..9c2a100bc 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 @@ -128,7 +128,7 @@ class ResourceResolutionServiceTest { val artifactPrefix = "another" - // Velocity Artifact Definition Name + // Templating Artifact Definition Name val artifactTemplate = "$artifactPrefix-template" // Resource Assignment Artifact Definition Name val artifactMapping = "$artifactPrefix-mapping" diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockBlueprintResLibPropertyService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockBlueprintResLibPropertyService.kt new file mode 100644 index 000000000..b79f48682 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockBlueprintResLibPropertyService.kt @@ -0,0 +1,36 @@ +/* + * Copyright © 2019 IBM, 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.mock + +import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties +import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPropertyService + +class MockBluePrintRestLibPropertyService(bluePrintProperties: BluePrintProperties) : + BluePrintRestLibPropertyService(bluePrintProperties) { + + fun mockBlueprintWebClientService (selector: String): + MockBlueprintWebClientService { + val prefix = "blueprintsprocessor.restclient.$selector" + val restClientProperties = restClientProperties(prefix) + return mockBlueprintWebClientService(restClientProperties) + } + + private fun mockBlueprintWebClientService(restClientProperties: RestClientProperties): + MockBlueprintWebClientService { + return MockBlueprintWebClientService(restClientProperties) + } +}
\ 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/MockBlueprintWebClientService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockBlueprintWebClientService.kt new file mode 100644 index 000000000..c6ca41351 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockBlueprintWebClientService.kt @@ -0,0 +1,124 @@ +/* + * Copyright © 2019 IBM, 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.mock + +import org.apache.http.message.BasicHeader +import org.mockserver.integration.ClientAndServer +import org.mockserver.model.Header +import org.mockserver.model.HttpRequest.request +import org.mockserver.model.HttpResponse.response +import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestClientProperties +import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService +import org.springframework.http.HttpHeaders +import org.springframework.http.MediaType +import java.nio.charset.Charset +import java.util.* + +class MockBlueprintWebClientService(private var restClientProperties: RestClientProperties): BlueprintWebClientService { + private var mockServer: ClientAndServer + private var port: String = if (restClientProperties.url.split(":")[2].isEmpty()) "8080" + else restClientProperties.url.split(":")[2] + private var headers: Map<String, String> + + init { + mockServer = ClientAndServer.startClientAndServer(port.toInt()) + headers = defaultHeaders() + + // Create expected requests and responses + setRequest("GET", "/aai/v14/network/generic-vnfs/generic-vnf/123456") + setRequest("GET", "/config/GENERIC-RESOURCE-API:services/service/10/service-data/vnfs/vnf/123456/" + + "vnf-data/vnf-topology/vnf-parameters-data/param/vnf_name") + setRequestWithPayload("PUT", "/query", + "{\r\n\"start\": \"\\/nodes\\/vf-modules?vf-module-name=vf-module-name\",\r\n\"query\": \"\\/query\\/related-to?startingNodeType=vf-module&relatedToNodeType=generic-vnf\"\r\n}") + } + + override fun defaultHeaders(): Map<String, String> { + val encodedCredentials = this.setBasicAuth("admin", "aaiTest") + return mapOf( + HttpHeaders.CONTENT_TYPE to MediaType.APPLICATION_JSON_VALUE, + HttpHeaders.ACCEPT to MediaType.APPLICATION_JSON_VALUE, + HttpHeaders.AUTHORIZATION to "Basic $encodedCredentials") + } + + override fun host(uri: String): String { + return restClientProperties.url + uri + } + + fun tearDown() { + mockServer.close() + } + + override fun exchangeResource(method: String, path: String, payload: String): String { + val header = arrayOf(BasicHeader(HttpHeaders.AUTHORIZATION, headers[HttpHeaders.AUTHORIZATION])) + return when (method) { + "POST" -> { + post(path, payload, header) + } + "PUT" -> { + put(path, payload, header) + } + else -> { + get(path, header) + } + } + } + + private fun setRequest(method: String, path: String) { + val requestResponse = when (method) { + "POST" -> { + "Post response" + } + "PUT" -> { + "Put response" + } + else -> { + "Get response" + } + + } + mockServer.`when`(request().withHeaders(Header(HttpHeaders.AUTHORIZATION, headers[HttpHeaders.AUTHORIZATION])) + .withMethod(method) + .withPath(path) + ).respond(response().withStatusCode(200).withBody("{\"aai-resource\":\"$requestResponse\"}")) + } + + private fun setRequestWithPayload(method: String, path: String, payload: String) { + val requestResponse = when (method) { + "POST" -> { + "Post response" + } + "PUT" -> { + "Put response" + } + else -> { + "Get response" + } + + } + mockServer.`when`(request().withHeaders(Header(HttpHeaders.AUTHORIZATION, headers[HttpHeaders.AUTHORIZATION])) + .withMethod(method) + .withPath(path) + .withQueryStringParameter("format", "resource") + .withBody(payload) + ).respond(response().withStatusCode(200).withBody("{\"aai-resource\":\"$requestResponse\"}")) + } + + private fun setBasicAuth(username: String, password: String): String { + val credentialsString = "$username:$password" + return Base64.getEncoder().encodeToString( + credentialsString.toByteArray(Charset.defaultCharset())) + } +}
\ 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 new file mode 100644 index 000000000..2c481dca3 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockRestResourceResolutionProcessor.kt @@ -0,0 +1,159 @@ +/* + * Copyright © 2019 IBM, 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.mock + +import com.fasterxml.jackson.databind.node.ArrayNode +import com.fasterxml.jackson.databind.node.MissingNode +import org.apache.commons.collections.MapUtils +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.RestResourceSource +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.ResourceAssignmentProcessor +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils +import org.onap.ccsdk.cds.controllerblueprints.core.* +import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment +import org.slf4j.LoggerFactory +import java.util.HashMap + +class MockRestResourceResolutionProcessor(private val blueprintRestLibPropertyService: + MockBluePrintRestLibPropertyService): ResourceAssignmentProcessor() { + + private val logger = LoggerFactory.getLogger(MockRestResourceResolutionProcessor::class.java) + + override fun resolveInputKeyMappingVariables(inputKeyMapping: Map<String, String>): Map<String, Any> { + val resolvedInputKeyMapping = HashMap<String, Any>() + if (MapUtils.isNotEmpty(inputKeyMapping)) { + resolvedInputKeyMapping["service-instance-id"] = "10" + resolvedInputKeyMapping["vnf_name"] = "vnf1" + resolvedInputKeyMapping["vnf-id"] = "123456" + } + return resolvedInputKeyMapping + } + + override fun getName(): String { + return "${ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-rest" + } + + override suspend fun processNB(executionRequest: ResourceAssignment) { + try { + // Check if It has Input + val value = getFromInput(executionRequest) + if (value == null || value is MissingNode) { + val dName = executionRequest.dictionaryName + val dSource = executionRequest.dictionarySource + val resourceDefinition = resourceDictionaries[dName] + + val resourceSource = resourceDefinition!!.sources[dSource] + + val resourceSourceProperties = resourceSource!!.properties + + val sourceProperties = + JacksonUtils.getInstanceFromMap(resourceSourceProperties!!, RestResourceSource::class.java) + + val path = nullToEmpty(sourceProperties.path) + val inputKeyMapping = sourceProperties.inputKeyMapping + + val resolvedInputKeyMapping = resolveInputKeyMappingVariables(inputKeyMapping!!).toMutableMap() + + // Resolving content Variables + val payload = resolveFromInputKeyMapping(nullToEmpty(sourceProperties.payload), resolvedInputKeyMapping) + val urlPath = + resolveFromInputKeyMapping(checkNotNull(sourceProperties.urlPath), resolvedInputKeyMapping) + val verb = resolveFromInputKeyMapping(nullToEmpty(sourceProperties.verb), resolvedInputKeyMapping) + + logger.info("$dSource dictionary information : ($urlPath), ($inputKeyMapping), (${sourceProperties.outputKeyMapping})") + + // Get the Rest Client Service + val restClientService = blueprintWebClientService(executionRequest) + + val response = restClientService.exchangeResource(verb, urlPath, payload) + if (response.isEmpty()) { + logger.warn("Failed to get $dSource result for dictionary name ($dName) using urlPath ($urlPath)") + } else { + populateResource(executionRequest, sourceProperties, response, path) + restClientService.tearDown() + } + } + } catch (e: Exception) { + ResourceAssignmentUtils.setFailedResourceDataValue(executionRequest, e.message) + throw BluePrintProcessorException("Failed in template key ($executionRequest) assignments with: ${e.message}", + e) + } + } + + override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ResourceAssignment) { + raRuntimeService.getBluePrintError().addError(runtimeException.message!!) + } + + private fun blueprintWebClientService(resourceAssignment: ResourceAssignment): MockBlueprintWebClientService { + return blueprintRestLibPropertyService.mockBlueprintWebClientService(resourceAssignment.dictionarySource!!) + } + + @Throws(BluePrintProcessorException::class) + private fun populateResource(resourceAssignment: ResourceAssignment, sourceProperties: RestResourceSource, + restResponse: String, path: String) { + val type = nullToEmpty(resourceAssignment.property?.type) + lateinit var entrySchemaType: String + + val outputKeyMapping = sourceProperties.outputKeyMapping + + val responseNode = JacksonUtils.jsonNode(restResponse).at(path) + + when (type) { + in BluePrintTypes.validPrimitiveTypes() -> { + ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, responseNode) + } + in BluePrintTypes.validCollectionTypes() -> { + // Array Types + entrySchemaType = resourceAssignment.property!!.entrySchema!!.type + val arrayNode = responseNode as ArrayNode + + if (entrySchemaType !in BluePrintTypes.validPrimitiveTypes()) { + val responseArrayNode = responseNode.toList() + for (responseSingleJsonNode in responseArrayNode) { + + val arrayChildNode = JacksonUtils.objectMapper.createObjectNode() + + outputKeyMapping!!.map { + val responseKeyValue = responseSingleJsonNode.get(it.key) + val propertyTypeForDataType = ResourceAssignmentUtils + .getPropertyType(raRuntimeService, entrySchemaType, it.key) + + JacksonUtils.populateJsonNodeValues(it.value, + responseKeyValue, propertyTypeForDataType, arrayChildNode) + } + arrayNode.add(arrayChildNode) + } + } + // Set the List of Complex Values + ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, arrayNode) + } + else -> { + // Complex Types + entrySchemaType = resourceAssignment.property!!.type + val objectNode = JacksonUtils.objectMapper.createObjectNode() + outputKeyMapping!!.map { + val responseKeyValue = responseNode.get(it.key) + val propertyTypeForDataType = ResourceAssignmentUtils + .getPropertyType(raRuntimeService, entrySchemaType, it.key) + JacksonUtils.populateJsonNodeValues(it.value, responseKeyValue, propertyTypeForDataType, objectNode) + } + // Set the List of Complex Values + ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, objectNode) + } + } + } +}
\ 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/processor/CapabilityResourceResolutionProcessorTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessorTest.kt index 2af15c2be..66fdd8ff8 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessorTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessorTest.kt @@ -123,7 +123,6 @@ class CapabilityResourceResolutionProcessorTest { println(processorName) } } - } open class MockCapabilityService { diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessorTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessorTest.kt index 08174ed47..7e7e65635 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessorTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessorTest.kt @@ -16,13 +16,15 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor import kotlinx.coroutines.runBlocking -import org.junit.Ignore 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.functions.resource.resolution.ResourceAssignmentRuntimeService +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.mock.MockBluePrintRestLibPropertyService +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.mock.MockRestResourceResolutionProcessor import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils +import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestClientProperties import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPropertyService import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils @@ -31,18 +33,25 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.TestPropertySource import org.springframework.test.context.junit4.SpringRunner +import kotlin.test.AfterTest +import kotlin.test.BeforeTest import kotlin.test.assertNotNull @RunWith(SpringRunner::class) -@ContextConfiguration(classes = [RestResourceResolutionProcessor::class, BluePrintRestLibPropertyService::class, - BlueprintPropertyConfiguration::class, BluePrintProperties::class]) +@ContextConfiguration(classes = [MockRestResourceResolutionProcessor::class, MockBluePrintRestLibPropertyService::class, + BlueprintPropertyConfiguration::class, BluePrintProperties::class, RestClientProperties::class]) @TestPropertySource(locations = ["classpath:application-test.properties"]) class RestResourceResolutionProcessorTest { - @Autowired - lateinit var restResourceResolutionProcessor: RestResourceResolutionProcessor + lateinit var bluePrintRestLibPropertyService: MockBluePrintRestLibPropertyService + + private lateinit var restResourceResolutionProcessor: MockRestResourceResolutionProcessor + + @BeforeTest + fun init(){ + restResourceResolutionProcessor = MockRestResourceResolutionProcessor(bluePrintRestLibPropertyService) + } - @Ignore @Test fun `test rest resource resolution`() { runBlocking { @@ -55,7 +64,11 @@ class RestResourceResolutionProcessorTest { restResourceResolutionProcessor.resourceDictionaries = ResourceAssignmentUtils .resourceDefinitions(bluePrintContext.rootPath) - //TODO ("Mock the dependency values and rest service.") + val scriptPropertyInstances: MutableMap<String, Any> = mutableMapOf() + scriptPropertyInstances["mock-service1"] = MockCapabilityService() + scriptPropertyInstances["mock-service2"] = MockCapabilityService() + + restResourceResolutionProcessor.scriptPropertyInstances = scriptPropertyInstances val resourceAssignment = ResourceAssignment().apply { name = "rr-name" @@ -71,4 +84,70 @@ class RestResourceResolutionProcessorTest { println(processorName) } } + + @Test + fun `test rest aai get resource resolution`() { + runBlocking { + val bluePrintContext = BluePrintMetadataUtils.getBluePrintContext( + "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") + + val resourceAssignmentRuntimeService = ResourceAssignmentRuntimeService("1234", bluePrintContext) + + restResourceResolutionProcessor.raRuntimeService = resourceAssignmentRuntimeService + restResourceResolutionProcessor.resourceDictionaries = ResourceAssignmentUtils + .resourceDefinitions(bluePrintContext.rootPath) + + val scriptPropertyInstances: MutableMap<String, Any> = mutableMapOf() + scriptPropertyInstances["mock-service1"] = MockCapabilityService() + scriptPropertyInstances["mock-service2"] = MockCapabilityService() + + restResourceResolutionProcessor.scriptPropertyInstances = scriptPropertyInstances + + val resourceAssignment = ResourceAssignment().apply { + name = "rr-aai" + dictionaryName = "aai-get-resource" + dictionarySource = "primary-aai-data" + property = PropertyDefinition().apply { + type = "string" + } + } + + val processorName = restResourceResolutionProcessor.applyNB(resourceAssignment) + assertNotNull(processorName, "couldn't get AAI Rest resource assignment processor name") + println(processorName) + } + } + + @Test + fun `test rest aai put resource resolution`() { + runBlocking { + val bluePrintContext = BluePrintMetadataUtils.getBluePrintContext( + "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") + + val resourceAssignmentRuntimeService = ResourceAssignmentRuntimeService("1234", bluePrintContext) + + restResourceResolutionProcessor.raRuntimeService = resourceAssignmentRuntimeService + restResourceResolutionProcessor.resourceDictionaries = ResourceAssignmentUtils + .resourceDefinitions(bluePrintContext.rootPath) + + val scriptPropertyInstances: MutableMap<String, Any> = mutableMapOf() + scriptPropertyInstances["mock-service1"] = MockCapabilityService() + scriptPropertyInstances["mock-service2"] = MockCapabilityService() + + restResourceResolutionProcessor.scriptPropertyInstances = scriptPropertyInstances + + val resourceAssignment = ResourceAssignment().apply { + name = "rr-aai" + dictionaryName = "aai-put-resource" + dictionarySource = "primary-aai-data" + property = PropertyDefinition().apply { + type = "string" + } + } + + val processorName = restResourceResolutionProcessor.applyNB(resourceAssignment) + assertNotNull(processorName, "couldn't get AAI Rest resource assignment processor name") + println(processorName) + } + } }
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/resources/application-test.properties b/ms/blueprintsprocessor/functions/resource-resolution/src/test/resources/application-test.properties index 071b27afc..5deea31e1 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/resources/application-test.properties +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/resources/application-test.properties @@ -28,4 +28,14 @@ blueprintsprocessor.blueprintArchivePath=./target/blueprints/archive blueprintsprocessor.blueprintWorkingPath=./target/blueprints/work # Python executor blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_blueprints -blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints
\ No newline at end of file +blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints + +blueprintsprocessor.restclient.primary-config-data.type=basic-auth +blueprintsprocessor.restclient.primary-config-data.url=http://127.0.0.1:9911 +blueprintsprocessor.restclient.primary-config-data.username=sampleuser +blueprintsprocessor.restclient.primary-config-data.password=sampletoken + +blueprintsprocessor.restclient.primary-aai-data.type=basic-auth +blueprintsprocessor.restclient.primary-aai-data.url=http://127.0.0.1:30800 +blueprintsprocessor.restclient.primary-aai-data.username=admin +blueprintsprocessor.restclient.primary-aai-data.password=aaiTest
\ No newline at end of file |