diff options
Diffstat (limited to 'ms/blueprintsprocessor/modules')
10 files changed, 341 insertions, 7 deletions
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..46969b1c5 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,142 @@ 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)!! + + lateinit var channel: ManagedChannel + 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() { + // TODO('Verify the correct way to close the client conncetion") + if (channel != null) { + 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 if (this != null) { + Identifiers.newBuilder() + .setBlueprintName(this.blueprintName) + .setBlueprintVersion(this.blueprintVersion) + .build() + } else { + null + } + } + + 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 |