Containerization feature of SO
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / java / org / onap / so / bpmn / infrastructure / workflow / serviceTask / AbstractSdncOperationTask.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.bpmn.infrastructure.workflow.serviceTask;
22
23 import java.io.IOException;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.Map;
28
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.http.client.methods.CloseableHttpResponse;
31 import org.apache.http.client.methods.HttpPost;
32 import org.apache.http.entity.ContentType;
33 import org.apache.http.entity.StringEntity;
34 import org.apache.http.impl.client.CloseableHttpClient;
35 import org.apache.http.impl.client.HttpClients;
36 import org.apache.http.util.EntityUtils;
37 import org.camunda.bpm.engine.delegate.DelegateExecution;
38 import org.json.JSONObject;
39 import org.onap.msb.sdk.discovery.common.RouteException;
40 import org.onap.msb.sdk.httpclient.RestServiceCreater;
41 import org.onap.msb.sdk.httpclient.msb.MSBServiceClient;
42 import org.onap.so.bpmn.core.BaseTask;
43 import org.onap.so.bpmn.core.UrnPropertiesReader;
44 import org.onap.so.bpmn.infrastructure.workflow.serviceTask.client.GenericResourceApi;
45 import org.onap.so.db.request.beans.ResourceOperationStatus;
46 import org.onap.so.logger.MessageEnum;
47 import org.onap.so.logger.MsoLogger;
48 import org.onap.so.requestsdb.RequestsDbConstant;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51 import org.springframework.beans.factory.annotation.Autowired;
52 import org.springframework.core.env.Environment;
53
54 import com.fasterxml.jackson.annotation.JsonInclude;
55 import com.fasterxml.jackson.core.JsonProcessingException;
56 import com.fasterxml.jackson.databind.ObjectMapper;
57
58 public abstract class AbstractSdncOperationTask extends BaseTask {
59
60     private static final Logger logger = LoggerFactory.getLogger(AbstractSdncOperationTask.class);
61     protected static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA, AbstractSdncOperationTask.class);
62     
63     @Autowired
64     private Environment env;
65     private static final String DEFAULT_MSB_IP = "127.0.0.1";
66     private static final int DEFAULT_MSB_PORT = 80;
67     private static final String SDCADAPTOR_INPUTS = "resourceParameters";
68     private static final String TOPOLOGY_PROPERTIES = "topology.properties";
69     public static final String ONAP_IP = "ONAP_IP";
70
71     private static final String POST_BODY_TEMPLATE = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"http://org.onap.so/requestsdb\"><soapenv:Header/><soapenv:Body>\n"+
72             "     <ns:updateResourceOperationStatus>\n"+
73             "                <errorCode>$errorCode</errorCode>\n"+
74             "                <jobId>$jobId</jobId>\n"+
75             "                <operType>$operType</operType>\n"+
76             "                <operationId>$operationId</operationId>\n"+
77             "                <progress>$progress</progress>\n"+
78             "                <resourceTemplateUUID>$resourceTemplateUUID</resourceTemplateUUID>\n"+
79             "                <serviceId>$serviceId</serviceId>\n"+
80             "                <status>$status</status>\n"+
81             "                <statusDescription>$statusDescription</statusDescription>\n"+
82             "     </ns:updateResourceOperationStatus></soapenv:Body></soapenv:Envelope>";
83
84     private static final String GET_BODY_TEMPLATE = " <soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"http://org.onap.so/requestsdb\"><soapenv:Header/><soapenv:Body>\n" +
85             "     <ns:getResourceOperationStatus>\n" +
86             "                <operationId>$operationId</operationId>\n" +
87             "                <resourceTemplateUUID>$resourceTemplateUUID</resourceTemplateUUID>\n" +
88             "                <serviceId>$serviceId</serviceId>\n" +
89             "     </ns:getResourceOperationStatus></soapenv:Body></soapenv:Envelope>";
90
91
92     private void updateResOperStatus(ResourceOperationStatus resourceOperationStatus) throws RouteException {
93         logger.info("AbstractSdncOperationTask.updateResOperStatus begin!");
94                 String requestsdbEndPoint = env.getProperty("mso.adapters.openecomp.db.endpoint");
95         HttpPost httpPost = new HttpPost(requestsdbEndPoint);
96         httpPost.addHeader("Authorization", "Basic QlBFTENsaWVudDpwYXNzd29yZDEk");
97         httpPost.addHeader("Content-type", "application/soap+xml");
98         String postBody = getPostStringBody(resourceOperationStatus);
99         httpPost.setEntity(new StringEntity(postBody, ContentType.APPLICATION_XML));
100         httpPost(requestsdbEndPoint, httpPost);
101         logger.info("AbstractSdncOperationTask.updateResOperStatus end!");
102     }
103
104     protected String getPostbody(Object inputEntity) {
105         ObjectMapper objectMapper = new ObjectMapper();
106         String postBody = null;
107         try {
108             objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
109             postBody = objectMapper.writeValueAsString(inputEntity);
110         } catch (JsonProcessingException e) {
111             logger.error(Arrays.toString(e.getStackTrace()));
112         }
113         return postBody;
114     }
115
116     protected String httpPost(String url, HttpPost httpPost) throws RouteException {
117         logger.info("AbstractSdncOperationTask.httpPost begin!");
118         String result = null;
119
120         String errorMsg;
121         try(CloseableHttpClient httpClient = HttpClients.createDefault()) {
122             CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpPost);
123             result = EntityUtils.toString(closeableHttpResponse.getEntity());
124             logger.info("result = {}", result);
125             if(closeableHttpResponse.getStatusLine().getStatusCode() != 200) {
126                 logger.info("exception: fail for status code = {}", closeableHttpResponse.getStatusLine().getStatusCode());
127                 throw new RouteException(result, "SERVICE_GET_ERR");
128             }
129
130             closeableHttpResponse.close();
131         } catch (IOException e) {
132             errorMsg = url + ":httpPostWithJSON connect faild";
133             logger.info("exception: POST_CONNECT_FAILD : {}", errorMsg);
134             throwsRouteException(errorMsg, e, "POST_CONNECT_FAILD");
135         }
136
137         logger.info("AbstractSdncOperationTask.httpPost end!");
138         return result;
139     }
140
141     private static void throwsRouteException(String errorMsg, Exception e, String errorCode) throws RouteException {
142         String msg = errorMsg + ".errorMsg:" + e.getMessage();
143         logger.info("exception: {}", msg);
144         throw new RouteException(errorMsg, errorCode);
145     }
146
147     private String getPostStringBody(ResourceOperationStatus resourceOperationStatus) {
148         logger.info("AbstractSdncOperationTask.getPostStringBody begin!");
149         String postBody = POST_BODY_TEMPLATE;
150         postBody = postBody.replace("$errorCode", resourceOperationStatus.getErrorCode());
151         postBody = postBody.replace("$jobId", resourceOperationStatus.getJobId());
152         postBody = postBody.replace("$operType", resourceOperationStatus.getOperType());
153         postBody = postBody.replace("$operationId", resourceOperationStatus.getOperationId());
154         postBody = postBody.replace("$progress", resourceOperationStatus.getProgress());
155         postBody = postBody.replace("$resourceTemplateUUID", resourceOperationStatus.getResourceTemplateUUID());
156         postBody = postBody.replace("$serviceId", resourceOperationStatus.getServiceId());
157         postBody = postBody.replace("$status", resourceOperationStatus.getStatus());
158         postBody = postBody.replace("$statusDescription", resourceOperationStatus.getStatusDescription());
159         logger.info("AbstractSdncOperationTask.getPostStringBody end!");
160         return postBody;
161     }
162
163     private String getGetStringBody(String serviceId, String operationId, String resourceTemplateUUID) {
164         logger.info("AbstractSdncOperationTask.getGetStringBody begin!");
165         String getBody = GET_BODY_TEMPLATE;
166         getBody = getBody.replace("$operationId", operationId);
167         getBody = getBody.replace("$resourceTemplateUUID", resourceTemplateUUID);
168         getBody = getBody.replace("$serviceId", serviceId);
169         logger.info("AbstractSdncOperationTask.getGetStringBody end!");
170         return getBody;
171     }
172
173     private ResourceOperationStatus getResourceOperationStatus(String serviceId, String operationId, String resourceTemplateUUID) throws RouteException {
174         logger.info("AbstractSdncOperationTask.getResourceOperationStatus begin!");
175                 String requestsdbEndPoint = env.getProperty("mso.adapters.openecomp.db.endpoint");
176         HttpPost httpPost = new HttpPost(requestsdbEndPoint);
177         httpPost.addHeader("Authorization", "Basic QlBFTENsaWVudDpwYXNzd29yZDEk");
178         httpPost.addHeader("Content-type", "application/soap+xml");
179         String getBody = getGetStringBody(serviceId, operationId, resourceTemplateUUID);
180         httpPost.setEntity(new StringEntity(getBody, ContentType.APPLICATION_XML));
181         String result = httpPost(requestsdbEndPoint, httpPost);
182         ResourceOperationStatus resourceOperationStatus = getResourceOperationStatusFromXmlString(result);
183         logger.info("AbstractSdncOperationTask.getResourceOperationStatus end!");
184         return resourceOperationStatus;
185     }
186
187     private ResourceOperationStatus getResourceOperationStatusFromXmlString(String result) {
188         logger.info("AbstractSdncOperationTask.getResourceOperationStatusFromXmlString begin!");
189         ResourceOperationStatus resourceOperationStatus = new ResourceOperationStatus();
190         resourceOperationStatus.setErrorCode(getValueByName("errorCode", result));
191         resourceOperationStatus.setJobId(getValueByName("jobId", result));
192         resourceOperationStatus.setOperType(getValueByName("operType", result));
193         resourceOperationStatus.setOperationId(getValueByName("operationId", result));
194         resourceOperationStatus.setProgress(getValueByName("progress", result));
195         resourceOperationStatus.setResourceTemplateUUID(getValueByName("resourceTemplateUUID", result));
196         resourceOperationStatus.setServiceId(getValueByName("serviceId", result));
197         resourceOperationStatus.setStatus(getValueByName("status", result));
198         resourceOperationStatus.setStatusDescription(getValueByName("statusDescription", result));
199         logger.info("AbstractSdncOperationTask.getResourceOperationStatusFromXmlString end!");
200         return resourceOperationStatus;
201     }
202
203     private String getValueByName(String name, String xml) {
204         if (!StringUtils.isBlank(xml) && xml.contains(name)) {
205             String start = "<" + name + ">";
206             String end = "</" + name + ">";
207             return xml.substring(xml.indexOf(start), xml.indexOf(end)).replace(start, "");
208         }
209         return "";
210     }
211
212     @Override
213     public void execute(DelegateExecution execution) {
214         logger.info("AbstractSdncOperationTask.execute begin!");
215         GenericResourceApi genericResourceApiClient = getGenericResourceApiClient();
216         try {
217             Map<String, String> inputs = getInputs(execution);
218
219             sendRestrequestAndHandleResponse(execution, inputs, genericResourceApiClient);
220             execution.setVariable("SDNCA_SuccessIndicator", true);
221         } catch (Exception e) {
222             logger.info("exception: AbstractSdncOperationTask.fail!");
223             logger.error("exception: AbstractSdncOperationTask.fail!:", e);
224             logger.error(Arrays.toString(e.getStackTrace()));
225             execution.setVariable("SDNCA_SuccessIndicator", false);
226             updateProgress(execution, RequestsDbConstant.Status.ERROR, null, "100", "sendRestrequestAndHandleResponse finished!");
227
228         }
229         logger.info("AbstractSdncOperationTask.execute end!");
230     }
231
232     protected Map<String, String> getInputs(DelegateExecution execution) {
233         logger.info("AbstractSdncOperationTask.getInputs begin!");
234         Map<String, String> inputs = new HashMap<>();
235         String json = (String) execution.getVariable(SDCADAPTOR_INPUTS);
236         if (!StringUtils.isBlank(json)) {
237             JSONObject jsonObject = new JSONObject(json);
238             JSONObject paras = jsonObject.getJSONObject("additionalParamForNs");
239             Iterator<String> iterator = paras.keys();
240             while (iterator.hasNext()) {
241                 String key = iterator.next();
242                 inputs.put(key, paras.getString(key));
243             }
244         }
245         logger.info("AbstractSdncOperationTask.getInputs end!");
246         return inputs;
247     }
248
249     public abstract void sendRestrequestAndHandleResponse(DelegateExecution execution,
250                                                           Map<String, String> inputs,
251                                                           GenericResourceApi genericResourceApiClient) throws Exception;
252
253     public void updateProgress(DelegateExecution execution,
254                                String status,
255                                String errorCode,
256                                String progress,
257                                String statusDescription) {
258         logger.info("AbstractSdncOperationTask.updateProgress begin!");
259         String serviceId = (String) execution.getVariable("serviceId");
260         serviceId = StringUtils.isBlank(serviceId) ? (String) execution.getVariable("serviceInstanceId") : serviceId;
261         String operationId = (String) execution.getVariable("operationId");
262         String resourceTemplateUUID = (String) execution.getVariable("resourceUUID");
263         String resourceTemplateId = (String) execution.getVariable("resourceTemplateId");
264         resourceTemplateId = StringUtils.isBlank(resourceTemplateId) ? "" : resourceTemplateUUID;
265         resourceTemplateUUID = StringUtils.isBlank(resourceTemplateUUID) ? resourceTemplateId : resourceTemplateUUID;
266         try {
267             ResourceOperationStatus resourceOperationStatus = getResourceOperationStatus(serviceId, operationId, resourceTemplateUUID);
268             if (!StringUtils.isBlank(status)) {
269                 resourceOperationStatus.setStatus(status);
270             }
271             if (!StringUtils.isBlank(errorCode)) {
272                 resourceOperationStatus.setErrorCode(errorCode);
273             }
274             if (!StringUtils.isBlank(progress)) {
275                 resourceOperationStatus.setProgress(progress);
276             }
277             if (!StringUtils.isBlank(statusDescription)) {
278                 resourceOperationStatus.setStatusDescription(statusDescription);
279             }
280             updateResOperStatus(resourceOperationStatus);
281             logger.info("AbstractSdncOperationTask.updateProgress end!");
282         } catch (Exception exception) {
283             logger.info("exception: AbstractSdncOperationTask.updateProgress fail!");
284             logger.error("exception: AbstractSdncOperationTask.updateProgress fail:", exception);
285             msoLogger.error(MessageEnum.GENERAL_EXCEPTION, " updateProgress catch exception: ", "", this.getTaskName(), MsoLogger.ErrorCode.UnknownError, exception.getClass().toString());
286         }
287     }
288
289
290     protected boolean isSend2SdncDirectly() {
291         logger.info("AbstractSdncOperationTask.isSend2SdncDirectly begin!");
292             String sdncIp = UrnPropertiesReader.getVariable("sdnc-ip");
293             String sdncPort = UrnPropertiesReader.getVariable("sdnc-port");
294             if (!StringUtils.isBlank(sdncIp) && isIp(sdncIp) && !StringUtils.isBlank(sdncPort)) {
295                 logger.info("AbstractSdncOperationTask.isSend2SdncDirectly = true.");
296                 return true;
297             }
298         
299         logger.info("AbstractSdncOperationTask.isSend2SdncDirectly = false.");
300         return false;
301     }
302
303     protected String getSdncIp() {
304         logger.info("AbstractSdncOperationTask.getSdncIp begin.");
305         String sdncIp = null;
306          sdncIp = UrnPropertiesReader.getVariable("sdnc-ip");
307         String returnIp = StringUtils.isBlank(sdncIp) || !isIp(sdncIp) ? null : sdncIp;
308         logger.info("AbstractSdncOperationTask.getSdncIp: sdncIp = {}", returnIp);
309         return returnIp;
310     }
311
312     protected String getSdncPort() {
313         logger.info("AbstractSdncOperationTask.getSdncPort begin.");
314         String sdncPort = UrnPropertiesReader.getVariable("sdnc-port");
315         String returnPort = StringUtils.isBlank(sdncPort) ? null : sdncPort;
316         logger.info("AbstractSdncOperationTask.getSdncPort: returnPort = {}", sdncPort);
317         return returnPort;
318     }
319
320     private GenericResourceApi getGenericResourceApiClient() {
321         logger.info("AbstractSdncOperationTask.getGenericResourceApiClient begin!");
322         String msbIp = System.getenv().get(ONAP_IP);
323         int msbPort = DEFAULT_MSB_PORT;
324         if (StringUtils.isBlank(msbIp) || !isIp(msbIp)) {
325             msbIp = env.getProperty("msb-ip");
326             if (StringUtils.isBlank(msbIp)) {
327                 msbIp = env.getProperty("msb.address", DEFAULT_MSB_IP);
328             }
329         }
330         String strMsbPort = env.getProperty("msb-port");
331         if (StringUtils.isBlank(strMsbPort)) {
332             strMsbPort = env.getProperty("msb.port", String.valueOf(DEFAULT_MSB_PORT));
333         }
334         msbPort = Integer.valueOf(strMsbPort);
335         
336         logger.info("AbstractSdncOperationTask.getGenericResourceApiClient msbIp = " + msbIp + " msbPort = " + msbPort);
337         MSBServiceClient msbClient = new MSBServiceClient(msbIp, msbPort);
338         RestServiceCreater restServiceCreater = new RestServiceCreater(msbClient);
339         logger.info("AbstractSdncOperationTask.getGenericResourceApiClient end!");
340         return restServiceCreater.createService(GenericResourceApi.class);
341     }
342
343     protected boolean isIp(String msbIp) {
344         return !StringUtils.isBlank(msbIp) && msbIp.split("\\.").length == 4;
345     }
346
347     public String getProcessKey(DelegateExecution execution) {
348         return execution.getProcessEngineServices().getRepositoryService().getProcessDefinition(execution.getProcessDefinitionId()).getKey();
349     }
350 }