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