ChefApiClient Package Reorganization and cleanup
[appc.git] / appc-adapters / appc-chef-adapter / appc-chef-adapter-bundle / src / main / java / org / onap / appc / adapter / chef / impl / ChefAdapterImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
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  *
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  * ============LICENSE_END=========================================================
23  */
24 package org.onap.appc.adapter.chef.impl;
25
26 import java.io.File;
27 import java.util.Arrays;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Properties;
31 import org.apache.commons.lang.StringUtils;
32 import org.apache.http.HttpEntity;
33 import org.apache.http.HttpResponse;
34 import org.apache.http.client.methods.HttpGet;
35 import org.apache.http.impl.client.CloseableHttpClient;
36 import org.apache.http.impl.client.HttpClients;
37 import org.apache.http.util.EntityUtils;
38 import org.json.JSONException;
39 import org.json.JSONObject;
40 import org.onap.appc.adapter.chef.ChefAdapter;
41 import org.onap.appc.adapter.chef.chefclient.api.ChefApiClient;
42 import org.onap.appc.adapter.chef.chefclient.ChefApiClientFactory;
43 import org.onap.appc.adapter.chef.chefclient.api.ChefResponse;
44 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
45 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
46 import com.att.eelf.configuration.EELFLogger;
47 import com.att.eelf.configuration.EELFManager;
48
49 /**
50  * This class implements the {@link ChefAdapter} interface. This interface defines the behaviors that our service
51  * provides.
52  */
53 public class ChefAdapterImpl implements ChefAdapter {
54
55     // chef server Initialize variable
56     private String username = StringUtils.EMPTY;
57     private String clientPrivatekey = StringUtils.EMPTY;
58     private String chefserver = StringUtils.EMPTY;
59     private String serverAddress = StringUtils.EMPTY;
60     private String organizations = StringUtils.EMPTY;
61
62     @SuppressWarnings("nls")
63     public static final String MDC_ADAPTER = "adapter";
64
65     @SuppressWarnings("nls")
66     public static final String MDC_SERVICE = "service";
67
68     @SuppressWarnings("nls")
69     public static final String OUTCOME_FAILURE = "failure";
70
71     @SuppressWarnings("nls")
72     public static final String OUTCOME_SUCCESS = "success";
73
74     @SuppressWarnings("nls")
75     public static final String PROPERTY_PROVIDER = "provider";
76
77     @SuppressWarnings("nls")
78     public static final String PROPERTY_PROVIDER_IDENTITY = "identity";
79
80     @SuppressWarnings("nls")
81     public static final String PROPERTY_PROVIDER_NAME = "name";
82
83     @SuppressWarnings("nls")
84     public static final String PROPERTY_PROVIDER_TENANT = "tenant";
85
86     @SuppressWarnings("nls")
87     public static final String PROPERTY_PROVIDER_TENANT_NAME = "name";
88
89     @SuppressWarnings("nls")
90     public static final String PROPERTY_PROVIDER_TENANT_PASSWORD = "password"; // NOSONAR
91
92     @SuppressWarnings("nls")
93     public static final String PROPERTY_PROVIDER_TENANT_USERID = "userid";
94
95     @SuppressWarnings("nls")
96     public static final String PROPERTY_PROVIDER_TYPE = "type";
97
98
99     private static final EELFLogger logger = EELFManager.getInstance().getLogger(ChefAdapterImpl.class);
100
101     private static final String CANNOT_FIND_PRIVATE_KEY_STR =
102         "Cannot find the private key in the APPC file system, please load the private key to ";
103
104     private static final String POSTING_REQUEST_JSON_ERROR_STR = "Error posting request due to invalid JSON block: ";
105     private static final String POSTING_REQUEST_ERROR_STR = "Error posting request: ";
106     private static final String CHEF_CLIENT_RESULT_CODE_STR = "chefClientResult.code";
107     private static final String CHEF_SERVER_RESULT_CODE_STR = "chefServerResult.code";
108     private static final String CHEF_CLIENT_RESULT_MSG_STR = "chefClientResult.message";
109     private static final String CHEF_SERVER_RESULT_MSG_STR = "chefServerResult.message";
110     private static final String CHEF_ACTION_STR = "chefAction";
111     private static final String NODE_LIST_STR = "NodeList";
112     private ChefApiClientFactory chefApiClientFactory = new ChefApiClientFactory();
113
114     /**
115      * This default constructor is used as a work around because the activator wasnt getting called
116      */
117     public ChefAdapterImpl() {
118         initialize();
119     }
120
121     public ChefAdapterImpl(Properties props) {
122         initialize();
123     }
124
125     /**
126      * This constructor is used primarily in the test cases to bypass initialization of the adapter for isolated,
127      * disconnected testing
128      *
129      * @param initialize True if the adapter is to be initialized, can false if not
130      */
131
132     public ChefAdapterImpl(boolean initialize) {
133         if (initialize) {
134             initialize();
135         }
136     }
137
138     public ChefAdapterImpl(String key) {
139         initialize();
140     }
141
142     @SuppressWarnings("nls")
143     @Override
144     public void vnfcEnvironment(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
145         int code;
146         try {
147             logger.info("environment of VNF-C");
148             chefInfo(params, ctx);
149             RequestContext rc = new RequestContext(ctx);
150             logger.info("Context" + ctx);
151             rc.isAlive();
152             String env = params.get("Environment");
153             logger.info("Environmnet" + env);
154             if (env.equals(StringUtils.EMPTY)) {
155                 chefServerResult(rc, 200, "Skip Environment block ");
156             } else {
157                 JSONObject envJ = new JSONObject(env);
158                 String envName = envJ.getString("name");
159                 String message;
160                 if (privateKeyCheck()) {
161                     // update the details of an environment on the Chef server.
162                     ChefApiClient chefApiClient = chefApiClientFactory.create(chefserver, organizations, username, clientPrivatekey);
163                     ChefResponse chefResponse = chefApiClient.put("/environments/" + envName, env);
164                     code = chefResponse.getStatusCode();
165                     message = chefResponse.getBody();
166                     if (code == 404) {
167                         // need create a new environment
168                         chefResponse = chefApiClient.post("/environments", env);
169                         code = chefResponse.getStatusCode();
170                         message = chefResponse.getBody();
171                         logger.info("requestbody {}", chefResponse.getBody());
172                     }
173
174                 } else {
175                     code = 500;
176                     message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
177                     doFailure(ctx, code, message);
178                 }
179                 chefServerResult(rc, code, message);
180             }
181         } catch (JSONException e) {
182             code = 401;
183             logger.error(POSTING_REQUEST_JSON_ERROR_STR, e);
184             doFailure(ctx, code, POSTING_REQUEST_JSON_ERROR_STR + e.getMessage());
185         } catch (Exception e) {
186             code = 401;
187             logger.error(POSTING_REQUEST_ERROR_STR, e);
188             doFailure(ctx, code, POSTING_REQUEST_ERROR_STR + e.getMessage());
189         }
190     }
191
192     @SuppressWarnings("nls")
193     @Override
194     public void vnfcNodeobjects(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
195         logger.info("update the nodeObjects of VNF-C");
196         int code;
197         try {
198             chefInfo(params, ctx);
199             String nodeListS = params.get(NODE_LIST_STR);
200             String nodeS = params.get("Node");
201             if (StringUtils.isNotBlank(nodeListS) && StringUtils.isNotBlank(nodeS)) {
202                 nodeListS = nodeListS.replace("[", StringUtils.EMPTY);
203                 nodeListS = nodeListS.replace("]", StringUtils.EMPTY);
204                 nodeListS = nodeListS.replace("\"", StringUtils.EMPTY);
205                 nodeListS = nodeListS.replace(" ", StringUtils.EMPTY);
206                 List<String> nodes = Arrays.asList(nodeListS.split("\\s*,\\s*"));
207                 RequestContext rc = new RequestContext(ctx);
208                 rc.isAlive();
209                 code = 200;
210                 String message = null;
211                 if (privateKeyCheck()) {
212                     ChefApiClient cac = chefApiClientFactory.create(chefserver, organizations, username, clientPrivatekey);
213
214                     for (String nodeName: nodes) {
215                         JSONObject nodeJ = new JSONObject(nodeS);
216                         nodeJ.remove("name");
217                         nodeJ.put("name", nodeName);
218                         String nodeObject = nodeJ.toString();
219                         logger.info(nodeObject);
220                         ChefResponse chefResponse = cac.put("/nodes/" + nodeName, nodeObject);
221                         code = chefResponse.getStatusCode();
222                         message = chefResponse.getBody();
223                         if (code != 200) {
224                             break;
225                         }
226                     }
227                 } else {
228                     code = 500;
229                     message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
230                     doFailure(ctx, code, message);
231                 }
232                 chefServerResult(rc, code, message);
233             } else {
234                 throw new SvcLogicException("Missing Mandatory param(s) Node , NodeList ");
235             }
236         } catch (JSONException e) {
237             code = 401;
238             logger.error(POSTING_REQUEST_JSON_ERROR_STR, e);
239             doFailure(ctx, code, POSTING_REQUEST_JSON_ERROR_STR + e.getMessage());
240         } catch (Exception e) {
241             code = 401;
242             logger.error(POSTING_REQUEST_ERROR_STR, e);
243             doFailure(ctx, code, POSTING_REQUEST_ERROR_STR + e.getMessage());
244         }
245     }
246
247     @Override
248     public void vnfcPushJob(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
249         int code;
250         try {
251             chefInfo(params, ctx);
252             String nodeList = params.get(NODE_LIST_STR);
253             if (StringUtils.isNotBlank(nodeList)) {
254                 String isCallback = params.get("CallbackCapable");
255                 String chefAction = "/pushy/jobs";
256                 // need work on this
257                 String pushRequest;
258                 if ("true".equals(isCallback)) {
259                     String requestId = params.get("RequestId");
260                     String callbackUrl = params.get("CallbackUrl");
261                     pushRequest = "{" + "\"command\": \"chef-client\"," + "\"run_timeout\": 300," + "\"nodes\":"
262                         + nodeList + "," + "\"env\": {\"RequestId\": \"" + requestId + "\", \"CallbackUrl\": \""
263                         + callbackUrl + "\"}," + "\"capture_output\": true" + "}";
264                 } else {
265                     pushRequest = "{" + "\"command\": \"chef-client\"," + "\"run_timeout\": 300," + "\"nodes\":"
266                         + nodeList + "," + "\"env\": {}," + "\"capture_output\": true" + "}";
267                 }
268                 RequestContext rc = new RequestContext(ctx);
269
270                 rc.isAlive();
271                 SvcLogicContext svcLogic = rc.getSvcLogicContext();
272                 ChefApiClient cac = chefApiClientFactory.create(chefserver, organizations, username, clientPrivatekey);
273                 ChefResponse chefResponse = cac.post(chefAction, pushRequest);
274                 code = chefResponse.getStatusCode();
275                 logger.info("pushRequest:" + pushRequest);
276                 logger.info("requestbody: {}", chefResponse.getBody());
277                 String message = chefResponse.getBody();
278                 if (code == 201) {
279                     int startIndex = message.indexOf("jobs") + 5;
280                     int endIndex = message.length() - 2;
281                     String jobID = message.substring(startIndex, endIndex);
282                     svcLogic.setAttribute("jobID", jobID);
283                     logger.info(jobID);
284                 }
285                 chefServerResult(rc, code, message);
286             } else {
287                 throw new SvcLogicException("Missing Mandatory param(s)  NodeList ");
288             }
289         } catch (JSONException e) {
290             code = 401;
291             logger.error(POSTING_REQUEST_JSON_ERROR_STR, e);
292             doFailure(ctx, code, POSTING_REQUEST_JSON_ERROR_STR + e.getMessage());
293         } catch (Exception e) {
294             code = 401;
295             logger.error(POSTING_REQUEST_ERROR_STR, e);
296             doFailure(ctx, code, POSTING_REQUEST_ERROR_STR + e.getMessage());
297         }
298     }
299
300     @SuppressWarnings("nls")
301     @Override
302     public void fetchResults(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
303         int code = 200;
304         try {
305             chefInfo(params, ctx);
306             String nodeListS = params.get(NODE_LIST_STR);
307             if (StringUtils.isNotBlank(nodeListS)) {
308                 nodeListS = nodeListS.replace("[", StringUtils.EMPTY);
309                 nodeListS = nodeListS.replace("]", StringUtils.EMPTY);
310                 nodeListS = nodeListS.replace("\"", StringUtils.EMPTY);
311                 nodeListS = nodeListS.replace(" ", StringUtils.EMPTY);
312                 List<String> nodes = Arrays.asList(nodeListS.split("\\s*,\\s*"));
313                 JSONObject result = new JSONObject();
314                 String returnMessage = StringUtils.EMPTY;
315
316                 for (String node : nodes) {
317                     String chefAction = "/nodes/" + node;
318                     String message;
319                     if (privateKeyCheck()) {
320                         ChefResponse chefResponse = getApiMethod(chefAction);
321                         code = chefResponse.getStatusCode();
322                         message = chefResponse.getBody();
323                     } else {
324                         code = 500;
325                         message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
326                         doFailure(ctx, code, message);
327                     }
328                     if (code == 200) {
329                         JSONObject nodeResult = new JSONObject();
330                         JSONObject allNodeData = new JSONObject(message);
331                         allNodeData = allNodeData.getJSONObject("normal");
332                         String attribute = "PushJobOutput";
333
334                         String resultData = allNodeData.optString(attribute);
335                         if (resultData == null) {
336                             resultData = allNodeData.optJSONObject(attribute).toString();
337
338                             if (resultData == null) {
339                                 resultData = allNodeData.optJSONArray(attribute).toString();
340
341                                 if (resultData == null) {
342                                     code = 500;
343                                     returnMessage = "Cannot find " + attribute;
344                                     break;
345                                 }
346                             }
347                         }
348                         nodeResult.put(attribute, resultData);
349                         result.put(node, nodeResult);
350                         returnMessage = result.toString();
351                     } else {
352                         code = 500;
353                         returnMessage = message + " Cannot access: " + node;
354                         doFailure(ctx, code, message);
355                         break;
356                     }
357                 }
358
359                 RequestContext rc = new RequestContext(ctx);
360                 rc.isAlive();
361                 chefServerResult(rc, code, returnMessage);
362             } else {
363                 throw new SvcLogicException("Missing Mandatory param(s)  NodeList ");
364             }
365         } catch (JSONException e) {
366             code = 401;
367             logger.error(POSTING_REQUEST_JSON_ERROR_STR, e);
368             doFailure(ctx, code, POSTING_REQUEST_JSON_ERROR_STR + e.getMessage());
369         } catch (Exception e) {
370             code = 401;
371             logger.error(POSTING_REQUEST_ERROR_STR , e);
372             doFailure(ctx, code, POSTING_REQUEST_ERROR_STR + e.getMessage());
373         }
374     }
375
376     private ChefResponse getApiMethod(String chefAction) {
377         ChefApiClient cac = chefApiClientFactory.create(chefserver, organizations, username, clientPrivatekey);
378         return cac.get(chefAction);
379     }
380
381     /**
382      * build node object
383      */
384     @SuppressWarnings("nls")
385     @Override
386     public void nodeObejctBuilder(Map<String, String> params, SvcLogicContext ctx) {
387         logger.info("nodeObejctBuilder");
388         String name = params.get("nodeobject.name");
389         String normal = params.get("nodeobject.normal");
390         String overrides = params.get("nodeobject.overrides");
391         String defaults = params.get("nodeobject.defaults");
392         String runList = params.get("nodeobject.run_list");
393         String chefEnvironment = params.get("nodeobject.chef_environment");
394         String nodeObject = "{\"json_class\":\"Chef::Node\",\"default\":{" + defaults
395             + "},\"chef_type\":\"node\",\"run_list\":[" + runList + "],\"override\":{" + overrides
396             + "},\"normal\": {" + normal + "},\"automatic\":{},\"name\":\"" + name + "\",\"chef_environment\":\""
397             + chefEnvironment + "\"}";
398         logger.info(nodeObject);
399         RequestContext rc = new RequestContext(ctx);
400         rc.isAlive();
401         SvcLogicContext svcLogic = rc.getSvcLogicContext();
402         svcLogic.setAttribute("chef.nodeObject", nodeObject);
403     }
404
405     /**
406      * send get request to chef server
407      */
408     private void chefInfo(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
409
410         username = params.get("username");
411         serverAddress = params.get("serverAddress");
412         organizations = params.get("organizations");
413         if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(serverAddress)
414             && StringUtils.isNotBlank(organizations)) {
415             chefserver = "https://" + serverAddress + "/organizations/" + organizations;
416             clientPrivatekey = "/opt/onap/appc/chef/" + serverAddress + "/" + organizations + "/" + username + ".pem";
417             logger.info(" clientPrivatekey  " + clientPrivatekey);
418         } else {
419             doFailure(ctx, 401, "Missing mandatory param(s) such as username, serverAddress, organizations");
420         }
421     }
422
423     private Boolean privateKeyCheck() {
424         File f = new File(clientPrivatekey);
425         if (f.exists()) {
426             logger.info("Key exists");
427             return true;
428         } else {
429             logger.info("Key doesn't exists");
430             return false;
431         }
432     }
433
434     @SuppressWarnings("nls")
435     @Override
436     public void retrieveData(Map<String, String> params, SvcLogicContext ctx) {
437         String allConfigData = params.get("allConfig");
438         String key = params.get("key");
439         String dgContext = params.get("dgContext");
440         JSONObject jsonConfig = new JSONObject(allConfigData);
441         String contextData = fetchContextData(key, jsonConfig);
442
443         RequestContext rc = new RequestContext(ctx);
444         rc.isAlive();
445         SvcLogicContext svcLogic = rc.getSvcLogicContext();
446         svcLogic.setAttribute(dgContext, contextData);
447     }
448
449     private String fetchContextData(String key, JSONObject jsonConfig) {
450         try {
451             return jsonConfig.getString(key);
452         } catch (Exception e) {
453             logger.error("Failed getting string value corresponding to " + key + ". Trying to fetch nested json object", e);
454             try {
455                 return jsonConfig.getJSONObject(key).toString();
456             } catch (Exception ex) {
457                 logger.error("Failed getting json object corresponding to " + key + ". Trying to fetch array", ex);
458                 return jsonConfig.getJSONArray(key).toString();
459             }
460         }
461     }
462
463     @SuppressWarnings("nls")
464     @Override
465     public void combineStrings(Map<String, String> params, SvcLogicContext ctx) {
466         String string1 = params.get("String1");
467         String string2 = params.get("String2");
468         String dgContext = params.get("dgContext");
469         String contextData = string1 + string2;
470         RequestContext rc = new RequestContext(ctx);
471         rc.isAlive();
472         SvcLogicContext svcLogic = rc.getSvcLogicContext();
473         svcLogic.setAttribute(dgContext, contextData);
474     }
475
476     /**
477      * Send GET request to chef server
478      */
479     @SuppressWarnings("nls")
480
481     @Override
482     public void chefGet(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
483         logger.info("chef get method");
484         chefInfo(params, ctx);
485         String chefAction = params.get(CHEF_ACTION_STR);
486         RequestContext rc = new RequestContext(ctx);
487         rc.isAlive();
488         int code;
489         String message;
490
491         if (privateKeyCheck()) {
492             ChefResponse chefResponse = getApiMethod(chefAction);
493             code = chefResponse.getStatusCode();
494             message = chefResponse.getBody();
495         } else {
496             code = 500;
497             message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
498         }
499         chefServerResult(rc, code, message);
500     }
501
502     /**
503      * Send PUT request to chef server
504      */
505     @SuppressWarnings("nls")
506
507     @Override
508     public void chefPut(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
509         chefInfo(params, ctx);
510         String chefAction = params.get(CHEF_ACTION_STR);
511         String chefNodeStr = params.get("chefRequestBody");
512         RequestContext rc = new RequestContext(ctx);
513         rc.isAlive();
514         int code;
515         String message;
516         if (privateKeyCheck()) {
517             ChefApiClient chefApiClient = chefApiClientFactory.create(chefserver, organizations, username, clientPrivatekey);
518
519             ChefResponse chefResponse = chefApiClient.put(chefAction, chefNodeStr);
520             code = chefResponse.getStatusCode();
521             message = chefResponse.getBody();
522         } else {
523             code = 500;
524             message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
525         }
526         logger.info(code + "   " + message);
527         chefServerResult(rc, code, message);
528     }
529
530     /**
531      * send Post request to chef server
532      */
533     @Override
534     public void chefPost(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
535         chefInfo(params, ctx);
536         logger.info("chef Post method");
537         logger.info(username + " " + clientPrivatekey + " " + chefserver + " " + organizations);
538         String chefNodeStr = params.get("chefRequestBody");
539         String chefAction = params.get(CHEF_ACTION_STR);
540
541         RequestContext rc = new RequestContext(ctx);
542         rc.isAlive();
543         int code;
544         String message;
545         // should load pem from somewhere else
546         if (privateKeyCheck()) {
547             ChefApiClient chefApiClient = chefApiClientFactory.create(chefserver, organizations, username, clientPrivatekey);
548
549             // need pass path into it
550             // "/nodes/testnode"
551             ChefResponse chefResponse = chefApiClient.post(chefAction, chefNodeStr);
552             code = chefResponse.getStatusCode();
553             message = chefResponse.getBody();
554         } else {
555             code = 500;
556             message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
557         }
558         logger.info(code + "   " + message);
559         chefServerResult(rc, code, message);
560     }
561
562     /**
563      * send delete request to chef server
564      */
565     @Override
566     public void chefDelete(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
567         logger.info("chef delete method");
568         chefInfo(params, ctx);
569         String chefAction = params.get(CHEF_ACTION_STR);
570         RequestContext rc = new RequestContext(ctx);
571         rc.isAlive();
572         int code;
573         String message;
574         if (privateKeyCheck()) {
575             ChefApiClient chefApiClient = chefApiClientFactory.create(chefserver, organizations, username, clientPrivatekey);
576             ChefResponse chefResponse = chefApiClient.delete(chefAction);
577             code = chefResponse.getStatusCode();
578             message = chefResponse.getBody();
579         } else {
580             code = 500;
581             message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
582         }
583         logger.info(code + "   " + message);
584         chefServerResult(rc, code, message);
585     }
586
587     /**
588      * Trigger target vm run chef
589      */
590     @Override
591     public void trigger(Map<String, String> params, SvcLogicContext ctx) {
592         logger.info("Run trigger method");
593         String tVmIp = params.get("ip");
594         RequestContext rc = new RequestContext(ctx);
595         rc.isAlive();
596
597         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
598             HttpGet httpGet = new HttpGet(tVmIp);
599             HttpResponse response = httpClient.execute(httpGet);
600             int responseCode = response.getStatusLine().getStatusCode();
601             HttpEntity entity = response.getEntity();
602             String responseOutput = EntityUtils.toString(entity);
603             chefClientResult(rc, responseCode, responseOutput);
604             doSuccess(rc);
605         } catch (Exception e) {
606             logger.error("An error occurred when executing trigger method", e);
607             doFailure(rc, 500, e.toString());
608         }
609     }
610
611     @SuppressWarnings("nls")
612     @Override
613     public void checkPushJob(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
614         int code;
615         try {
616             chefInfo(params, ctx);
617             String jobID = params.get("jobid");
618             String retry = params.get("retryTimes");
619             String intrva = params.get("retryInterval");
620             if (StringUtils.isNotBlank(retry) && StringUtils.isNotBlank(intrva)) {
621
622                 int retryTimes = Integer.parseInt(params.get("retryTimes"));
623                 int retryInterval = Integer.parseInt(params.get("retryInterval"));
624
625                 String chefAction = "/pushy/jobs/" + jobID;
626
627                 RequestContext rc = new RequestContext(ctx);
628                 rc.isAlive();
629                 SvcLogicContext svcLogic = rc.getSvcLogicContext();
630                 String message = StringUtils.EMPTY;
631                 String status = StringUtils.EMPTY;
632                 for (int i = 0; i < retryTimes; i++) {
633                     sleepFor(retryInterval);
634                     ChefResponse chefResponse = getApiMethod(chefAction);
635                     code = chefResponse.getStatusCode();
636                     message = chefResponse.getBody();
637                     JSONObject obj = new JSONObject(message);
638                     status = obj.getString("status");
639                     if (!"running".equals(status)) {
640                         logger.info(i + " time " + code + "   " + status);
641                         break;
642                     }
643                 }
644                 resolveSvcLogicAttributes(svcLogic, message, status);
645             } else {
646                 throw new SvcLogicException("Missing Mandatory param(s) retryTimes , retryInterval ");
647             }
648         } catch (Exception e) {
649             code = 401;
650             logger.error("An error occurred when executing checkPushJob method", e);
651             doFailure(ctx, code, e.getMessage());
652         }
653     }
654
655     private void resolveSvcLogicAttributes(SvcLogicContext svcLogic, String message, String status) {
656         if ("complete".equals(status)) {
657             svcLogic.setAttribute(CHEF_SERVER_RESULT_CODE_STR, "200");
658             svcLogic.setAttribute(CHEF_SERVER_RESULT_MSG_STR, message);
659         } else {
660             if ("running".equals(status)) {
661                 svcLogic.setAttribute(CHEF_SERVER_RESULT_CODE_STR, "202");
662                 svcLogic.setAttribute(CHEF_SERVER_RESULT_MSG_STR, "chef client runtime out");
663             } else {
664                 svcLogic.setAttribute(CHEF_SERVER_RESULT_CODE_STR, "500");
665                 svcLogic.setAttribute(CHEF_SERVER_RESULT_MSG_STR, message);
666             }
667         }
668     }
669
670     private void sleepFor(int retryInterval) {
671         try {
672             Thread.sleep(retryInterval); // 1000 milliseconds is one second.
673         } catch (InterruptedException ex) {
674             Thread.currentThread().interrupt();
675         }
676     }
677
678     @SuppressWarnings("nls")
679     @Override
680     public void pushJob(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
681         int code;
682         try {
683             chefInfo(params, ctx);
684             String pushRequest = params.get("pushRequest");
685             String chefAction = "/pushy/jobs";
686             RequestContext rc = new RequestContext(ctx);
687             rc.isAlive();
688             SvcLogicContext svcLogic = rc.getSvcLogicContext();
689             ChefApiClient chefApiClient = chefApiClientFactory.create(chefserver, organizations, username, clientPrivatekey);
690             ChefResponse chefResponse = chefApiClient.post(chefAction, pushRequest);
691
692             code = chefResponse.getStatusCode();
693             String message = chefResponse.getBody();
694             if (code == 201) {
695                 int startIndex = message.indexOf("jobs") + 6;
696                 int endIndex = message.length() - 2;
697                 String jobID = message.substring(startIndex, endIndex);
698                 svcLogic.setAttribute("jobID", jobID);
699                 logger.info(jobID);
700             }
701             chefServerResult(rc, code, message);
702         } catch (Exception e) {
703             code = 401;
704             logger.error("An error occurred when executing pushJob method", e);
705             doFailure(ctx, code, e.getMessage());
706         }
707     }
708
709     @SuppressWarnings("static-method")
710     private void doFailure(RequestContext rc, int code, String message) {
711         SvcLogicContext svcLogic = rc.getSvcLogicContext();
712         String msg = (message == null) ? Integer.toString(code) : message;
713         if (msg.contains("\n")) {
714             msg = msg.substring(msg.indexOf('\n'));
715         }
716
717         String status;
718         try {
719             status = Integer.toString(code);
720         } catch (Exception e) {
721             status = "500";
722             logger.error("Parsing status code failed. Setting it to \"500\"", e);
723         }
724         svcLogic.setAttribute("chefAgent.code", status);
725         svcLogic.setAttribute("chefAgent.message", msg);
726     }
727
728     /**
729      * @param rc The request context that manages the state and recovery of the request for the life of its processing.
730      */
731     @SuppressWarnings("static-method")
732     private void doSuccess(RequestContext rc) {
733         SvcLogicContext svcLogic = rc.getSvcLogicContext();
734         svcLogic.setAttribute("chefAgent.code", "200");
735     }
736
737     @SuppressWarnings("static-method")
738     private void chefServerResult(RequestContext rc, int code, String message) {
739         initSvcLogic(rc, code, message, "server");
740     }
741
742     @SuppressWarnings("static-method")
743     private void chefClientResult(RequestContext rc, int code, String message) {
744         initSvcLogic(rc, code, message, "client");
745     }
746
747     private void initSvcLogic(RequestContext rc, int code, String message, String target) {
748
749         SvcLogicContext svcLogic = rc.getSvcLogicContext();
750         String codeStr = "server".equals(target) ? CHEF_SERVER_RESULT_CODE_STR : CHEF_CLIENT_RESULT_CODE_STR;
751         String messageStr = "client".equals(target) ? CHEF_SERVER_RESULT_MSG_STR : CHEF_CLIENT_RESULT_MSG_STR;
752
753         svcLogic.setStatus(OUTCOME_SUCCESS);
754         svcLogic.setAttribute(codeStr, Integer.toString(code));
755         svcLogic.setAttribute(messageStr, message);
756         logger.info(codeStr + ": " + svcLogic.getAttribute(codeStr));
757         logger.info(messageStr + ": " + svcLogic.getAttribute(messageStr));
758     }
759
760
761     /**
762      * initialize the provider adapter by building the context cache
763      */
764     private void initialize() {
765
766         logger.info("Initialize Chef Adapter");
767     }
768
769     @SuppressWarnings("static-method")
770     private void doFailure(SvcLogicContext svcLogic, int code, String message) throws SvcLogicException {
771
772         String cutMessage = message.contains("\n") ? message.substring(message.indexOf('\n')) : message;
773
774         svcLogic.setStatus(OUTCOME_FAILURE);
775         svcLogic.setAttribute(CHEF_SERVER_RESULT_CODE_STR, Integer.toString(code));
776         svcLogic.setAttribute(CHEF_SERVER_RESULT_MSG_STR, cutMessage);
777
778         throw new SvcLogicException("Chef Adapter error:" + cutMessage);
779     }
780 }