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