Merge "Support for SO to ExtAPI"
[so.git] / bpmn / MSOCommonBPMN / src / main / java / org / onap / so / client / cds / AbstractCDSProcessingBBUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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=========================================================
21  */
22
23 package org.onap.so.client.cds;
24
25 import java.util.concurrent.CountDownLatch;
26 import java.util.concurrent.TimeUnit;
27 import java.util.concurrent.atomic.AtomicReference;
28 import org.camunda.bpm.engine.delegate.DelegateExecution;
29 import org.onap.ccsdk.cds.controllerblueprints.common.api.ActionIdentifiers;
30 import org.onap.ccsdk.cds.controllerblueprints.common.api.CommonHeader;
31 import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType;
32 import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput;
33 import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput;
34 import org.onap.so.client.PreconditionFailedException;
35 import org.onap.so.client.RestPropertiesLoader;
36 import org.onap.so.client.cds.beans.AbstractCDSPropertiesBean;
37 import org.onap.so.client.exception.ExceptionBuilder;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.springframework.beans.factory.annotation.Autowired;
41 import org.springframework.stereotype.Component;
42 import com.google.protobuf.InvalidProtocolBufferException;
43 import com.google.protobuf.Struct;
44 import com.google.protobuf.Struct.Builder;
45 import com.google.protobuf.util.JsonFormat;
46 import io.grpc.Status;
47
48 /**
49  * Util class to support Call to CDS client
50  *
51  */
52 @Component
53 public class AbstractCDSProcessingBBUtils implements CDSProcessingListener {
54
55     private static final Logger logger = LoggerFactory.getLogger(AbstractCDSProcessingBBUtils.class);
56
57     private static final String SUCCESS = "Success";
58     private static final String FAILED = "Failed";
59     private static final String PROCESSING = "Processing";
60
61     private final AtomicReference<String> cdsResponse = new AtomicReference<>();
62
63     @Autowired
64     private ExceptionBuilder exceptionUtil;
65
66     /**
67      * Extracting data from execution object and building the ExecutionServiceInput Object
68      * 
69      * @param execution DelegateExecution object
70      */
71     public void constructExecutionServiceInputObject(DelegateExecution execution) {
72         logger.trace("Start AbstractCDSProcessingBBUtils.preProcessRequest ");
73
74         try {
75             AbstractCDSPropertiesBean executionObject =
76                     (AbstractCDSPropertiesBean) execution.getVariable("executionObject");
77
78             String payload = executionObject.getRequestObject();
79
80             CommonHeader commonHeader = CommonHeader.newBuilder().setOriginatorId(executionObject.getOriginatorId())
81                     .setRequestId(executionObject.getRequestId()).setSubRequestId(executionObject.getSubRequestId())
82                     .build();
83             ActionIdentifiers actionIdentifiers =
84                     ActionIdentifiers.newBuilder().setBlueprintName(executionObject.getBlueprintName())
85                             .setBlueprintVersion(executionObject.getBlueprintVersion())
86                             .setActionName(executionObject.getActionName()).setMode(executionObject.getMode()).build();
87
88             Builder struct = Struct.newBuilder();
89             try {
90                 JsonFormat.parser().merge(payload, struct);
91             } catch (InvalidProtocolBufferException e) {
92                 logger.error("Failed to parse received message. blueprint({}:{}) for action({}). {}",
93                         executionObject.getBlueprintVersion(), executionObject.getBlueprintName(),
94                         executionObject.getActionName(), e);
95             }
96
97             ExecutionServiceInput executionServiceInput =
98                     ExecutionServiceInput.newBuilder().setCommonHeader(commonHeader)
99                             .setActionIdentifiers(actionIdentifiers).setPayload(struct.build()).build();
100
101             execution.setVariable("executionServiceInput", executionServiceInput);
102
103         } catch (Exception ex) {
104             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
105         }
106     }
107
108     /**
109      * get the executionServiceInput object from execution and send a request to CDS Client and wait for TIMEOUT period
110      * 
111      * @param execution DelegateExecution object
112      */
113     public void sendRequestToCDSClient(DelegateExecution execution) {
114
115         logger.trace("Start AbstractCDSProcessingBBUtils.sendRequestToCDSClient ");
116         try {
117             CDSProperties props = RestPropertiesLoader.getInstance().getNewImpl(CDSProperties.class);
118             if (props == null) {
119                 throw new PreconditionFailedException(
120                         "No RestProperty.CDSProperties implementation found on classpath, can't create client.");
121             }
122
123             ExecutionServiceInput executionServiceInput =
124                     (ExecutionServiceInput) execution.getVariable("executionServiceInput");
125
126             try (CDSProcessingClient cdsClient = new CDSProcessingClient(this)) {
127                 CountDownLatch countDownLatch = cdsClient.sendRequest(executionServiceInput);
128                 countDownLatch.await(props.getTimeout(), TimeUnit.SECONDS);
129             } catch (InterruptedException ex) {
130                 logger.error("Caught exception in sendRequestToCDSClient in AbstractCDSProcessingBBUtils : ", ex);
131                 Thread.currentThread().interrupt();
132             }
133
134             if (cdsResponse != null) {
135                 execution.setVariable("CDSStatus", cdsResponse.get());
136             }
137
138         } catch (Exception ex) {
139             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
140         }
141     }
142
143     /**
144      * Get Response from CDS Client
145      * 
146      */
147     @Override
148     public void onMessage(ExecutionServiceOutput message) {
149         logger.info("Received notification from CDS: {}", message);
150         EventType eventType = message.getStatus().getEventType();
151
152         switch (eventType) {
153
154             case EVENT_COMPONENT_FAILURE:
155                 // failed processing with failure
156                 cdsResponse.set(FAILED);
157                 break;
158             case EVENT_COMPONENT_PROCESSING:
159                 // still processing
160                 cdsResponse.set(PROCESSING);
161                 break;
162             case EVENT_COMPONENT_EXECUTED:
163                 // done with async processing
164                 cdsResponse.set(SUCCESS);
165                 break;
166             default:
167                 cdsResponse.set(FAILED);
168                 break;
169         }
170
171     }
172
173     /**
174      * On error at CDS, log the error
175      */
176     @Override
177     public void onError(Throwable t) {
178         Status status = Status.fromThrowable(t);
179         logger.error("Failed processing blueprint {}", status, t);
180     }
181
182 }