summaryrefslogtreecommitdiffstats
path: root/ms
diff options
context:
space:
mode:
Diffstat (limited to 'ms')
-rwxr-xr-xms/blueprintsprocessor/application/src/main/resources/application-dev.properties8
-rwxr-xr-xms/blueprintsprocessor/application/src/main/resources/application.properties18
-rw-r--r--ms/blueprintsprocessor/application/src/test/resources/application.properties10
-rw-r--r--ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt77
-rw-r--r--ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutorTest.kt91
-rw-r--r--ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibConfiguration.kt1
-rw-r--r--ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibData.kt6
-rw-r--r--ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BasicAuthGrpcClientService.kt40
-rw-r--r--ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcClientService.kt23
-rw-r--r--ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyService.kt38
-rw-r--r--ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TokenAuthGrpcClientService.kt54
-rw-r--r--ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintRemoteProcessorData.kt17
-rw-r--r--ms/blueprintsprocessor/modules/services/execution-service/pom.xml4
-rw-r--r--ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ExecutionServiceConfiguration.kt29
-rw-r--r--ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt129
-rwxr-xr-xms/blueprintsprocessor/parent/pom.xml8
-rw-r--r--ms/cds-sdc-listener/application/pom.xml107
-rw-r--r--ms/cds-sdc-listener/application/src/main/docker/Dockerfile13
-rw-r--r--ms/cds-sdc-listener/application/src/main/docker/docker-compose.yaml29
-rwxr-xr-xms/cds-sdc-listener/application/src/main/docker/start.sh6
-rw-r--r--ms/cds-sdc-listener/application/src/main/resources/application.yml46
-rw-r--r--ms/cds-sdc-listener/application/src/main/resources/logback.xml33
-rw-r--r--ms/cds-sdc-listener/distribution/pom.xml106
-rwxr-xr-xms/command-executor/pom.xml155
-rw-r--r--ms/command-executor/src/main/docker/Dockerfile21
-rwxr-xr-xms/command-executor/src/main/docker/distribution.xml31
-rwxr-xr-xms/command-executor/src/main/docker/start.sh32
-rw-r--r--ms/command-executor/src/main/python/command_executor_handler.py105
-rw-r--r--ms/command-executor/src/main/python/command_executor_server.py57
-rw-r--r--ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py422
-rw-r--r--ms/command-executor/src/main/python/proto/CommandExecutor_pb2_grpc.py63
-rw-r--r--ms/command-executor/src/main/python/proto/__init__.py0
-rw-r--r--ms/command-executor/src/main/python/request_header_validator_interceptor.py38
-rw-r--r--ms/command-executor/src/main/python/server.py72
-rw-r--r--ms/command-executor/src/main/python/utils.py37
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt4
-rw-r--r--ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt10
-rw-r--r--ms/pom.xml1
38 files changed, 1771 insertions, 170 deletions
diff --git a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties
index 0e2cdf9de..2b90998b1 100755
--- a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties
+++ b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties
@@ -47,4 +47,10 @@ blueprintsprocessor.restconfEnabled=true
blueprintsprocessor.restclient.sdncodl.type=basic-auth
blueprintsprocessor.restclient.sdncodl.url=http://localhost:8282/
blueprintsprocessor.restclient.sdncodl.username=admin
-blueprintsprocessor.restclient.sdncodl.password=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U \ No newline at end of file
+blueprintsprocessor.restclient.sdncodl.password=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
+
+# Executor Options
+blueprintprocessor.resourceResolution.enabled=true
+blueprintprocessor.netconfExecutor.enabled=true
+blueprintprocessor.restConfExecutor.enabled=true
+blueprintprocessor.remoteScriptCommand.enabled=false \ No newline at end of file
diff --git a/ms/blueprintsprocessor/application/src/main/resources/application.properties b/ms/blueprintsprocessor/application/src/main/resources/application.properties
index b34609cd1..e5b1fe58f 100755
--- a/ms/blueprintsprocessor/application/src/main/resources/application.properties
+++ b/ms/blueprintsprocessor/application/src/main/resources/application.properties
@@ -13,11 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-#logging.level.web=DEBUG
-
# Web server config
-server.port=8080
-
blueprintsprocessor.grpcEnable=false
blueprintsprocessor.httpPort=8080
blueprintsprocessor.grpcPort=9111
@@ -25,7 +21,8 @@ blueprintsprocessor.grpcPort=9111
# Blueprint Processor File Execution and Handling Properties
blueprintsprocessor.blueprintDeployPath=/opt/app/onap/blueprints/deploy
blueprintsprocessor.blueprintArchivePath=/opt/app/onap/blueprints/archive
-blueprintsprocessor.blueprintWorkingPath=/opt/app/onap/blueprints/work
+blueprintsprocessor.blueprintWorkingPath=/opt/app/onap/blueprints/working
+
# Primary Database Configuration
blueprintsprocessor.db.primary.url=jdbc:mysql://db:3306/sdnctl
blueprintsprocessor.db.primary.username=sdnctl
@@ -49,3 +46,14 @@ blueprintsprocessor.restclient.sdncodl.type=basic-auth
blueprintsprocessor.restclient.sdncodl.url=http://sdnc:8282/
blueprintsprocessor.restclient.sdncodl.username=admin
blueprintsprocessor.restclient.sdncodl.password=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
+
+# Executor Options
+blueprintprocessor.resourceResolution.enabled=true
+blueprintprocessor.netconfExecutor.enabled=true
+blueprintprocessor.restConfExecutor.enabled=true
+blueprintprocessor.remoteScriptCommand.enabled=true
+
+blueprintsprocessor.grpcclient.remote-python.type=token-auth
+blueprintsprocessor.grpcclient.remote-python.host=localhost
+blueprintsprocessor.grpcclient.remote-python.port=50051
+blueprintsprocessor.grpcclient.remote-python.token=Basic Y2NzZGthcHBzOmNjc2RrYXBwcw== \ No newline at end of file
diff --git a/ms/blueprintsprocessor/application/src/test/resources/application.properties b/ms/blueprintsprocessor/application/src/test/resources/application.properties
index 307850547..7e462f25d 100644
--- a/ms/blueprintsprocessor/application/src/test/resources/application.properties
+++ b/ms/blueprintsprocessor/application/src/test/resources/application.properties
@@ -37,5 +37,11 @@ blueprintsprocessor.db.primary.hibernateDialect=org.hibernate.dialect.H2Dialect
blueprints.processor.functions.python.executor.executionPath=/opt/app/onap/scripts/jython/ccsdk_blueprints
blueprints.processor.functions.python.executor.modulePaths=/opt/app/onap/scripts/jython/ccsdk_blueprints
-security.user.password: {bcrypt}$2a$10$duaUzVUVW0YPQCSIbGEkQOXwafZGwQ/b32/Ys4R1iwSSawFgz7QNu
-security.user.name: ccsdkapps
+security.user.password:{bcrypt}$2a$10$duaUzVUVW0YPQCSIbGEkQOXwafZGwQ/b32/Ys4R1iwSSawFgz7QNu
+security.user.name:ccsdkapps
+
+# Executor Options
+blueprintprocessor.resourceResolution.enabled=true
+blueprintprocessor.netconfExecutor.enabled=true
+blueprintprocessor.restConfExecutor.enabled=true
+blueprintprocessor.remoteScriptCommand.enabled=false
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 d34dbb7e9..6437cdf03 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
@@ -18,28 +18,35 @@ 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)
+ 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) {
@@ -51,51 +58,77 @@ open class ComponentRemotePythonExecutor(private val remoteScriptExecutionServic
val blueprintVersion = bluePrintContext.version()
val operationAssignment: OperationAssignment = bluePrintContext
- .nodeTemplateInterfaceOperation(nodeTemplateName, interfaceName, operationName)
+ .nodeTemplateInterfaceOperation(nodeTemplateName, interfaceName, operationName)
val artifactName: String = operationAssignment.implementation?.primary
- ?: throw BluePrintProcessorException("missing primary field to get artifact name for node template ($nodeTemplateName)")
+ ?: throw BluePrintProcessorException("missing primary field to get artifact name for node template ($nodeTemplateName)")
- val artifactDefinition = bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
+ 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" }
- //TODO ("Get the ENDPOINT SELECTOR and resolve the Remote Server")
+
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: String = "python ${pythonScript.absolutePath}"
+ val scriptCommand = command.replace(pythonScript.name, pythonScript.absolutePath)
+
+ val dependencies = operationAssignment.implementation?.dependencies
+
+ try {
+ // Open GRPC Connection
+ remoteScriptExecutionService.init(endPointSelector.asText())
+
+ var executionLogs = ""
- val packages = operationAssignment.implementation?.dependencies
- // If dependencies are defined, then install in remote server
- if (packages != null && !packages.isEmpty()) {
- val prepareEnvInput = PrepareRemoteEnvInput(requestId = processId,
+ // 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 = arrayListOf()
- )
- val prepareEnvOutput = remoteScriptExecutionService.prepareEnv(prepareEnvInput)
- checkNotNull(prepareEnvOutput) {
- "failed to get prepare remote env response for requestId(${prepareEnvInput.requestId})"
+ 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(
+ val remoteExecutionInput = RemoteScriptExecutionInput(
requestId = processId,
remoteIdentifier = RemoteIdentifier(blueprintName = blueprintName, blueprintVersion = blueprintVersion),
remoteScriptType = RemoteScriptType.PYTHON,
command = scriptCommand)
- val remoteExecutionOutput = remoteScriptExecutionService.executeCommand(remoteExecutionInput)
- checkNotNull(remoteExecutionOutput) {
- "failed to get prepare remote command response for requestId(${remoteExecutionOutput.requestId})"
+ 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}")
+ .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/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibConfiguration.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibConfiguration.kt
index 3fbc42742..1bef3a0f2 100644
--- a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibConfiguration.kt
+++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibConfiguration.kt
@@ -26,6 +26,7 @@ open class BluePrintGrpcLibConfiguration
class GRPCLibConstants {
companion object {
const val SERVICE_BLUEPRINT_GRPC_LIB_PROPERTY = "blueprint-grpc-lib-property-service"
+ const val TYPE_TOKEN_AUTH = "token-auth"
const val TYPE_BASIC_AUTH = "basic-auth"
}
} \ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibData.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibData.kt
index 1e082b408..76e60bd0d 100644
--- a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibData.kt
+++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/BluePrintGrpcLibData.kt
@@ -22,7 +22,11 @@ open class GrpcClientProperties {
var port: Int = -1
}
+open class TokenAuthGrpcClientProperties : GrpcClientProperties() {
+ lateinit var token: String
+}
+
open class BasicAuthGrpcClientProperties : GrpcClientProperties() {
lateinit var username: String
lateinit var password: String
-}
+} \ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BasicAuthGrpcClientService.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BasicAuthGrpcClientService.kt
new file mode 100644
index 000000000..a175d8b3a
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BasicAuthGrpcClientService.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.grpc.service
+
+import io.grpc.ManagedChannel
+import io.grpc.internal.DnsNameResolverProvider
+import io.grpc.internal.PickFirstLoadBalancerProvider
+import io.grpc.netty.NettyChannelBuilder
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.BasicAuthGrpcClientProperties
+
+
+open class BasicAuthGrpcClientService(private val basicAuthGrpcClientProperties: BasicAuthGrpcClientProperties)
+ : BluePrintGrpcClientService {
+
+ override suspend fun channel(): ManagedChannel {
+ val managedChannel = NettyChannelBuilder
+ .forAddress(basicAuthGrpcClientProperties.host, basicAuthGrpcClientProperties.port)
+ .nameResolverFactory(DnsNameResolverProvider())
+ .loadBalancerFactory(PickFirstLoadBalancerProvider())
+ // .intercept(BasicAuthClientInterceptor(basicAuthGrpcClientProperties)).usePlaintext()
+ .build()
+ return managedChannel
+ }
+
+
+}
diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcClientService.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcClientService.kt
new file mode 100644
index 000000000..016c05035
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcClientService.kt
@@ -0,0 +1,23 @@
+/*
+ * 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.grpc.service
+
+import io.grpc.ManagedChannel
+
+interface BluePrintGrpcClientService {
+ suspend fun channel(): ManagedChannel
+} \ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyService.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyService.kt
index 7510d1d96..088533a71 100644
--- a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyService.kt
+++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/BluePrintGrpcLibPropertyService.kt
@@ -21,6 +21,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties
import org.onap.ccsdk.cds.blueprintsprocessor.grpc.BasicAuthGrpcClientProperties
import org.onap.ccsdk.cds.blueprintsprocessor.grpc.GRPCLibConstants
import org.onap.ccsdk.cds.blueprintsprocessor.grpc.GrpcClientProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TokenAuthGrpcClientProperties
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
import org.springframework.stereotype.Service
@@ -28,9 +29,24 @@ import org.springframework.stereotype.Service
@Service(GRPCLibConstants.SERVICE_BLUEPRINT_GRPC_LIB_PROPERTY)
open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: BluePrintProperties) {
+ fun blueprintGrpcClientService(jsonNode: JsonNode): BluePrintGrpcClientService {
+ val restClientProperties = grpcClientProperties(jsonNode)
+ return blueprintGrpcClientService(restClientProperties)
+ }
+
+ fun blueprintGrpcClientService(selector: String): BluePrintGrpcClientService {
+ val prefix = "blueprintsprocessor.grpcclient.$selector"
+ val restClientProperties = grpcClientProperties(prefix)
+ return blueprintGrpcClientService(restClientProperties)
+ }
+
+
fun grpcClientProperties(jsonNode: JsonNode): GrpcClientProperties {
val type = jsonNode.get("type").textValue()
return when (type) {
+ GRPCLibConstants.TYPE_TOKEN_AUTH -> {
+ JacksonUtils.readValue(jsonNode, TokenAuthGrpcClientProperties::class.java)!!
+ }
GRPCLibConstants.TYPE_BASIC_AUTH -> {
JacksonUtils.readValue(jsonNode, BasicAuthGrpcClientProperties::class.java)!!
}
@@ -44,6 +60,9 @@ open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: Blue
val type = bluePrintProperties.propertyBeanType(
"$prefix.type", String::class.java)
return when (type) {
+ GRPCLibConstants.TYPE_TOKEN_AUTH -> {
+ tokenAuthGrpcClientProperties(prefix)
+ }
GRPCLibConstants.TYPE_BASIC_AUTH -> {
basicAuthGrpcClientProperties(prefix)
}
@@ -54,6 +73,25 @@ open class BluePrintGrpcLibPropertyService(private var bluePrintProperties: Blue
}
}
+ private fun blueprintGrpcClientService(grpcClientProperties: GrpcClientProperties):
+ BluePrintGrpcClientService {
+ when (grpcClientProperties) {
+ is TokenAuthGrpcClientProperties -> {
+ return TokenAuthGrpcClientService(grpcClientProperties)
+ }
+ is BasicAuthGrpcClientProperties -> {
+ return BasicAuthGrpcClientService(grpcClientProperties)
+ }
+ else -> {
+ throw BluePrintProcessorException("couldn't get grpc service for type(${grpcClientProperties.type})")
+ }
+ }
+ }
+
+ private fun tokenAuthGrpcClientProperties(prefix: String): TokenAuthGrpcClientProperties {
+ return bluePrintProperties.propertyBeanType(prefix, TokenAuthGrpcClientProperties::class.java)
+ }
+
private fun basicAuthGrpcClientProperties(prefix: String): BasicAuthGrpcClientProperties {
return bluePrintProperties.propertyBeanType(prefix, BasicAuthGrpcClientProperties::class.java)
}
diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TokenAuthGrpcClientService.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TokenAuthGrpcClientService.kt
new file mode 100644
index 000000000..dbff84211
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/service/TokenAuthGrpcClientService.kt
@@ -0,0 +1,54 @@
+/*
+ * 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.grpc.service
+
+import io.grpc.*
+import io.grpc.internal.DnsNameResolverProvider
+import io.grpc.internal.PickFirstLoadBalancerProvider
+import io.grpc.netty.NettyChannelBuilder
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.TokenAuthGrpcClientProperties
+
+class TokenAuthGrpcClientService(private val tokenAuthGrpcClientProperties: TokenAuthGrpcClientProperties)
+ : BluePrintGrpcClientService {
+
+ override suspend fun channel(): ManagedChannel {
+ val managedChannel = NettyChannelBuilder
+ .forAddress(tokenAuthGrpcClientProperties.host, tokenAuthGrpcClientProperties.port)
+ .nameResolverFactory(DnsNameResolverProvider())
+ .loadBalancerFactory(PickFirstLoadBalancerProvider())
+ .intercept(TokenAuthClientInterceptor(tokenAuthGrpcClientProperties)).usePlaintext().build()
+ return managedChannel
+ }
+}
+
+class TokenAuthClientInterceptor(private val tokenAuthGrpcClientProperties: TokenAuthGrpcClientProperties) : ClientInterceptor {
+
+ override fun <ReqT, RespT> interceptCall(method: MethodDescriptor<ReqT, RespT>,
+ callOptions: CallOptions, channel: Channel): ClientCall<ReqT, RespT> {
+
+ val authHeader = Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER)
+
+ return object : ForwardingClientCall
+ .SimpleForwardingClientCall<ReqT, RespT>(channel.newCall(method, callOptions)) {
+
+ override fun start(responseListener: Listener<RespT>, headers: Metadata) {
+ headers.put(authHeader, tokenAuthGrpcClientProperties.token)
+ super.start(responseListener, headers)
+ }
+ }
+ }
+}
diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintRemoteProcessorData.kt b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintRemoteProcessorData.kt
index 90eb933f4..da952c034 100644
--- a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintRemoteProcessorData.kt
+++ b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/api/data/BlueprintRemoteProcessorData.kt
@@ -17,16 +17,22 @@
package org.onap.ccsdk.cds.blueprintsprocessor.core.api.data
import com.fasterxml.jackson.databind.JsonNode
+import java.util.*
enum class RemoteScriptType {
PYTHON, ANSIBLE, KOTLIN, SH
}
-data class RemoteIdentifier(var blueprintName: String? = null,
- var blueprintVersion: String? = null)
+enum class StatusType {
+ SUCCESS, FAILURE
+}
+
+data class RemoteIdentifier(var blueprintName: String,
+ var blueprintVersion: String)
data class RemoteScriptExecutionInput(var requestId: String,
+ var correlationId: String? = null,
var remoteIdentifier: RemoteIdentifier? = null,
var remoteScriptType: RemoteScriptType,
var command: String,
@@ -35,9 +41,14 @@ data class RemoteScriptExecutionInput(var requestId: String,
)
-data class RemoteScriptExecutionOutput(var requestId: String, var response: String)
+data class RemoteScriptExecutionOutput(var requestId: String,
+ var response: String,
+ var status: StatusType = StatusType.SUCCESS,
+ var timestamp: Date = Date())
data class PrepareRemoteEnvInput(var requestId: String,
+ var correlationId: String? = null,
+ var remoteIdentifier: RemoteIdentifier? = null,
var remoteScriptType: RemoteScriptType,
var packages: MutableList<String>?,
var timeOut: Long = 120,
diff --git a/ms/blueprintsprocessor/modules/services/execution-service/pom.xml b/ms/blueprintsprocessor/modules/services/execution-service/pom.xml
index 9ce5292e8..d366f740d 100644
--- a/ms/blueprintsprocessor/modules/services/execution-service/pom.xml
+++ b/ms/blueprintsprocessor/modules/services/execution-service/pom.xml
@@ -54,6 +54,10 @@
<artifactId>rest-lib</artifactId>
</dependency>
<dependency>
+ <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId>
+ <artifactId>grpc-lib</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.onap.ccsdk.cds.controllerblueprints</groupId>
<artifactId>resource-dict</artifactId>
</dependency>
diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ExecutionServiceConfiguration.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ExecutionServiceConfiguration.kt
new file mode 100644
index 000000000..806c33039
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ExecutionServiceConfiguration.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.services.execution
+
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.context.annotation.Configuration
+
+@Configuration
+@ComponentScan
+open class ExecutionServiceConfiguration
+
+
+object ExecutionServiceConstant {
+ const val SERVICE_GRPC_REMOTE_SCRIPT_EXECUTION = "grpc-remote-script-execution-service"
+} \ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt
index 5d279ce3f..7db5f52a4 100644
--- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt
+++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/RemoteScriptExecutionService.kt
@@ -16,12 +16,135 @@
package org.onap.ccsdk.cds.blueprintsprocessor.services.execution
-import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.PrepareRemoteEnvInput
-import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.RemoteScriptExecutionInput
-import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.RemoteScriptExecutionOutput
+import com.fasterxml.jackson.databind.JsonNode
+import com.google.protobuf.Struct
+import com.google.protobuf.Timestamp
+import com.google.protobuf.util.JsonFormat
+import io.grpc.ManagedChannel
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.*
+import org.onap.ccsdk.cds.blueprintsprocessor.grpc.service.BluePrintGrpcLibPropertyService
+import org.onap.ccsdk.cds.controllerblueprints.command.api.*
+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.ConditionalOnProperty
+import org.springframework.context.annotation.Scope
+import org.springframework.stereotype.Service
interface RemoteScriptExecutionService {
+ suspend fun init(selector: String)
suspend fun prepareEnv(prepareEnvInput: PrepareRemoteEnvInput): RemoteScriptExecutionOutput
suspend fun executeCommand(remoteExecutionInput: RemoteScriptExecutionInput): RemoteScriptExecutionOutput
+ suspend fun close()
+}
+
+@Service(ExecutionServiceConstant.SERVICE_GRPC_REMOTE_SCRIPT_EXECUTION)
+@ConditionalOnProperty(prefix = "blueprintprocessor.remoteScriptCommand", name = arrayOf("enabled"),
+ havingValue = "true", matchIfMissing = false)
+@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+class GrpcRemoteScriptExecutionService(private val bluePrintGrpcLibPropertyService: BluePrintGrpcLibPropertyService)
+ : RemoteScriptExecutionService {
+
+ private val log = LoggerFactory.getLogger(GrpcRemoteScriptExecutionService::class.java)!!
+
+ private var channel: ManagedChannel? = null
+ private lateinit var commandExecutorServiceGrpc: CommandExecutorServiceGrpc.CommandExecutorServiceFutureStub
+
+ override suspend fun init(selector: String) {
+ // Get the GRPC Client Service based on selector
+ val grpcClientService = bluePrintGrpcLibPropertyService.blueprintGrpcClientService(selector)
+ // Get the GRPC Channel
+ channel = grpcClientService.channel()
+ // Create Non Blocking Stub
+ commandExecutorServiceGrpc = CommandExecutorServiceGrpc.newFutureStub(channel)
+
+ checkNotNull(commandExecutorServiceGrpc) {
+ "failed to create command executor grpc client for selector($selector)"
+ }
+ }
+
+ override suspend fun prepareEnv(prepareEnvInput: PrepareRemoteEnvInput)
+ : RemoteScriptExecutionOutput {
+ val grpResponse = commandExecutorServiceGrpc.prepareEnv(prepareEnvInput.asGrpcData()).get()
+
+ checkNotNull(grpResponse.status) {
+ "failed to get GRPC prepare env response status for requestId($prepareEnvInput.requestId)"
+ }
+
+ val remoteScriptExecutionOutput = grpResponse.asJavaData()
+ log.debug("Received prepare env response from command server for requestId($prepareEnvInput.requestId)")
+
+ return remoteScriptExecutionOutput
+ }
+
+ override suspend fun executeCommand(remoteExecutionInput: RemoteScriptExecutionInput)
+ : RemoteScriptExecutionOutput {
+
+ val grpResponse = commandExecutorServiceGrpc.executeCommand(remoteExecutionInput.asGrpcData()).get()
+
+ checkNotNull(grpResponse.status) {
+ "failed to get GRPC response status for requestId($remoteExecutionInput.requestId)"
+ }
+
+ val remoteScriptExecutionOutput = grpResponse.asJavaData()
+ log.debug("Received response from command server for requestId($remoteExecutionInput.requestId)")
+
+ return remoteScriptExecutionOutput
+ }
+
+ override suspend fun close() {
+ channel?.shutdownNow()
+ }
+
+
+ fun PrepareRemoteEnvInput.asGrpcData(): PrepareEnvInput {
+ val correlationId = this.correlationId ?: this.requestId
+
+ return PrepareEnvInput.newBuilder()
+ .setIdentifiers(this.remoteIdentifier!!.asGrpcData())
+ .setRequestId(this.requestId)
+ .setCorrelationId(correlationId)
+ .setScriptType(ScriptType.valueOf(this.remoteScriptType.name))
+ .setTimeOut(this.timeOut.toInt())
+ .addAllPackages(this.packages)
+ .setProperties(this.properties.asGrpcData())
+ .build()
+ }
+
+ fun RemoteScriptExecutionInput.asGrpcData(): ExecutionInput {
+ val correlationId = this.correlationId ?: this.requestId
+ return ExecutionInput.newBuilder()
+ .setRequestId(this.requestId)
+ .setCorrelationId(correlationId)
+ .setIdentifiers(this.remoteIdentifier!!.asGrpcData())
+ .setScriptType(ScriptType.valueOf(this.remoteScriptType.name))
+ .setCommand(this.command)
+ .setTimeOut(this.timeOut.toInt())
+ .setProperties(this.properties.asGrpcData())
+ .setTimestamp(Timestamp.getDefaultInstance())
+ .build()
+ }
+
+ fun RemoteIdentifier.asGrpcData(): Identifiers? {
+ return Identifiers.newBuilder()
+ .setBlueprintName(this.blueprintName)
+ .setBlueprintVersion(this.blueprintVersion)
+ .build()
+ }
+
+ fun Map<String, JsonNode>.asGrpcData(): Struct {
+ val struct = Struct.newBuilder()
+ JsonFormat.parser().merge(JacksonUtils.getJson(this), struct)
+ return struct.build()
+ }
+
+ fun ExecutionOutput.asJavaData(): RemoteScriptExecutionOutput {
+ return RemoteScriptExecutionOutput(
+ requestId = this.requestId,
+ response = this.response,
+ status = StatusType.valueOf(this.status.name)
+ )
+ }
+
} \ No newline at end of file
diff --git a/ms/blueprintsprocessor/parent/pom.xml b/ms/blueprintsprocessor/parent/pom.xml
index 0ad566669..42abbc51d 100755
--- a/ms/blueprintsprocessor/parent/pom.xml
+++ b/ms/blueprintsprocessor/parent/pom.xml
@@ -16,7 +16,8 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onap.ccsdk.cds</groupId>
@@ -313,6 +314,11 @@
</dependency>
<dependency>
<groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId>
+ <artifactId>grpc-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId>
<artifactId>execution-service</artifactId>
<version>${project.version}</version>
</dependency>
diff --git a/ms/cds-sdc-listener/application/pom.xml b/ms/cds-sdc-listener/application/pom.xml
index c58bb130f..3f8e1a319 100644
--- a/ms/cds-sdc-listener/application/pom.xml
+++ b/ms/cds-sdc-listener/application/pom.xml
@@ -6,7 +6,8 @@
~ proprietary to Bell Canada and are protected by trade secret or copyright law.
~ Unauthorized copying of this file, via any medium is strictly prohibited.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.onap.ccsdk.parent</groupId>
@@ -18,11 +19,17 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>cds-sdc-listener-application</artifactId>
<version>0.4.2-SNAPSHOT</version>
- <name>CDS-SDC Listener Application </name>
+ <name>CDS-SDC Listener Application</name>
<properties>
<grpc.version>1.17.1</grpc.version>
<protobuf.version>3.6.1</protobuf.version>
+ <image.name>onap/ccsdk-cds-sdc-listener</image.name>
+ <docker.push.phase>deploy</docker.push.phase>
+ <project.version>${parent.version}</project.version>
+ <!-- Start of Docker Related Properties -->
+ <docker.fabric.version>0.26.1</docker.fabric.version>
+ <ccsdk.project.version>${project.version}</ccsdk.project.version>
</properties>
<dependencies>
@@ -106,7 +113,103 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <id>copy</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <echo>ANT TASK - copying Docker files</echo>
+ <copy todir="${basedir}/target/docker-stage" overwrite="true" flatten="true">
+ <fileset dir="${basedir}/src/main/docker">
+ <include name="Dockerfile"/>
+ <include name="start.sh"/>
+ </fileset>
+ <fileset dir="${basedir}/target">
+ <include name="*.jar"/>
+ </fileset>
+ <fileset dir="${basedir}/src/main/resources/">
+ <include name="application.yml"/>
+ </fileset>
+ </copy>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.groovy.maven</groupId>
+ <artifactId>gmaven-plugin</artifactId>
+ <version>1.0</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <source>${basedir}/../../../TagVersion.groovy</source>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
+ <profiles>
+ <profile>
+ <id>docker</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>io.fabric8</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ <version>${docker.fabric.version}</version>
+ <inherited>false</inherited>
+ <configuration>
+ <images>
+ <image>
+ <name>${image.name}</name>
+ <build>
+ <cleanup>try</cleanup>
+ <dockerFileDir>${basedir}/target/docker-stage</dockerFileDir>
+ <tags>
+ <tag>${project.docker.latestminortag.version}</tag>
+ <tag>${project.docker.latestfulltag.version}</tag>
+ <tag>${project.docker.latesttagtimestamp.version}</tag>
+ </tags>
+ </build>
+ </image>
+ </images>
+ <verbose>true</verbose>
+ </configuration>
+ <executions>
+ <execution>
+ <id>generate-images</id>
+ <phase>package</phase>
+ <goals>
+ <goal>build</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>push-images</id>
+ <phase>${docker.push.phase}</phase>
+ <goals>
+ <goal>build</goal>
+ <goal>push</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
</project>
diff --git a/ms/cds-sdc-listener/application/src/main/docker/Dockerfile b/ms/cds-sdc-listener/application/src/main/docker/Dockerfile
new file mode 100644
index 000000000..062f65767
--- /dev/null
+++ b/ms/cds-sdc-listener/application/src/main/docker/Dockerfile
@@ -0,0 +1,13 @@
+FROM openjdk:8-jdk-alpine
+
+ENV HTTP_PROXY ${HTTP_PROXY}
+ENV HTTPS_PROXY ${HTTPS_PROXY}
+
+RUN mkdir -p /opt/app/onap/ /opt/app/onap/config
+WORKDIR /opt/app/onap/
+COPY start.sh /opt/app/onap/
+COPY application.yml /opt/app/onap/config
+RUN chmod 751 /opt/app/onap/start.sh
+COPY cds-sdc-listener-application-0.4.2-SNAPSHOT.jar /opt/app/onap/cds-sdc-listener-distribution.jar
+EXPOSE 9000
+ENTRYPOINT /opt/app/onap/start.sh
diff --git a/ms/cds-sdc-listener/application/src/main/docker/docker-compose.yaml b/ms/cds-sdc-listener/application/src/main/docker/docker-compose.yaml
new file mode 100644
index 000000000..1e7384744
--- /dev/null
+++ b/ms/cds-sdc-listener/application/src/main/docker/docker-compose.yaml
@@ -0,0 +1,29 @@
+version: '3.3'
+
+services:
+ cds-sdc-listener:
+ image: onap/cdssdclistener:latest
+ container_name: cdssdclistener
+ restart: always
+ environment:
+ asdcAddress: localhost:8443
+ messageBusAddress: localhost
+ sdcusername: vid
+ password: Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
+ pollingInterval: 15
+ pollingTimeout: 15
+ relevantArtifactTypes: TOSCA_CSAR
+ consumerGroup: cds-id-local
+ environmentName: AUTO
+ consumerId: cds-id-local
+ keyStorePassword:
+ keyStorePath:
+ activateServerTLSAuth: "false"
+ isUseHttpsWithDmaap: "false"
+ archivePath: /opt/app/onap/cds-sdc-listener/
+ grpcAddress: localhost
+ grpcPort: 9111
+ authHeader: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==
+ #port needed by Liveness probe
+ healthcheckPort: "9000"
+ sprintWebListenerEnabled: "true"
diff --git a/ms/cds-sdc-listener/application/src/main/docker/start.sh b/ms/cds-sdc-listener/application/src/main/docker/start.sh
new file mode 100755
index 000000000..f24d15618
--- /dev/null
+++ b/ms/cds-sdc-listener/application/src/main/docker/start.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+extraArgs=$@
+java -jar /opt/app/onap/cds-sdc-listener-distribution.jar \
+-Dspring.config=/opt/app/onap/config/application.yml \
+-Djava.security.egd=file:/dev/./urandom \
+${extraArgs}
diff --git a/ms/cds-sdc-listener/application/src/main/resources/application.yml b/ms/cds-sdc-listener/application/src/main/resources/application.yml
index 0c2c60dca..b3f8443eb 100644
--- a/ms/cds-sdc-listener/application/src/main/resources/application.yml
+++ b/ms/cds-sdc-listener/application/src/main/resources/application.yml
@@ -1,27 +1,27 @@
listenerservice:
- config:
- asdcAddress: localhost:8443
- messageBusAddress: localhost
- user: vid
- password: Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
- pollingInterval: 15
- pollingTimeout: 60
- relevantArtifactTypes: TOSCA_CSAR
- consumerGroup: cds-id-local
- environmentName: AUTO
- consumerId: cds-id-local
- keyStorePassword:
- keyStorePath:
- activateServerTLSAuth : false
- isUseHttpsWithDmaap: false
- archivePath: /opt/app/onap/cds-sdc-listener/
- grpcAddress: localhost
- grpcPort: 9111
- authHeader: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==
+ config:
+ asdcAddress: ${asdcAddress:localhost:8443}
+ messageBusAddress: ${messageBusAddress:localhost}
+ user: ${sdcusername:vid}
+ password: ${password:Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U}
+ pollingInterval: ${pollingInterval:15}
+ pollingTimeout: ${pollingTimeout:60}
+ relevantArtifactTypes: ${relevantArtifactTypes:TOSCA_CSAR}
+ consumerGroup: ${consumerGroup:cds-id-local}
+ environmentName: ${environmentName:AUTO}
+ consumerId: ${consumerId:cds-id-local}
+ keyStorePassword: ${keyStorePassword}
+ keyStorePath: ${keyStorePath}
+ activateServerTLSAuth : ${activateServerTLSAuth:false}
+ isUseHttpsWithDmaap: ${isUseHttpsWithDmaap:false}
+ archivePath: ${archivePath:/opt/app/onap/cds-sdc-listener/}
+ grpcAddress: ${grpcAddress:localhost}
+ grpcPort: ${grpcPort:9111}
+ authHeader: ${authHeader:Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==}
#port needed by Liveness probe
server:
- port: 9000
+ port: ${healthcheckPort:9000}
#set spring.main.web-environment=false if you want to NOT to open a port for healthcheck.
-#spring:
-# main:
-# web-environment: false \ No newline at end of file
+spring:
+ main:
+ web-environment: ${sprintWebListenerEnabled:true}
diff --git a/ms/cds-sdc-listener/application/src/main/resources/logback.xml b/ms/cds-sdc-listener/application/src/main/resources/logback.xml
new file mode 100644
index 000000000..b26cbcbe4
--- /dev/null
+++ b/ms/cds-sdc-listener/application/src/main/resources/logback.xml
@@ -0,0 +1,33 @@
+<!--
+Copyright (C) 2019 Bell Canada
+
+Unless otherwise specified, all software contained herein is licensed
+under the Apache License, Version 2.0 (the License);
+you may not use this software except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<configuration>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="info">
+ <appender-ref ref="STDOUT"/>
+ </root>
+
+ <logger name="org.springframework" level="info"/>
+ <logger name="org.springframework.web" level="info"/>
+ <logger name="org.onap.ccsdk.cds" level="info"/>
+
+</configuration>
diff --git a/ms/cds-sdc-listener/distribution/pom.xml b/ms/cds-sdc-listener/distribution/pom.xml
deleted file mode 100644
index 59e3824d7..000000000
--- a/ms/cds-sdc-listener/distribution/pom.xml
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2019 Bell Canada. All rights reserved.
- ~
- ~ NOTICE: All the intellectual and technical concepts contained herein are
- ~ proprietary to Bell Canada and are protected by trade secret or copyright law.
- ~ Unauthorized copying of this file, via any medium is strictly prohibited.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <artifactId>cds-sdc-listener</artifactId>
- <groupId>org.onap.ccsdk.cds</groupId>
- <version>0.4.2-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.onap.ccsdk.cds</groupId>
- <artifactId>cds-sdc-listener-distribution</artifactId>
- <name>CDS-SDC Listener Distribution</name>
-
- <properties>
- <image.name>onap/ccsdk-cdssdclistener</image.name>
- <docker.push.phase>deploy</docker.push.phase>
- </properties>
-
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-resources-plugin</artifactId>
- <version>2.6</version>
- <executions>
- <execution>
- <id>copy-dockerfile</id>
- <goals>
- <goal>copy-resources</goal>
- </goals>
- <phase>validate</phase>
- <configuration>
- <outputDirectory>${basedir}/target/docker-stage</outputDirectory>
- <resources>
- <resource>
- <directory>src/main/docker</directory>
- <includes>
- <include>*</include>
- </includes>
- <filtering>true</filtering>
- </resource>
- </resources>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <profiles>
- <profile>
- <id>docker</id>
- <build>
- <plugins>
- <plugin>
- <!-- Maven plugin for managing docker images and containers -->
- <groupId>io.fabric8</groupId>
- <artifactId>docker-maven-plugin</artifactId>
- <version>0.26.1</version>
- <inherited>false</inherited>
- <configuration>
- <images>
- <image>
- <name>${image.name}</name>
- <build>
- <cleanup>try</cleanup>
- <dockerFileDir>${basedir}/target/docker-stage</dockerFileDir>
- <tags>
- <tag>${project.version}</tag>
- <tag>${project.version}-STAGING-${maven.build.timestamp}</tag>
- </tags>
- </build>
- </image>
- </images>
- <verbose>true</verbose>
- </configuration>
- <executions>
- <execution>
- <id>generate-images</id>
- <phase>package</phase>
- <goals>
- <goal>build</goal>
- </goals>
- </execution>
- <execution>
- <id>push-images</id>
- <phase>${docker.push.phase}</phase>
- <goals>
- <goal>build</goal>
- <goal>push</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-
-</project>
diff --git a/ms/command-executor/pom.xml b/ms/command-executor/pom.xml
new file mode 100755
index 000000000..af1b4f43b
--- /dev/null
+++ b/ms/command-executor/pom.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright © 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onap.ccsdk.cds</groupId>
+ <artifactId>ms</artifactId>
+ <version>0.4.2-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>command-executor</artifactId>
+ <packaging>pom</packaging>
+ <name>Command Executor</name>
+ <description>Micro-service providing python environment with gRPC binding for command execution</description>
+
+ <properties>
+ <assembly.id>maven</assembly.id>
+ <image.name>onap/ccsdk-commandexecutor</image.name>
+ <docker.buildArg.https_proxy>${https_proxy}</docker.buildArg.https_proxy>
+ <docker.push.phase>deploy</docker.push.phase>
+ <docker.verbose>true</docker.verbose>
+ <ccsdk.project.version>${project.version}</ccsdk.project.version>
+ <ccsdk.build.timestamp>${maven.build.timestamp}</ccsdk.build.timestamp>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <execution>
+ <id>copy-dockerfile</id>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <phase>validate</phase>
+ <configuration>
+ <outputDirectory>${basedir}/target/docker-stage</outputDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/docker</directory>
+ <includes>
+ <include>Dockerfile</include>
+ <include>start.sh</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>3.1.0</version>
+ <configuration>
+ <outputDirectory>${basedir}/target/docker-stage</outputDirectory>
+ <descriptors>
+ <descriptor>src/main/docker/distribution.xml</descriptor>
+ </descriptors>
+ <tarLongFileMode>posix</tarLongFileMode>
+ </configuration>
+ <executions>
+ <execution>
+ <id>${assembly.id}</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.groovy.maven</groupId>
+ <artifactId>gmaven-plugin</artifactId>
+ <version>1.0</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <source>${basedir}/../../TagVersion.groovy</source>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>docker</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>io.fabric8</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ <version>0.26.1</version>
+ <inherited>false</inherited>
+ <configuration>
+ <images>
+ <image>
+ <name>${image.name}</name>
+ <build>
+ <cleanup>try</cleanup>
+ <dockerFileDir>${basedir}/target/docker-stage</dockerFileDir>
+ <tags>
+ <tag>${project.docker.latestfulltag.version}</tag>
+ </tags>
+ </build>
+ </image>
+ </images>
+ <verbose>true</verbose>
+ </configuration>
+ <executions>
+ <execution>
+ <id>generate-images</id>
+ <phase>package</phase>
+ <goals>
+ <goal>build</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>push-images</id>
+ <phase>${docker.push.phase}</phase>
+ <goals>
+ <goal>build</goal>
+ <goal>push</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/ms/command-executor/src/main/docker/Dockerfile b/ms/command-executor/src/main/docker/Dockerfile
new file mode 100644
index 000000000..50f592dd6
--- /dev/null
+++ b/ms/command-executor/src/main/docker/Dockerfile
@@ -0,0 +1,21 @@
+FROM python:3.6-slim
+
+ENV GRPC_PYTHON_VERSION 1.19.0
+RUN python -m pip install --upgrade pip
+RUN pip install grpcio==${GRPC_PYTHON_VERSION} grpcio-tools==${GRPC_PYTHON_VERSION}
+RUN pip install virtualenv
+
+COPY start.sh /opt/app/onap/start.sh
+RUN chmod u+x /opt/app/onap/start.sh
+
+RUN mkdir -p /opt/app/onap/logs/ && touch /opt/app/onap/logs/application.log
+
+COPY @project.build.finalName@-@assembly.id@.tar.gz /source.tar.gz
+RUN tar -xzf /source.tar.gz -C /tmp \
+ && cp -rf /tmp/@project.build.finalName@/opt / \
+ && rm -rf /source.tar.gz \
+ && rm -rf /tmp/@project.build.finalName@
+
+VOLUME /opt/app/onap/blueprints/deploy/
+
+ENTRYPOINT /opt/app/onap/start.sh \ No newline at end of file
diff --git a/ms/command-executor/src/main/docker/distribution.xml b/ms/command-executor/src/main/docker/distribution.xml
new file mode 100755
index 000000000..7b8c27021
--- /dev/null
+++ b/ms/command-executor/src/main/docker/distribution.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright © 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.
+ -->
+
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
+ <id>${assembly.id}</id>
+ <formats>
+ <format>tar.gz</format>
+ </formats>
+ <fileSets>
+ <fileSet>
+ <directory>${project.basedir}/src/main/python</directory>
+ <outputDirectory>/opt/app/onap/python</outputDirectory>
+ </fileSet>
+ </fileSets>
+</assembly> \ No newline at end of file
diff --git a/ms/command-executor/src/main/docker/start.sh b/ms/command-executor/src/main/docker/start.sh
new file mode 100755
index 000000000..659038418
--- /dev/null
+++ b/ms/command-executor/src/main/docker/start.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+#
+# 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.
+#
+
+if [ -z "${APP_PORT}" ]
+then
+ echo "APP_PORT environment variable is not set, using default."
+ export APP_PORT=50051
+fi
+
+if [ -z "${BASIC_AUTH}" ]
+then
+ echo "BASIC_AUTH environment variable is not set, using default."
+ export BASIC_AUTH="Basic Y2NzZGthcHBzOmNjc2RrYXBwcw=="
+fi
+
+cd /opt/app/onap/python/
+python server.py ${APP_PORT} ${BASIC_AUTH} \ No newline at end of file
diff --git a/ms/command-executor/src/main/python/command_executor_handler.py b/ms/command-executor/src/main/python/command_executor_handler.py
new file mode 100644
index 000000000..4ae575b0f
--- /dev/null
+++ b/ms/command-executor/src/main/python/command_executor_handler.py
@@ -0,0 +1,105 @@
+#
+# 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.
+#
+import logging
+import os
+import subprocess
+import virtualenv
+import venv
+from builtins import Exception, open, dict
+from subprocess import CalledProcessError, PIPE
+
+import utils
+
+
+class CommandExecutorHandler:
+
+ def __init__(self, request):
+ self.logger = logging.getLogger(self.__class__.__name__)
+ self.blueprint_id = utils.get_blueprint_id(request)
+ self.venv_home = '/opt/app/onap/blueprints/deploy/' + self.blueprint_id
+
+ def prepare_env(self, request, results):
+ self.create_venv()
+ if not self.activate_venv():
+ return False
+
+ for package in request.packages:
+ if not self.install(package, results):
+ return False
+
+ # deactivate_venv(blueprint_id)
+ return True
+
+ def execute_command(self, request, results):
+ if not self.activate_venv():
+ return False
+
+ try:
+ results.append(os.popen(request.command).read())
+ except Exception as e:
+ self.logger.info("{} - Failed to execute command. Error: {}".format(self.blueprint_id, e))
+ results.append(e)
+ return False
+
+ # deactivate_venv(blueprint_id)
+ return True
+
+ def install(self, package, results):
+ self.logger.info("{} - Install package({}) in Python Virtual Environment".format(self.blueprint_id, package))
+ command = ["pip", "install", package]
+
+ env = dict(os.environ)
+ # fixme - parameterize
+ # env['https_proxy'] = "https://fastweb.int.bell.ca:8083"
+
+ try:
+ results.append(subprocess.run(command, check=True, stdout=PIPE, stderr=PIPE, env=env).stdout.decode())
+ return True
+ except CalledProcessError as e:
+ results.append(e.stderr.decode())
+ return False
+
+ def create_venv(self):
+ self.logger.info("{} - Create Python Virtual Environment".format(self.blueprint_id))
+ try:
+ bin_dir = self.venv_home + "/bin"
+ # venv doesn't populate the activate_this.py script, hence we use from virtualenv
+ venv.create(self.venv_home, with_pip=True, system_site_packages=True)
+ virtualenv.writefile(os.path.join(bin_dir, "activate_this.py"), virtualenv.ACTIVATE_THIS)
+ except Exception as err:
+ self.logger.info(
+ "{} - Failed to provision Python Virtual Environment. Error: {}".format(self.blueprint_id, err))
+
+ def activate_venv(self):
+ self.logger.info("{} - Activate Python Virtual Environment".format(self.blueprint_id))
+
+ path = "%s/bin/activate_this.py" % self.venv_home
+ try:
+ exec (open(path).read(), {'__file__': path})
+ return True
+ except Exception as err:
+ self.logger.info(
+ "{} - Failed to activate Python Virtual Environment. Error: {}".format(self.blueprint_id, err))
+ return False
+
+ def deactivate_venv(self):
+ self.logger.info("{} - Deactivate Python Virtual Environment".format(self.blueprint_id))
+ command = ["deactivate"]
+ try:
+ subprocess.run(command, check=True)
+ except Exception as err:
+ self.logger.info(
+ "{} - Failed to deactivate Python Virtual Environment. Error: {}".format(self.blueprint_id, err))
diff --git a/ms/command-executor/src/main/python/command_executor_server.py b/ms/command-executor/src/main/python/command_executor_server.py
new file mode 100644
index 000000000..3596a0ec5
--- /dev/null
+++ b/ms/command-executor/src/main/python/command_executor_server.py
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+
+#
+# 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.
+#
+import logging
+
+import proto.CommandExecutor_pb2_grpc as CommandExecutor_pb2_grpc
+
+from command_executor_handler import CommandExecutorHandler
+import utils
+
+_ONE_DAY_IN_SECONDS = 60 * 60 * 24
+
+
+class CommandExecutorServer(CommandExecutor_pb2_grpc.CommandExecutorServiceServicer):
+
+ def __init__(self):
+ self.logger = logging.getLogger(self.__class__.__name__)
+
+ def prepareEnv(self, request, context):
+ blueprint_id = utils.get_blueprint_id(request)
+ self.logger.info("{} - Received prepareEnv request".format(blueprint_id))
+ self.logger.info(request)
+
+ results = []
+ handler = CommandExecutorHandler(request)
+ if not handler.prepare_env(request, results):
+ self.logger.info("{} - Failed to prepare python environment. {}".format(blueprint_id, results))
+ return utils.build_response(request, results, False)
+ self.logger.info("{} - Package installation logs {}".format(blueprint_id, results))
+ return utils.build_response(request, results)
+
+ def executeCommand(self, request, context):
+ blueprint_id = utils.get_blueprint_id(request)
+ self.logger.info("{} - Received executeCommand request".format(blueprint_id))
+ self.logger.info(request)
+
+ results = []
+ handler = CommandExecutorHandler(request)
+ if not handler.execute_command(request, results):
+ self.logger.info("{} - Failed to executeCommand. {}".format(blueprint_id, results))
+ return utils.build_response(request, results, False)
+ self.logger.info("{} - Execute command logs: {}".format(blueprint_id, results))
+ return utils.build_response(request, results)
diff --git a/ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py b/ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py
new file mode 100644
index 000000000..637d37d87
--- /dev/null
+++ b/ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py
@@ -0,0 +1,422 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: CommandExecutor.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
+from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+ name='CommandExecutor.proto',
+ package='org.onap.ccsdk.cds.controllerblueprints.command.api',
+ syntax='proto3',
+ serialized_options=_b('P\001'),
+ serialized_pb=_b('\n\x15\x43ommandExecutor.proto\x12\x33org.onap.ccsdk.cds.controllerblueprints.command.api\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xe4\x02\n\x0e\x45xecutionInput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x15\n\rcorrelationId\x18\x02 \x01(\t\x12U\n\x0bidentifiers\x18\x03 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12S\n\nscriptType\x18\x04 \x01(\x0e\x32?.org.onap.ccsdk.cds.controllerblueprints.command.api.ScriptType\x12\x0f\n\x07\x63ommand\x18\x05 \x01(\t\x12\x0f\n\x07timeOut\x18\x06 \x01(\x05\x12+\n\nproperties\x18\x07 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xe6\x02\n\x0fPrepareEnvInput\x12U\n\x0bidentifiers\x18\x01 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12\x11\n\trequestId\x18\x02 \x01(\t\x12\x15\n\rcorrelationId\x18\x03 \x01(\t\x12S\n\nscriptType\x18\x04 \x01(\x0e\x32?.org.onap.ccsdk.cds.controllerblueprints.command.api.ScriptType\x12\x10\n\x08packages\x18\x05 \x03(\t\x12\x0f\n\x07timeOut\x18\x06 \x01(\x05\x12+\n\nproperties\x18\x07 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\">\n\x0bIdentifiers\x12\x15\n\rblueprintName\x18\x01 \x01(\t\x12\x18\n\x10\x62lueprintVersion\x18\x02 \x01(\t\"\xba\x01\n\x0f\x45xecutionOutput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x10\n\x08response\x18\x02 \x01(\t\x12S\n\x06status\x18\x03 \x01(\x0e\x32\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ResponseStatus\x12-\n\ttimestamp\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp**\n\x0eResponseStatus\x12\x0b\n\x07SUCCESS\x10\x00\x12\x0b\n\x07\x46\x41ILURE\x10\x01*9\n\nScriptType\x12\n\n\x06PYTHON\x10\x00\x12\x0b\n\x07\x41NSIBLE\x10\x01\x12\n\n\x06KOTLIN\x10\x02\x12\x06\n\x02SH\x10\x03\x32\xd1\x02\n\x16\x43ommandExecutorService\x12\x98\x01\n\nprepareEnv\x12\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput\x12\x9b\x01\n\x0e\x65xecuteCommand\x12\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutputB\x02P\x01\x62\x06proto3')
+ ,
+ dependencies=[google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,])
+
+_RESPONSESTATUS = _descriptor.EnumDescriptor(
+ name='ResponseStatus',
+ full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ResponseStatus',
+ filename=None,
+ file=DESCRIPTOR,
+ values=[
+ _descriptor.EnumValueDescriptor(
+ name='SUCCESS', index=0, number=0,
+ serialized_options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='FAILURE', index=1, number=1,
+ serialized_options=None,
+ type=None),
+ ],
+ containing_type=None,
+ serialized_options=None,
+ serialized_start=1114,
+ serialized_end=1156,
+)
+_sym_db.RegisterEnumDescriptor(_RESPONSESTATUS)
+
+ResponseStatus = enum_type_wrapper.EnumTypeWrapper(_RESPONSESTATUS)
+_SCRIPTTYPE = _descriptor.EnumDescriptor(
+ name='ScriptType',
+ full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ScriptType',
+ filename=None,
+ file=DESCRIPTOR,
+ values=[
+ _descriptor.EnumValueDescriptor(
+ name='PYTHON', index=0, number=0,
+ serialized_options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='ANSIBLE', index=1, number=1,
+ serialized_options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='KOTLIN', index=2, number=2,
+ serialized_options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='SH', index=3, number=3,
+ serialized_options=None,
+ type=None),
+ ],
+ containing_type=None,
+ serialized_options=None,
+ serialized_start=1158,
+ serialized_end=1215,
+)
+_sym_db.RegisterEnumDescriptor(_SCRIPTTYPE)
+
+ScriptType = enum_type_wrapper.EnumTypeWrapper(_SCRIPTTYPE)
+SUCCESS = 0
+FAILURE = 1
+PYTHON = 0
+ANSIBLE = 1
+KOTLIN = 2
+SH = 3
+
+
+
+_EXECUTIONINPUT = _descriptor.Descriptor(
+ name='ExecutionInput',
+ full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='requestId', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.requestId', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='correlationId', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.correlationId', index=1,
+ number=2, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='identifiers', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.identifiers', index=2,
+ number=3, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='scriptType', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.scriptType', index=3,
+ number=4, type=14, cpp_type=8, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='command', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.command', index=4,
+ number=5, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='timeOut', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.timeOut', index=5,
+ number=6, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='properties', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.properties', index=6,
+ number=7, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='timestamp', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.timestamp', index=7,
+ number=8, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ serialized_options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=142,
+ serialized_end=498,
+)
+
+
+_PREPAREENVINPUT = _descriptor.Descriptor(
+ name='PrepareEnvInput',
+ full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='identifiers', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.identifiers', index=0,
+ number=1, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='requestId', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.requestId', index=1,
+ number=2, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='correlationId', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.correlationId', index=2,
+ number=3, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='scriptType', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.scriptType', index=3,
+ number=4, type=14, cpp_type=8, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='packages', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.packages', index=4,
+ number=5, type=9, cpp_type=9, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='timeOut', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.timeOut', index=5,
+ number=6, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='properties', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.properties', index=6,
+ number=7, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='timestamp', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.timestamp', index=7,
+ number=8, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ serialized_options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=501,
+ serialized_end=859,
+)
+
+
+_IDENTIFIERS = _descriptor.Descriptor(
+ name='Identifiers',
+ full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='blueprintName', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers.blueprintName', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='blueprintVersion', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers.blueprintVersion', index=1,
+ number=2, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ serialized_options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=861,
+ serialized_end=923,
+)
+
+
+_EXECUTIONOUTPUT = _descriptor.Descriptor(
+ name='ExecutionOutput',
+ full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='requestId', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput.requestId', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='response', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput.response', index=1,
+ number=2, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='status', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput.status', index=2,
+ number=3, type=14, cpp_type=8, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='timestamp', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput.timestamp', index=3,
+ number=4, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ serialized_options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=926,
+ serialized_end=1112,
+)
+
+_EXECUTIONINPUT.fields_by_name['identifiers'].message_type = _IDENTIFIERS
+_EXECUTIONINPUT.fields_by_name['scriptType'].enum_type = _SCRIPTTYPE
+_EXECUTIONINPUT.fields_by_name['properties'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT
+_EXECUTIONINPUT.fields_by_name['timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_PREPAREENVINPUT.fields_by_name['identifiers'].message_type = _IDENTIFIERS
+_PREPAREENVINPUT.fields_by_name['scriptType'].enum_type = _SCRIPTTYPE
+_PREPAREENVINPUT.fields_by_name['properties'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT
+_PREPAREENVINPUT.fields_by_name['timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_EXECUTIONOUTPUT.fields_by_name['status'].enum_type = _RESPONSESTATUS
+_EXECUTIONOUTPUT.fields_by_name['timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+DESCRIPTOR.message_types_by_name['ExecutionInput'] = _EXECUTIONINPUT
+DESCRIPTOR.message_types_by_name['PrepareEnvInput'] = _PREPAREENVINPUT
+DESCRIPTOR.message_types_by_name['Identifiers'] = _IDENTIFIERS
+DESCRIPTOR.message_types_by_name['ExecutionOutput'] = _EXECUTIONOUTPUT
+DESCRIPTOR.enum_types_by_name['ResponseStatus'] = _RESPONSESTATUS
+DESCRIPTOR.enum_types_by_name['ScriptType'] = _SCRIPTTYPE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+ExecutionInput = _reflection.GeneratedProtocolMessageType('ExecutionInput', (_message.Message,), dict(
+ DESCRIPTOR = _EXECUTIONINPUT,
+ __module__ = 'CommandExecutor_pb2'
+ # @@protoc_insertion_point(class_scope:org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput)
+ ))
+_sym_db.RegisterMessage(ExecutionInput)
+
+PrepareEnvInput = _reflection.GeneratedProtocolMessageType('PrepareEnvInput', (_message.Message,), dict(
+ DESCRIPTOR = _PREPAREENVINPUT,
+ __module__ = 'CommandExecutor_pb2'
+ # @@protoc_insertion_point(class_scope:org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput)
+ ))
+_sym_db.RegisterMessage(PrepareEnvInput)
+
+Identifiers = _reflection.GeneratedProtocolMessageType('Identifiers', (_message.Message,), dict(
+ DESCRIPTOR = _IDENTIFIERS,
+ __module__ = 'CommandExecutor_pb2'
+ # @@protoc_insertion_point(class_scope:org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers)
+ ))
+_sym_db.RegisterMessage(Identifiers)
+
+ExecutionOutput = _reflection.GeneratedProtocolMessageType('ExecutionOutput', (_message.Message,), dict(
+ DESCRIPTOR = _EXECUTIONOUTPUT,
+ __module__ = 'CommandExecutor_pb2'
+ # @@protoc_insertion_point(class_scope:org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput)
+ ))
+_sym_db.RegisterMessage(ExecutionOutput)
+
+
+DESCRIPTOR._options = None
+
+_COMMANDEXECUTORSERVICE = _descriptor.ServiceDescriptor(
+ name='CommandExecutorService',
+ full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.CommandExecutorService',
+ file=DESCRIPTOR,
+ index=0,
+ serialized_options=None,
+ serialized_start=1218,
+ serialized_end=1555,
+ methods=[
+ _descriptor.MethodDescriptor(
+ name='prepareEnv',
+ full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.CommandExecutorService.prepareEnv',
+ index=0,
+ containing_service=None,
+ input_type=_PREPAREENVINPUT,
+ output_type=_EXECUTIONOUTPUT,
+ serialized_options=None,
+ ),
+ _descriptor.MethodDescriptor(
+ name='executeCommand',
+ full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.CommandExecutorService.executeCommand',
+ index=1,
+ containing_service=None,
+ input_type=_EXECUTIONINPUT,
+ output_type=_EXECUTIONOUTPUT,
+ serialized_options=None,
+ ),
+])
+_sym_db.RegisterServiceDescriptor(_COMMANDEXECUTORSERVICE)
+
+DESCRIPTOR.services_by_name['CommandExecutorService'] = _COMMANDEXECUTORSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/ms/command-executor/src/main/python/proto/CommandExecutor_pb2_grpc.py b/ms/command-executor/src/main/python/proto/CommandExecutor_pb2_grpc.py
new file mode 100644
index 000000000..3ea8ec4d6
--- /dev/null
+++ b/ms/command-executor/src/main/python/proto/CommandExecutor_pb2_grpc.py
@@ -0,0 +1,63 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import proto.CommandExecutor_pb2 as CommandExecutor__pb2
+
+
+class CommandExecutorServiceStub(object):
+ # missing associated documentation comment in .proto file
+ pass
+
+ def __init__(self, channel):
+ """Constructor.
+
+ Args:
+ channel: A grpc.Channel.
+ """
+ self.prepareEnv = channel.unary_unary(
+ '/org.onap.ccsdk.cds.controllerblueprints.command.api.CommandExecutorService/prepareEnv',
+ request_serializer=CommandExecutor__pb2.PrepareEnvInput.SerializeToString,
+ response_deserializer=CommandExecutor__pb2.ExecutionOutput.FromString,
+ )
+ self.executeCommand = channel.unary_unary(
+ '/org.onap.ccsdk.cds.controllerblueprints.command.api.CommandExecutorService/executeCommand',
+ request_serializer=CommandExecutor__pb2.ExecutionInput.SerializeToString,
+ response_deserializer=CommandExecutor__pb2.ExecutionOutput.FromString,
+ )
+
+
+class CommandExecutorServiceServicer(object):
+ # missing associated documentation comment in .proto file
+ pass
+
+ def prepareEnv(self, request, context):
+ # missing associated documentation comment in .proto file
+ pass
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+ def executeCommand(self, request, context):
+ # missing associated documentation comment in .proto file
+ pass
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+
+def add_CommandExecutorServiceServicer_to_server(servicer, server):
+ rpc_method_handlers = {
+ 'prepareEnv': grpc.unary_unary_rpc_method_handler(
+ servicer.prepareEnv,
+ request_deserializer=CommandExecutor__pb2.PrepareEnvInput.FromString,
+ response_serializer=CommandExecutor__pb2.ExecutionOutput.SerializeToString,
+ ),
+ 'executeCommand': grpc.unary_unary_rpc_method_handler(
+ servicer.executeCommand,
+ request_deserializer=CommandExecutor__pb2.ExecutionInput.FromString,
+ response_serializer=CommandExecutor__pb2.ExecutionOutput.SerializeToString,
+ ),
+ }
+ generic_handler = grpc.method_handlers_generic_handler(
+ 'org.onap.ccsdk.cds.controllerblueprints.command.api.CommandExecutorService', rpc_method_handlers)
+ server.add_generic_rpc_handlers((generic_handler,))
diff --git a/ms/command-executor/src/main/python/proto/__init__.py b/ms/command-executor/src/main/python/proto/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ms/command-executor/src/main/python/proto/__init__.py
diff --git a/ms/command-executor/src/main/python/request_header_validator_interceptor.py b/ms/command-executor/src/main/python/request_header_validator_interceptor.py
new file mode 100644
index 000000000..261357337
--- /dev/null
+++ b/ms/command-executor/src/main/python/request_header_validator_interceptor.py
@@ -0,0 +1,38 @@
+#
+# 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.
+#
+
+import grpc
+
+
+def _unary_unary_rpc_terminator(code, details):
+ def terminate(ignored_request, context):
+ context.abort(code, details)
+
+ return grpc.unary_unary_rpc_method_handler(terminate)
+
+
+class RequestHeaderValidatorInterceptor(grpc.ServerInterceptor):
+
+ def __init__(self, header, value, code, details):
+ self._header = header
+ self._value = value
+ self._terminator = _unary_unary_rpc_terminator(code, details)
+
+ def intercept_service(self, continuation, handler_call_details):
+ if (self._header, self._value) in handler_call_details.invocation_metadata:
+ return continuation(handler_call_details)
+ else:
+ return self._terminator
diff --git a/ms/command-executor/src/main/python/server.py b/ms/command-executor/src/main/python/server.py
new file mode 100644
index 000000000..de620474b
--- /dev/null
+++ b/ms/command-executor/src/main/python/server.py
@@ -0,0 +1,72 @@
+#!/usr/bin/python
+
+#
+# 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.
+#
+from builtins import KeyboardInterrupt
+from concurrent import futures
+import logging
+import time
+import sys
+
+import grpc
+
+import proto.CommandExecutor_pb2_grpc as CommandExecutor_pb2_grpc
+
+from request_header_validator_interceptor import RequestHeaderValidatorInterceptor
+from command_executor_server import CommandExecutorServer
+
+logger = logging.getLogger("Server")
+
+_ONE_DAY_IN_SECONDS = 60 * 60 * 24
+
+
+def serve():
+ port = sys.argv[1]
+ basic_auth = sys.argv[2] + ' ' + sys.argv[3]
+
+ header_validator = RequestHeaderValidatorInterceptor(
+ 'authorization', basic_auth, grpc.StatusCode.UNAUTHENTICATED,
+ 'Access denied!')
+
+ server = grpc.server(
+ futures.ThreadPoolExecutor(max_workers=10),
+ interceptors=(header_validator,))
+
+ CommandExecutor_pb2_grpc.add_CommandExecutorServiceServicer_to_server(
+ CommandExecutorServer(), server)
+
+ server.add_insecure_port('[::]:' + port)
+ server.start()
+
+ logger.info("Command Executor Server started on %s" % port)
+
+ try:
+ while True:
+ time.sleep(_ONE_DAY_IN_SECONDS)
+ except KeyboardInterrupt:
+ server.stop(0)
+
+
+if __name__ == '__main__':
+ logging_formater = '%(asctime)s - %(name)s - %(threadName)s - %(levelname)s - %(message)s'
+ logging.basicConfig(filename='/opt/app/onap/logs/application.log', level=logging.DEBUG,
+ format=logging_formater)
+ console = logging.StreamHandler()
+ console.setLevel(logging.INFO)
+ formatter = logging.Formatter(logging_formater)
+ console.setFormatter(formatter)
+ logging.getLogger('').addHandler(console)
+ serve()
diff --git a/ms/command-executor/src/main/python/utils.py b/ms/command-executor/src/main/python/utils.py
new file mode 100644
index 000000000..6260997f3
--- /dev/null
+++ b/ms/command-executor/src/main/python/utils.py
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+from google.protobuf.timestamp_pb2 import Timestamp
+
+import proto.CommandExecutor_pb2 as CommandExecutor_pb2
+
+
+def get_blueprint_id(request):
+ blueprint_name = request.identifiers.blueprintName
+ blueprint_version = request.identifiers.blueprintVersion
+ return blueprint_name + '/' + blueprint_version
+
+
+def build_response(request, results, is_success=True):
+ if is_success:
+ status = CommandExecutor_pb2.SUCCESS
+ else:
+ status = CommandExecutor_pb2.FAILURE
+
+ timestamp = Timestamp()
+ timestamp.GetCurrentTime()
+
+ return CommandExecutor_pb2.ExecutionOutput(requestId=request.requestId, response="".join(results), status=status,
+ timestamp=timestamp)
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt
index d45571cdf..72c2c1df3 100644
--- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt
@@ -97,6 +97,10 @@ fun <T : Any> Map<String, *>.castValue(key: String, valueType: KClass<T>): T {
}
}
+fun ArrayNode.asListOfString(): List<String> {
+ return JacksonUtils.getListFromJsonNode(this, String::class.java)
+}
+
/**
* Convert Json to map of json node, the root fields will be map keys
*/
diff --git a/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt b/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt
index e82ffc458..d06d5db9a 100644
--- a/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt
+++ b/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt
@@ -92,6 +92,14 @@ class BluePrintEnhancerServiceImplTest {
}
+ @Test
+ @Throws(Exception::class)
+ fun testRemoteScriptsEnhancementAndValidation() {
+ val basePath = "./../../../../components/model-catalog/blueprint-model/test-blueprint/remote_scripts"
+ testComponentInvokeEnhancementAndValidation(basePath, "remote_scripts-enhance")
+
+ }
+
private fun testComponentInvokeEnhancementAndValidation(basePath: String, targetDirName: String) {
runBlocking {
val targetPath = normalizedPathName("target/blueprints/enrichment", targetDirName)
@@ -105,7 +113,7 @@ class BluePrintEnhancerServiceImplTest {
val valid = bluePrintValidatorService.validateBluePrints(targetPath)
Assert.assertTrue("blueprint($basePath) validation failed ", valid)
-// deleteDir(targetPath)
+ deleteDir(targetPath)
}
}
diff --git a/ms/pom.xml b/ms/pom.xml
index 6f84a1438..d1c87c995 100644
--- a/ms/pom.xml
+++ b/ms/pom.xml
@@ -35,6 +35,7 @@
<modules>
<module>controllerblueprints</module>
<module>blueprintsprocessor</module>
+ <module>command-executor</module>
<module>cds-sdc-listener</module>
</modules>
</project>