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