diff options
author | Brinda Santh <bs2796@att.com> | 2019-12-02 19:04:13 -0500 |
---|---|---|
committer | Brinda Santh Muthuramalingam <bs2796@att.com> | 2019-12-06 17:46:13 +0000 |
commit | 7466e4277c9fe098a61ae126d1892b3cd30d6f89 (patch) | |
tree | aee929bbb64db1d1b831cbe17551957c8916c3c2 /ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org | |
parent | aa75fbae60835585b72195c581b88cacca511a5d (diff) |
Remote Script Executor Component
Define and Implement component-remote-script-executor component and DSL.
Get the timeout from model definitions
fix the dat pattern issues
Define API data extension functions.
Issue-ID: CCSDK-1975
Signed-off-by: Brinda Santh <bs2796@att.com>
Change-Id: I41a429eb21a050e5ab512a7a73a394b975543f31
Diffstat (limited to 'ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org')
3 files changed, 267 insertions, 9 deletions
diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt index 1abac7f3d..e2a594b08 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt @@ -27,8 +27,8 @@ import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.data.Implementation import org.onap.ccsdk.cds.controllerblueprints.core.getAsString -import org.onap.ccsdk.cds.controllerblueprints.core.getOptionalAsInt import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintFunctionNode import org.onap.ccsdk.cds.controllerblueprints.core.jsonPathParse import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile @@ -49,13 +49,13 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic lateinit var executionServiceInput: ExecutionServiceInput var executionServiceOutput = ExecutionServiceOutput() lateinit var bluePrintRuntimeService: BluePrintRuntimeService<*> + lateinit var implementation: Implementation lateinit var processId: String lateinit var workflowName: String lateinit var stepName: String lateinit var interfaceName: String lateinit var operationName: String lateinit var nodeTemplateName: String - var timeout: Int = 180 var operationInputs: MutableMap<String, JsonNode> = hashMapOf() override fun getName(): String { @@ -63,7 +63,7 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic } override suspend fun prepareRequestNB(executionRequest: ExecutionServiceInput): ExecutionServiceInput { - checkNotNull(bluePrintRuntimeService) { "failed to prepare blueprint runtime" } + check(this::bluePrintRuntimeService.isInitialized) { "failed to prepare blueprint runtime" } checkNotNull(executionRequest.stepData) { "failed to get step info" } // Get the Step Name and Step Inputs @@ -91,14 +91,17 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic operationName = this.operationInputs.getAsString(BluePrintConstants.PROPERTY_CURRENT_OPERATION) check(operationName.isNotEmpty()) { "couldn't get Operation name for step($stepName)" } + /** Get the Implementation Details */ + implementation = bluePrintRuntimeService.bluePrintContext() + .nodeTemplateOperationImplementation(nodeTemplateName, interfaceName, operationName) + ?: Implementation() + check(this::implementation.isInitialized) { "failed to prepare implementation" } + val operationResolvedProperties = bluePrintRuntimeService .resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName) this.operationInputs.putAll(operationResolvedProperties) - val timeout = this.operationInputs.getOptionalAsInt(BluePrintConstants.PROPERTY_CURRENT_TIMEOUT) - timeout?.let { this.timeout = timeout } - return executionRequest } @@ -106,7 +109,7 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic log.info("Preparing Response...") executionServiceOutput.commonHeader = executionServiceInput.commonHeader executionServiceOutput.actionIdentifiers = executionServiceInput.actionIdentifiers - var status = Status() + val status = Status() try { // Resolve the Output Expression val stepOutputs = bluePrintRuntimeService @@ -130,7 +133,7 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic override suspend fun applyNB(executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput { try { prepareRequestNB(executionServiceInput) - withTimeout((timeout * 1000).toLong()) { + withTimeout((implementation.timeout * 1000).toLong()) { processNB(executionServiceInput) } } catch (runtimeException: RuntimeException) { @@ -191,7 +194,8 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic } suspend fun readLinesFromArtifact(artifactName: String): List<String> { - val artifactDefinition = bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName) + val artifactDefinition = + bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName) val file = normalizedFile(bluePrintRuntimeService.bluePrintContext().rootPath, artifactDefinition.file) return file.readNBLines() } diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentRemoteScriptExecutor.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentRemoteScriptExecutor.kt new file mode 100644 index 000000000..6003cceab --- /dev/null +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentRemoteScriptExecutor.kt @@ -0,0 +1,106 @@ +/* + * Copyright © 2018-2019 AT&T Intellectual Property. + * + * 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.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput +import org.onap.ccsdk.cds.blueprintsprocessor.core.asJsonType +import org.onap.ccsdk.cds.blueprintsprocessor.core.utils.PayloadUtils +import org.onap.ccsdk.cds.blueprintsprocessor.core.utils.createActionIdentifiersProto +import org.onap.ccsdk.cds.blueprintsprocessor.core.utils.createCommonHeaderProto +import org.onap.ccsdk.cds.blueprintsprocessor.core.utils.createExecutionServiceInputProto +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive +import org.springframework.beans.factory.config.ConfigurableBeanFactory +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component +import java.util.UUID + +/** + * This is generic Remote Script Component Executor function + * @author Brinda Santh + */ +@Component("component-remote-script-executor") +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +open class ComponentRemoteScriptExecutor( + private var streamingRemoteExecutionService: StreamingRemoteExecutionService< + org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput, + org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput> +) : AbstractComponentFunction() { + + companion object { + const val INPUT_SELECTOR = "selector" + const val INPUT_BLUEPRINT_NAME = "blueprint-name" + const val INPUT_BLUEPRINT_VERSION = "blueprint-version" + const val INPUT_BLUEPRINT_ACTION = "blueprint-action" + const val INPUT_TIMEOUT = "timeout" + const val INPUT_REQUEST_DATA = "request-data" + + const val ATTRIBUTE_RESPONSE_DATA = "response-data" + const val ATTRIBUTE_STATUS = "status" + + const val OUTPUT_STATUS = "status" + } + + override suspend fun processNB(executionRequest: ExecutionServiceInput) { + val selector = getOperationInput(INPUT_SELECTOR) + val blueprintName = getOperationInput(INPUT_BLUEPRINT_NAME).asText() + val blueprintVersion = getOperationInput(INPUT_BLUEPRINT_VERSION).asText() + val blueprintAction = getOperationInput(INPUT_BLUEPRINT_ACTION).asText() + val requestData = getOperationInput(INPUT_REQUEST_DATA) + val timeout = getOperationInput(INPUT_TIMEOUT).asLong() + + val requestPayload = PayloadUtils.prepareRequestPayloadStr(blueprintAction, requestData) + + val txId = UUID.randomUUID().toString() + val commonHeader = createCommonHeaderProto( + executionRequest.commonHeader.subRequestId, + txId, BluePrintConstants.APP_NAME + ) + val actionIdentifier = createActionIdentifiersProto(blueprintName, blueprintVersion, blueprintAction) + + val executionServiceInputProto = + createExecutionServiceInputProto(commonHeader, actionIdentifier, requestPayload) + + /** Invoke remote implementation using GRPC */ + val executionServiceOutputProto = + streamingRemoteExecutionService.sendNonInteractive(selector, txId, executionServiceInputProto, timeout) + + /** Set the response data */ + if (executionServiceOutputProto.payload != null) { + val outputData = PayloadUtils.getResponseDataFromPayload( + blueprintAction, + executionServiceOutputProto.payload.asJsonType() + ) + setAttribute(ATTRIBUTE_RESPONSE_DATA, outputData) + } + + /** set node template attribute */ + val statusMessage = executionServiceOutputProto.status.message + if (statusMessage == BluePrintConstants.STATUS_SUCCESS) { + setAttribute(ATTRIBUTE_STATUS, BluePrintConstants.STATUS_SUCCESS.asJsonPrimitive()) + } else { + val errorMessage = executionServiceOutputProto.status.errorMessage ?: "failed in remote execution" + throw BluePrintProcessorException(errorMessage) + } + } + + override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { + bluePrintRuntimeService.getBluePrintError() + .addError("Failed in ComponentCliExecutor : ${runtimeException.message}") + } +} diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentRemoteScriptExecutorDSL.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentRemoteScriptExecutorDSL.kt new file mode 100644 index 000000000..0210e88ea --- /dev/null +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentRemoteScriptExecutorDSL.kt @@ -0,0 +1,148 @@ +/* + * Copyright © 2018-2019 AT&T Intellectual Property. + * + * 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 com.fasterxml.jackson.databind.JsonNode +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType +import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeTemplate +import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeType +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.AbstractNodeTemplateOperationImplBuilder +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.PropertiesAssignmentBuilder +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.nodeType + +/** Component Extensions **/ + +fun BluePrintTypes.nodeTypeComponentRemoteScriptExecutor(): NodeType { + return nodeType( + id = "component-remote-script-executor", version = BluePrintConstants.DEFAULT_VERSION_NUMBER, + derivedFrom = BluePrintConstants.MODEL_TYPE_NODE_COMPONENT, + description = "Generic Remote Script Component Executor" + ) { + /** Attribute definitions */ + attribute( + ComponentRemoteScriptExecutor.ATTRIBUTE_RESPONSE_DATA, BluePrintConstants.DATA_TYPE_JSON, false, + "Remote executed response data." + ) + attribute( + ComponentRemoteScriptExecutor.ATTRIBUTE_STATUS, BluePrintConstants.DATA_TYPE_STRING, true, + "Remote execution status." + ) + + /** Operation definitions */ + operation("ComponentRemoteScriptExecutor", "ComponentRemoteScriptExecutor Operation") { + inputs { + property( + ComponentRemoteScriptExecutor.INPUT_SELECTOR, BluePrintConstants.DATA_TYPE_JSON, + true, "Remote GRPC selector or DSL reference or GRPC Json config." + ) + property( + ComponentRemoteScriptExecutor.INPUT_BLUEPRINT_NAME, BluePrintConstants.DATA_TYPE_STRING, + true, "Blueprint name." + ) + property( + ComponentRemoteScriptExecutor.INPUT_BLUEPRINT_VERSION, BluePrintConstants.DATA_TYPE_STRING, + true, "Blueprint version." + ) + property( + ComponentRemoteScriptExecutor.INPUT_BLUEPRINT_ACTION, BluePrintConstants.DATA_TYPE_STRING, + true, "Blueprint action name." + ) + property( + ComponentRemoteScriptExecutor.INPUT_TIMEOUT, BluePrintConstants.DATA_TYPE_INTEGER, + true, "Remote execution timeout in sec." + ) { + defaultValue(180) + } + property( + ComponentRemoteScriptExecutor.INPUT_REQUEST_DATA, BluePrintConstants.DATA_TYPE_JSON, + false, "Dynamic Json Content or DSL Json reference." + ) + } + outputs { + property( + ComponentRemoteScriptExecutor.OUTPUT_STATUS, BluePrintConstants.DATA_TYPE_STRING, + true, "Status of the Component Execution ( success or failure )" + ) + } + } + } +} + +/** Component Builder */ +fun BluePrintTypes.nodeTemplateComponentRemoteScriptExecutor( + id: String, + description: String, + block: ComponentRemoteScriptExecutorNodeTemplateBuilder.() -> Unit +): + NodeTemplate { + return ComponentRemoteScriptExecutorNodeTemplateBuilder(id, description).apply(block).build() +} + +class ComponentRemoteScriptExecutorNodeTemplateBuilder(id: String, description: String) : + AbstractNodeTemplateOperationImplBuilder<PropertiesAssignmentBuilder, + ComponentRemoteScriptExecutorNodeTemplateBuilder.InputsBuilder, + ComponentRemoteScriptExecutorNodeTemplateBuilder.OutputsBuilder>( + id, "component-remote-script-executor", + "ComponentRemoteScriptExecutor", + description + ) { + + class InputsBuilder : PropertiesAssignmentBuilder() { + + fun selector(selector: String) = selector(selector.asJsonPrimitive()) + + fun selector(selector: JsonNode) = property(ComponentRemoteScriptExecutor.INPUT_SELECTOR, selector) + + fun blueprintName(blueprintName: String) = property( + ComponentRemoteScriptExecutor.INPUT_BLUEPRINT_NAME, + blueprintName.asJsonPrimitive() + ) + + fun blueprintVersion(blueprintVersion: String) = property( + ComponentRemoteScriptExecutor.INPUT_BLUEPRINT_VERSION, + blueprintVersion.asJsonPrimitive() + ) + + fun blueprintAction(blueprintAction: String) = property( + ComponentRemoteScriptExecutor.INPUT_BLUEPRINT_ACTION, + blueprintAction.asJsonPrimitive() + ) + + fun timeout(timeout: Int) = property( + ComponentRemoteScriptExecutor.INPUT_TIMEOUT, + timeout.asJsonPrimitive() + ) + + fun requestData(requestData: String) = requestData(requestData.asJsonType()) + + fun requestData(requestData: JsonNode) { + property(ComponentRemoteScriptExecutor.INPUT_REQUEST_DATA, requestData) + } + } + + class OutputsBuilder : PropertiesAssignmentBuilder() { + + fun status(status: String) = status(status.asJsonPrimitive()) + + fun status(status: JsonNode) { + property(ComponentRemoteScriptExecutor.OUTPUT_STATUS, status) + } + } +} |