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