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