"component-remote-python-executor": {
"description": "This is Remote Python Execution Component.",
"version": "1.0.0",
+ "attributes": {
+ "execution-logs": {
+ "required": true,
+ "type": "string"
+ }
+ },
"capabilities": {
"component-node": {
"type": "tosca.capabilities.Node"
"description": "Remote Container or Server selector name.",
"required": false,
"type": "string",
- "default": "default"
+ "default": "remote-python"
},
"dynamic-properties": {
"description": "Dynamic Json Content or DSL Json reference.",
"required": false,
"type": "json"
}
- },
- "outputs": {
- "response-data": {
- "description": "Execution Response Data in JSON format.",
- "required": false,
- "type": "json"
- },
- "status": {
- "description": "Status of the Component Execution ( success or failure )",
- "required": true,
- "type": "string"
- }
}
}
}
]
}
},
- "inputs": {}
+ "inputs": {},
+ "outputs": {
+ "logs": {
+ "type": "json",
+ "value": {
+ "get_attribute": [
+ "execute-remote-python",
+ "execution-logs"
+ ]
+ }
+ }
+ }
}
},
"node_templates": {
"implementation": {
"primary": "component-script",
"dependencies": [
- "ncclient"
+ "pyaml"
]
- },
- "inputs": {
- "endpoint-selector": "default"
- },
- "outputs": {
- "response-data": "",
- "status": "success"
}
}
}
{
"description": "This is Remote Python Execution Component.",
"version": "1.0.0",
+ "attributes": {
+ "execution-logs": {
+ "required": true,
+ "type": "string"
+ }
+ },
"capabilities": {
"component-node": {
"type": "tosca.capabilities.Node"
"description": "Remote Container or Server selector name.",
"required": false,
"type": "string",
- "default": "default"
+ "default": "remote-python"
},
"dynamic-properties": {
"description": "Dynamic Json Content or DSL Json reference.",
"required": false,
"type": "json"
}
- },
- "outputs": {
- "response-data": {
- "description": "Execution Response Data in JSON format.",
- "required": false,
- "type": "json"
- },
- "status": {
- "description": "Status of the Component Execution ( success or failure )",
- "required": true,
- "type": "string"
- }
}
}
}
# 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
# 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
blueprintprocessor.resourceResolution.enabled=true
blueprintprocessor.netconfExecutor.enabled=true
blueprintprocessor.restConfExecutor.enabled=true
-blueprintprocessor.remoteScriptCommand.enabled=false
\ No newline at end of file
+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
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")
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 dynamicProperties = getOperationInput(INPUT_DYNAMIC_PROPERTIES)
// TODO("Python execution command and Resolve some expressions with dynamic properties")
- val scriptCommand = "${pythonScript.absolutePath}"
+ val scriptCommand = pythonScript.absolutePath
val dependencies = operationAssignment.implementation?.dependencies
// Open GRPC Connection
remoteScriptExecutionService.init(endPointSelector.asText())
+ var executionLogs = ""
+
// If dependencies are defined, then install in remote server
if (dependencies != null && dependencies.isNotEmpty()) {
val prepareEnvInput = PrepareRemoteEnvInput(requestId = processId,
- remoteScriptType = RemoteScriptType.PYTHON,
- packages = dependencies
+ remoteIdentifier = RemoteIdentifier(blueprintName = blueprintName,
+ blueprintVersion = blueprintVersion),
+ remoteScriptType = RemoteScriptType.PYTHON,
+ packages = dependencies
)
val prepareEnvOutput = remoteScriptExecutionService.prepareEnv(prepareEnvInput)
- checkNotNull(prepareEnvOutput.status) {
+ executionLogs = prepareEnvOutput.response
+ setOutput(executionLogs)
+ check(prepareEnvOutput.status == StatusType.SUCCESS) {
"failed to get prepare remote env response status for requestId(${prepareEnvInput.requestId})"
}
}
val remoteExecutionInput = RemoteScriptExecutionInput(
- requestId = processId,
- remoteIdentifier = RemoteIdentifier(blueprintName = blueprintName, blueprintVersion = blueprintVersion),
- remoteScriptType = RemoteScriptType.PYTHON,
- command = scriptCommand)
+ requestId = processId,
+ remoteIdentifier = RemoteIdentifier(blueprintName = blueprintName, blueprintVersion = blueprintVersion),
+ remoteScriptType = RemoteScriptType.PYTHON,
+ command = scriptCommand)
val remoteExecutionOutput = remoteScriptExecutionService.executeCommand(remoteExecutionInput)
- checkNotNull(remoteExecutionOutput.status) {
+ 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
private val log = LoggerFactory.getLogger(GrpcRemoteScriptExecutionService::class.java)!!
- lateinit var channel: ManagedChannel
- lateinit var commandExecutorServiceGrpc: CommandExecutorServiceGrpc.CommandExecutorServiceFutureStub
+ 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
}
override suspend fun close() {
- // TODO('Verify the correct way to close the client conncetion")
- if (channel != null) {
- channel.shutdownNow()
- }
+ channel?.shutdownNow()
}
val correlationId = this.correlationId ?: this.requestId
return PrepareEnvInput.newBuilder()
- .setIdentifiers(this.remoteIdentifier.asGrpcData())
+ .setIdentifiers(this.remoteIdentifier!!.asGrpcData())
.setRequestId(this.requestId)
.setCorrelationId(correlationId)
.setScriptType(ScriptType.valueOf(this.remoteScriptType.name))
return ExecutionInput.newBuilder()
.setRequestId(this.requestId)
.setCorrelationId(correlationId)
- .setIdentifiers(this.remoteIdentifier.asGrpcData())
+ .setIdentifiers(this.remoteIdentifier!!.asGrpcData())
.setScriptType(ScriptType.valueOf(this.remoteScriptType.name))
.setCommand(this.command)
.setTimeOut(this.timeOut.toInt())
.build()
}
- fun RemoteIdentifier?.asGrpcData(): Identifiers? {
- return if (this != null) {
- Identifiers.newBuilder()
- .setBlueprintName(this.blueprintName)
- .setBlueprintVersion(this.blueprintVersion)
- .build()
- } else {
- null
- }
+ fun RemoteIdentifier.asGrpcData(): Identifiers? {
+ return Identifiers.newBuilder()
+ .setBlueprintName(this.blueprintName)
+ .setBlueprintVersion(this.blueprintVersion)
+ .build()
}
fun Map<String, JsonNode>.asGrpcData(): Struct {
RUN pip install grpcio==${GRPC_PYTHON_VERSION} grpcio-tools==${GRPC_PYTHON_VERSION}
RUN pip install virtualenv
-RUN mkdir -p /opt/onap/blueprints && mkdir -p /opt/onap/app/python && chmod -R 777 /opt/onap
-
-COPY start.sh /opt/onap/app/start.sh
-RUN chmod u+x /opt/onap/app/start.sh
+COPY start.sh /opt/app/onap/start.sh
+RUN chmod u+x /opt/app/onap/start.sh
COPY @project.build.finalName@-@assembly.id@.tar.gz /source.tar.gz
RUN tar -xzf /source.tar.gz -C /tmp \
&& rm -rf /source.tar.gz \
&& rm -rf /tmp/@project.build.finalName@
-ENTRYPOINT /opt/onap/app/start.sh
\ No newline at end of file
+
+VOLUME /opt/app/onap/blueprints/deploy/
+
+ENTRYPOINT /opt/app/onap/start.sh
\ No newline at end of file
<fileSets>
<fileSet>
<directory>${project.basedir}/src/main/python</directory>
- <outputDirectory>/opt/onap/app/python</outputDirectory>
+ <outputDirectory>/opt/app/onap/python</outputDirectory>
</fileSet>
</fileSets>
</assembly>
\ No newline at end of file
export BASIC_AUTH="Basic Y2NzZGthcHBzOmNjc2RrYXBwcw=="
fi
-cd /opt/onap/app/python/
+cd /opt/app/onap/python/
python command_executor_server.py ${APP_PORT} ${BASIC_AUTH}
\ No newline at end of file