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