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