2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 TechMahindra
6 * ================================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=========================================================
23 package org.onap.so.client.cds;
25 import com.google.protobuf.InvalidProtocolBufferException;
26 import com.google.protobuf.Struct;
27 import com.google.protobuf.Struct.Builder;
28 import com.google.protobuf.util.JsonFormat;
29 import io.grpc.Status;
30 import org.camunda.bpm.engine.delegate.DelegateExecution;
31 import org.onap.ccsdk.cds.controllerblueprints.common.api.ActionIdentifiers;
32 import org.onap.ccsdk.cds.controllerblueprints.common.api.CommonHeader;
33 import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType;
34 import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput;
35 import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput;
36 import org.onap.so.bpmn.common.BuildingBlockExecution;
37 import org.onap.so.client.PreconditionFailedException;
38 import org.onap.so.client.RestPropertiesLoader;
39 import org.onap.so.client.cds.beans.AbstractCDSPropertiesBean;
40 import org.onap.so.client.exception.BadResponseException;
41 import org.onap.so.client.exception.ExceptionBuilder;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.springframework.beans.factory.annotation.Autowired;
45 import org.springframework.stereotype.Component;
46 import java.util.concurrent.CountDownLatch;
47 import java.util.concurrent.TimeUnit;
50 * Util class to support Call to CDS client
53 public class AbstractCDSProcessingBBUtils {
55 private static final Logger logger = LoggerFactory.getLogger(AbstractCDSProcessingBBUtils.class);
57 private static final String SUCCESS = "Success";
58 private static final String FAILED = "Failed";
59 private static final String PROCESSING = "Processing";
60 private static final String RESPONSE_PAYLOAD = "CDSResponsePayload";
61 private static final String CDS_STATUS = "ControllerStatus";
62 private static final String EXEC_INPUT = "executionServiceInput";
63 private static final String EXECUTION_OBJECT = "executionObject";
64 private static final String EXCEPTION = "Exception";
67 protected ExceptionBuilder exceptionUtil;
70 * Extracting data from execution object and building the ExecutionServiceInput Object
72 * @param execution DelegateExecution object
74 public void constructExecutionServiceInputObject(DelegateExecution execution) {
75 logger.trace("Start AbstractCDSProcessingBBUtils.preProcessRequest for DelegateExecution object.");
78 AbstractCDSPropertiesBean executionObject =
79 (AbstractCDSPropertiesBean) execution.getVariable(EXECUTION_OBJECT);
81 ExecutionServiceInput executionServiceInput = prepareExecutionServiceInput(executionObject);
83 execution.setVariable(EXEC_INPUT, executionServiceInput);
85 } catch (Exception ex) {
86 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
91 * Extracting data from execution object and building the ExecutionServiceInput Object
93 * @param execution BuildingBlockExecution object
95 public void constructExecutionServiceInputObject(BuildingBlockExecution execution) {
96 logger.trace("Start AbstractCDSProcessingBBUtils.preProcessRequest for BuildingBlockExecution object.");
99 AbstractCDSPropertiesBean executionObject = execution.getVariable(EXECUTION_OBJECT);
101 ExecutionServiceInput executionServiceInput = prepareExecutionServiceInput(executionObject);
103 execution.setVariable(EXEC_INPUT, executionServiceInput);
105 } catch (Exception ex) {
106 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
111 * get the executionServiceInput object from execution and send a request to CDS Client and wait for TIMEOUT period
113 * @param execution DelegateExecution object
115 public void sendRequestToCDSClient(DelegateExecution execution) {
117 logger.trace("Start AbstractCDSProcessingBBUtils.sendRequestToCDSClient for DelegateExecution object.");
119 ExecutionServiceInput executionServiceInput = (ExecutionServiceInput) execution.getVariable(EXEC_INPUT);
120 CDSResponse cdsResponse = getCdsResponse(executionServiceInput);
121 execution.setVariable(CDS_STATUS, cdsResponse.status);
123 if (cdsResponse.payload != null) {
124 String payload = JsonFormat.printer().print(cdsResponse.payload);
125 execution.setVariable(RESPONSE_PAYLOAD, payload);
128 } catch (Exception ex) {
129 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
134 * get the executionServiceInput object from execution and send a request to CDS Client and wait for TIMEOUT period
136 * @param execution BuildingBlockExecution object
138 public void sendRequestToCDSClient(BuildingBlockExecution execution) {
140 logger.trace("Start AbstractCDSProcessingBBUtils.sendRequestToCDSClient for BuildingBlockExecution object.");
142 ExecutionServiceInput executionServiceInput = execution.getVariable(EXEC_INPUT);
143 CDSResponse cdsResponse = getCdsResponse(executionServiceInput);
144 execution.setVariable(CDS_STATUS, cdsResponse.status);
146 if (cdsResponse.payload != null) {
147 String payload = JsonFormat.printer().print(cdsResponse.payload);
148 execution.setVariable(RESPONSE_PAYLOAD, payload);
151 } catch (Exception ex) {
152 exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
156 private CDSResponse getCdsResponse(ExecutionServiceInput executionServiceInput) throws BadResponseException {
157 CDSProperties props = RestPropertiesLoader.getInstance().getNewImpl(CDSProperties.class);
159 throw new PreconditionFailedException(
160 "No RestProperty.CDSProperties implementation found on classpath, can't create client.");
163 CDSResponse cdsResponse = new CDSResponse();
165 try (CDSProcessingClient cdsClient = new CDSProcessingClient(new ResponseHandler(cdsResponse))) {
166 CountDownLatch countDownLatch = cdsClient.sendRequest(executionServiceInput);
167 countDownLatch.await(props.getTimeout(), TimeUnit.SECONDS);
168 } catch (InterruptedException ex) {
169 logger.error("Caught exception in sendRequestToCDSClient in AbstractCDSProcessingBBUtils : ", ex);
170 Thread.currentThread().interrupt();
173 String cdsResponseStatus = cdsResponse.status;
176 * throw CDS failed exception.
178 if (!cdsResponseStatus.equals(SUCCESS)) {
179 throw new BadResponseException("CDS call failed with status: " + cdsResponse.status + " and errorMessage: "
180 + cdsResponse.errorMessage);
185 private ExecutionServiceInput prepareExecutionServiceInput(AbstractCDSPropertiesBean executionObject) {
186 String payload = executionObject.getRequestObject();
188 CommonHeader commonHeader = CommonHeader.newBuilder().setOriginatorId(executionObject.getOriginatorId())
189 .setRequestId(executionObject.getRequestId()).setSubRequestId(executionObject.getSubRequestId())
191 ActionIdentifiers actionIdentifiers =
192 ActionIdentifiers.newBuilder().setBlueprintName(executionObject.getBlueprintName())
193 .setBlueprintVersion(executionObject.getBlueprintVersion())
194 .setActionName(executionObject.getActionName()).setMode(executionObject.getMode()).build();
196 Builder struct = Struct.newBuilder();
198 JsonFormat.parser().merge(payload, struct);
199 } catch (InvalidProtocolBufferException e) {
200 logger.error("Failed to parse received message. blueprint({}:{}) for action({}). {}",
201 executionObject.getBlueprintVersion(), executionObject.getBlueprintName(),
202 executionObject.getActionName(), e);
205 return ExecutionServiceInput.newBuilder().setCommonHeader(commonHeader).setActionIdentifiers(actionIdentifiers)
206 .setPayload(struct.build()).build();
209 private class ResponseHandler implements CDSProcessingListener {
211 private CDSResponse cdsResponse;
213 ResponseHandler(CDSResponse cdsResponse) {
214 this.cdsResponse = cdsResponse;
218 * Get Response from CDS Client
221 public void onMessage(ExecutionServiceOutput message) {
222 logger.info("Received notification from CDS: {}", message);
223 EventType eventType = message.getStatus().getEventType();
226 case EVENT_COMPONENT_PROCESSING:
227 cdsResponse.status = PROCESSING;
229 case EVENT_COMPONENT_EXECUTED:
230 cdsResponse.status = SUCCESS;
233 cdsResponse.status = FAILED;
234 cdsResponse.errorMessage = message.getStatus().getErrorMessage();
237 cdsResponse.payload = message.getPayload();
241 * On error at CDS, log the error
244 public void onError(Throwable t) {
245 Status status = Status.fromThrowable(t);
246 logger.error("Failed processing blueprint {}", status, t);
247 cdsResponse.status = EXCEPTION;
251 private class CDSResponse {
258 public String toString() {
259 return "CDSResponse{" + "status='" + status + '\'' + ", errorMessage='" + errorMessage + '\'' + ", payload="