Minor and major fixes in ChefAdapterImpl
[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     /**
143      * Returns the symbolic name of the adapter
144      *
145      * @return The adapter name
146      * @see org.onap.appc.adapter.chef.ChefAdapter#getAdapterName()
147      */
148     @Override
149     public String getAdapterName() {
150         return "chef adapter";
151     }
152
153     @SuppressWarnings("nls")
154     @Override
155     public void vnfcEnvironment(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
156         int code;
157         try {
158             logger.info("environment of VNF-C");
159             chefInfo(params, ctx);
160             RequestContext rc = new RequestContext(ctx);
161             logger.info("Context" + ctx);
162             rc.isAlive();
163             String env = params.get("Environment");
164             logger.info("Environmnet" + env);
165             if (env.equals(StringUtils.EMPTY)) {
166                 chefServerResult(rc, 200, "Skip Environment block ");
167             } else {
168                 JSONObject envJ = new JSONObject(env);
169                 String envName = envJ.getString("name");
170                 String message;
171                 if (privateKeyCheck()) {
172                     // update the details of an environment on the Chef server.
173                     ChefApiClient cac = new ChefApiClient(username, clientPrivatekey, chefserver, organizations);
174                     ApiMethod am = cac.put("/environments/" + envName).body(env);
175                     am.execute();
176                     code = am.getReturnCode();
177                     message = am.getResponseBodyAsString();
178                     if (code == 404) {
179                         // need create a new environment
180                         am = cac.post("/environments").body(env);
181                         am.execute();
182                         code = am.getReturnCode();
183                         message = am.getResponseBodyAsString();
184                         logger.info("requestbody" + am.getReqBody());
185                     }
186
187                 } else {
188                     code = 500;
189                     message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
190                     doFailure(ctx, code, message);
191                 }
192                 chefServerResult(rc, code, message);
193             }
194         }
195
196         catch (JSONException e) {
197             code = 401;
198             doFailure(ctx, code, POSTING_REQUEST_JSON_ERROR_STR + e.getMessage());
199         } catch (Exception e) {
200             code = 401;
201             doFailure(ctx, code, POSTING_REQUEST_ERROR_STR + e.getMessage());
202         }
203     }
204
205     @SuppressWarnings("nls")
206     @Override
207     public void vnfcNodeobjects(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
208         logger.info("update the nodeObjects of VNF-C");
209         int code;
210         try {
211             chefInfo(params, ctx);
212             String nodeListS = params.get(NODE_LIST_STR);
213             String nodeS = params.get("Node");
214             if (StringUtils.isNotBlank(nodeListS) && StringUtils.isNotBlank(nodeS)) {
215                 nodeListS = nodeListS.replace("[", StringUtils.EMPTY);
216                 nodeListS = nodeListS.replace("]", StringUtils.EMPTY);
217                 nodeListS = nodeListS.replace("\"", StringUtils.EMPTY);
218                 nodeListS = nodeListS.replace(" ", StringUtils.EMPTY);
219                 List<String> nodes = Arrays.asList(nodeListS.split("\\s*,\\s*"));
220                 RequestContext rc = new RequestContext(ctx);
221                 rc.isAlive();
222                 code = 200;
223                 String message = null;
224                 if (privateKeyCheck()) {
225                     ChefApiClient cac = new ChefApiClient(username, clientPrivatekey, chefserver, organizations);
226
227                     for (int i = 0; i < nodes.size(); i++) {
228                         String nodeName = nodes.get(i);
229                         JSONObject nodeJ = new JSONObject(nodeS);
230                         nodeJ.remove("name");
231                         nodeJ.put("name", nodeName);
232                         String nodeObject = nodeJ.toString();
233                         logger.info(nodeObject);
234                         ApiMethod am = cac.put("/nodes/" + nodeName).body(nodeObject);
235                         am.execute();
236                         code = am.getReturnCode();
237                         message = am.getResponseBodyAsString();
238                         if (code != 200) {
239                             break;
240                         }
241                     }
242                 } else {
243                     code = 500;
244                     message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
245                     doFailure(ctx, code, message);
246                 }
247                 chefServerResult(rc, code, message);
248             }
249             else {
250                 throw new SvcLogicException("Missing Mandatory param(s) Node , NodeList ");
251             }
252         } catch (JSONException e) {
253             code = 401;
254             doFailure(ctx, code, POSTING_REQUEST_JSON_ERROR_STR + e.getMessage());
255         } catch (Exception ex) {
256             code = 401;
257             doFailure(ctx, code, POSTING_REQUEST_ERROR_STR + ex.getMessage());
258         }
259     }
260
261     @Override
262     public void vnfcPushJob(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
263         int code;
264         try {
265             chefInfo(params, ctx);
266             String nodeList = params.get(NODE_LIST_STR);
267             if (StringUtils.isNotBlank(nodeList)) {
268                 String isCallback = params.get("CallbackCapable");
269                 String chefAction = "/pushy/jobs";
270                 // need work on this
271                 String pushRequest;
272                 if ("true".equals(isCallback)) {
273                     String requestId = params.get("RequestId");
274                     String callbackUrl = params.get("CallbackUrl");
275                     pushRequest = "{" + "\"command\": \"chef-client\"," + "\"run_timeout\": 300," + "\"nodes\":"
276                             + nodeList + "," + "\"env\": {\"RequestId\": \"" + requestId + "\", \"CallbackUrl\": \""
277                             + callbackUrl + "\"}," + "\"capture_output\": true" + "}";
278                 } else {
279                     pushRequest = "{" + "\"command\": \"chef-client\"," + "\"run_timeout\": 300," + "\"nodes\":"
280                             + nodeList + "," + "\"env\": {}," + "\"capture_output\": true" + "}";
281                 }
282                 RequestContext rc = new RequestContext(ctx);
283
284                 rc.isAlive();
285                 SvcLogicContext svcLogic = rc.getSvcLogicContext();
286                 ChefApiClient cac = new ChefApiClient(username, clientPrivatekey, chefserver, organizations);
287                 ApiMethod am = cac.post(chefAction).body(pushRequest);
288                 am.execute();
289                 code = am.getReturnCode();
290                 logger.info("pushRequest:" + pushRequest);
291                 logger.info("requestbody:" + am.getReqBody());
292                 String message = am.getResponseBodyAsString();
293                 if (code == 201) {
294                     int startIndex = message.indexOf("jobs") + 5;
295                     int endIndex = message.length() - 2;
296                     String jobID = message.substring(startIndex, endIndex);
297                     svcLogic.setAttribute("jobID", jobID);
298                     logger.info(jobID);
299                 }
300                 chefServerResult(rc, code, message);
301             }
302             else {
303                 throw new SvcLogicException("Missing Mandatory param(s)  NodeList ");
304             }
305         } catch (JSONException e) {
306             code = 401;
307             doFailure(ctx, code, POSTING_REQUEST_JSON_ERROR_STR + e.getMessage());
308         } catch (Exception e) {
309             code = 401;
310             doFailure(ctx, code, POSTING_REQUEST_ERROR_STR + e.getMessage());
311         }
312     }
313
314     @SuppressWarnings("nls")
315     @Override
316     public void fetchResults(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
317         int code = 200;
318         try {
319             chefInfo(params, ctx);
320             String nodeListS = params.get(NODE_LIST_STR);
321             if (StringUtils.isNotBlank(nodeListS)) {
322                 nodeListS = nodeListS.replace("[", StringUtils.EMPTY);
323                 nodeListS = nodeListS.replace("]", StringUtils.EMPTY);
324                 nodeListS = nodeListS.replace("\"", StringUtils.EMPTY);
325                 nodeListS = nodeListS.replace(" ", StringUtils.EMPTY);
326                 List<String> nodes = Arrays.asList(nodeListS.split("\\s*,\\s*"));
327                 JSONObject result = new JSONObject();
328                 String returnMessage = StringUtils.EMPTY;
329
330                 for (String node : nodes) {
331                     String chefAction = "/nodes/" + node;
332                     String message;
333                     if (privateKeyCheck()) {
334                         ApiMethod am = getApiMethod(chefAction);
335                         code = am.getReturnCode();
336                         message = am.getResponseBodyAsString();
337                     } else {
338                         code = 500;
339                         message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
340                         doFailure(ctx, code, message);
341                     }
342                     if (code == 200) {
343                         JSONObject nodeResult = new JSONObject();
344                         JSONObject allNodeData = new JSONObject(message);
345                         allNodeData = allNodeData.getJSONObject("normal");
346                         String attribute = "PushJobOutput";
347
348                         String resultData = allNodeData.optString(attribute);
349                         if (resultData == null) {
350                             resultData = allNodeData.optJSONObject(attribute).toString();
351
352                             if (resultData == null) {
353                                 resultData = allNodeData.optJSONArray(attribute).toString();
354
355                                 if (resultData == null) {
356                                     code = 500;
357                                     returnMessage = "Cannot find " + attribute;
358                                     break;
359                                 }
360                             }
361                         }
362                         nodeResult.put(attribute, resultData);
363                         result.put(node, nodeResult);
364                         returnMessage = result.toString();
365                     } else {
366                         code = 500;
367                         returnMessage = message + " Cannot access: " + node;
368                         doFailure(ctx, code, message);
369                         break;
370                     }
371                 }
372
373                 RequestContext rc = new RequestContext(ctx);
374                 rc.isAlive();
375                 chefServerResult(rc, code, returnMessage);
376             } else {
377                 throw new SvcLogicException("Missing Mandatory param(s)  NodeList ");
378             }
379         } catch (JSONException e) {
380             code = 401;
381             doFailure(ctx, code, POSTING_REQUEST_JSON_ERROR_STR + e.getMessage());
382         } catch (Exception ex) {
383             code = 401;
384             doFailure(ctx, code, POSTING_REQUEST_ERROR_STR + ex.getMessage());
385         }
386     }
387
388     private ApiMethod getApiMethod(String chefAction) {
389         ChefApiClient cac = new ChefApiClient(username, clientPrivatekey, chefserver, organizations);
390
391         return cac.get(chefAction).execute();
392     }
393
394     /**
395      * build node object
396      */
397     @SuppressWarnings("nls")
398     @Override
399     public void nodeObejctBuilder(Map<String, String> params, SvcLogicContext ctx) {
400         logger.info("nodeObejctBuilder");
401         String name = params.get("nodeobject.name");
402         String normal = params.get("nodeobject.normal");
403         String overrides = params.get("nodeobject.overrides");
404         String defaults = params.get("nodeobject.defaults");
405         String runList = params.get("nodeobject.run_list");
406         String chefEnvironment = params.get("nodeobject.chef_environment");
407         String nodeObject = "{\"json_class\":\"Chef::Node\",\"default\":{" + defaults
408                 + "},\"chef_type\":\"node\",\"run_list\":[" + runList + "],\"override\":{" + overrides
409                 + "},\"normal\": {" + normal + "},\"automatic\":{},\"name\":\"" + name + "\",\"chef_environment\":\""
410                 + chefEnvironment + "\"}";
411         logger.info(nodeObject);
412         RequestContext rc = new RequestContext(ctx);
413         rc.isAlive();
414         SvcLogicContext svcLogic = rc.getSvcLogicContext();
415         svcLogic.setAttribute("chef.nodeObject", nodeObject);
416     }
417
418     /**
419      * send get request to chef server
420      * 
421      * @throws SvcLogicException
422      */
423     private void chefInfo(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
424
425         username = params.get("username");
426         serverAddress = params.get("serverAddress");
427         organizations = params.get("organizations");
428         if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(serverAddress)
429                 && StringUtils.isNotBlank(organizations)) {
430             chefserver = "https://" + serverAddress + "/organizations/" + organizations;
431             clientPrivatekey = "/opt/app/bvc/chef/" + serverAddress + "/" + organizations + "/" + username + ".pem";
432             logger.info(" clientPrivatekey  " + clientPrivatekey);
433         } else {
434             doFailure(ctx, 401, "Missing mandatory param(s) such as username, serverAddress, organizations");
435         }
436     }
437
438     private Boolean privateKeyCheck() {
439         File f = new File(clientPrivatekey);
440         if (f.exists()) {
441             logger.info("Key exists");
442             return true;
443         } else {
444             logger.info("Key doesn't exists");
445             return false;
446         }
447     }
448
449     @SuppressWarnings("nls")
450     @Override
451     public void retrieveData(Map<String, String> params, SvcLogicContext ctx) {
452         String contextData;
453         String allConfigData = params.get("allConfig");
454         String key = params.get("key");
455         String dgContext = params.get("dgContext");
456         JSONObject josnConfig = new JSONObject(allConfigData);
457
458         try {
459             contextData = josnConfig.getString(key);
460         } catch (Exception e) {
461             try {
462                 contextData = josnConfig.getJSONObject(key).toString();
463             } catch (Exception ex) {
464                 contextData = josnConfig.getJSONArray(key).toString();
465             }
466         }
467
468         RequestContext rc = new RequestContext(ctx);
469         rc.isAlive();
470         SvcLogicContext svcLogic = rc.getSvcLogicContext();
471         svcLogic.setAttribute(dgContext, contextData);
472     }
473
474     @SuppressWarnings("nls")
475     @Override
476     public void combineStrings(Map<String, String> params, SvcLogicContext ctx) {
477         String string1 = params.get("String1");
478         String string2 = params.get("String2");
479         String dgContext = params.get("dgContext");
480         String contextData = string1 + string2;
481         RequestContext rc = new RequestContext(ctx);
482         rc.isAlive();
483         SvcLogicContext svcLogic = rc.getSvcLogicContext();
484         svcLogic.setAttribute(dgContext, contextData);
485     }
486
487     /**
488      * Send GET request to chef server
489      * 
490      * @throws SvcLogicException
491      */
492     @SuppressWarnings("nls")
493
494     @Override
495     public void chefGet(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
496         logger.info("chef get method");
497         chefInfo(params, ctx);
498         String chefAction = params.get(CHEF_ACTION_STR);
499         RequestContext rc = new RequestContext(ctx);
500         rc.isAlive();
501         int code;
502         String message;
503
504         if (privateKeyCheck()) {
505             ApiMethod am = getApiMethod(chefAction);
506             code = am.getReturnCode();
507             message = am.getResponseBodyAsString();
508         } else {
509             code = 500;
510             message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
511         }
512         chefServerResult(rc, code, message);
513     }
514
515     /**
516      * Send PUT request to chef server
517      * 
518      * @throws SvcLogicException
519      */
520     @SuppressWarnings("nls")
521
522     @Override
523     public void chefPut(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
524         chefInfo(params, ctx);
525         String chefAction = params.get(CHEF_ACTION_STR);
526         String chefNodeStr = params.get("chefRequestBody");
527         RequestContext rc = new RequestContext(ctx);
528         rc.isAlive();
529         int code;
530         String message;
531         if (privateKeyCheck()) {
532             ChefApiClient cac = new ChefApiClient(username, clientPrivatekey, chefserver, organizations);
533
534             ApiMethod am = cac.put(chefAction).body(chefNodeStr);
535             am.execute();
536             code = am.getReturnCode();
537             message = am.getResponseBodyAsString();
538         } else {
539             code = 500;
540             message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
541         }
542         logger.info(code + "   " + message);
543         chefServerResult(rc, code, message);
544     }
545
546     /**
547      * send Post request to chef server
548      * 
549      * @throws SvcLogicException
550      */
551     @Override
552     public void chefPost(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
553         chefInfo(params, ctx);
554         logger.info("chef Post method");
555         logger.info(username + " " + clientPrivatekey + " " + chefserver + " " + organizations);
556         String chefNodeStr = params.get("chefRequestBody");
557         String chefAction = params.get(CHEF_ACTION_STR);
558
559         RequestContext rc = new RequestContext(ctx);
560         rc.isAlive();
561         int code;
562         String message;
563         // should load pem from somewhere else
564         if (privateKeyCheck()) {
565             ChefApiClient cac = new ChefApiClient(username, clientPrivatekey, chefserver, organizations);
566
567             // need pass path into it
568             // "/nodes/testnode"
569             ApiMethod am = cac.post(chefAction).body(chefNodeStr);
570             am.execute();
571             code = am.getReturnCode();
572             message = am.getResponseBodyAsString();
573         } else {
574             code = 500;
575             message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
576         }
577         logger.info(code + "   " + message);
578         chefServerResult(rc, code, message);
579     }
580
581     /**
582      * send delete request to chef server
583      * 
584      * @throws SvcLogicException
585      */
586     @Override
587     public void chefDelete(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
588         logger.info("chef delete method");
589         chefInfo(params, ctx);
590         String chefAction = params.get(CHEF_ACTION_STR);
591         RequestContext rc = new RequestContext(ctx);
592         rc.isAlive();
593         int code;
594         String message;
595         if (privateKeyCheck()) {
596             ChefApiClient cac = new ChefApiClient(username, clientPrivatekey, chefserver, organizations);
597             ApiMethod am = cac.delete(chefAction);
598             am.execute();
599             code = am.getReturnCode();
600             message = am.getResponseBodyAsString();
601         } else {
602             code = 500;
603             message = CANNOT_FIND_PRIVATE_KEY_STR + clientPrivatekey;
604         }
605         logger.info(code + "   " + message);
606         chefServerResult(rc, code, message);
607     }
608
609     /**
610      * Trigger target vm run chef
611      */
612     @Override
613     public void trigger(Map<String, String> params, SvcLogicContext ctx) {
614         logger.info("Run trigger method");
615         String tVmIp = params.get("ip");
616         RequestContext rc = new RequestContext(ctx);
617         rc.isAlive();
618
619         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
620             HttpGet httpGet = new HttpGet(tVmIp);
621             HttpResponse response = httpClient.execute(httpGet);
622             int responseCode = response.getStatusLine().getStatusCode();
623             HttpEntity entity = response.getEntity();
624             String responseOutput = EntityUtils.toString(entity);
625             chefClientResult(rc, responseCode, responseOutput);
626             doSuccess(rc);
627         } catch (Exception e) {
628             doFailure(rc, 500, e.toString());
629         }
630     }
631
632     @SuppressWarnings("nls")
633     @Override
634     public void checkPushJob(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
635         int code;
636         try {
637             chefInfo(params, ctx);
638             String jobID = params.get("jobid");
639             String retry = params.get("retryTimes");
640             String intrva = params.get("retryInterval");
641             if (StringUtils.isNotBlank(retry) && StringUtils.isNotBlank(intrva)) {
642
643                 int retryTimes = Integer.parseInt(params.get("retryTimes"));
644                 int retryInterval = Integer.parseInt(params.get("retryInterval"));
645
646                 String chefAction = "/pushy/jobs/" + jobID;
647
648                 RequestContext rc = new RequestContext(ctx);
649                 rc.isAlive();
650                 SvcLogicContext svcLogic = rc.getSvcLogicContext();
651                 String message = StringUtils.EMPTY;
652                 String status = StringUtils.EMPTY;
653                 for (int i = 0; i < retryTimes; i++) {
654                     sleepFor(retryInterval);
655                     ApiMethod am = getApiMethod(chefAction);
656                     code = am.getReturnCode();
657                     message = am.getResponseBodyAsString();
658                     JSONObject obj = new JSONObject(message);
659                     status = obj.getString("status");
660                     if (!"running".equals(status)) {
661                         logger.info(i + " time " + code + "   " + status);
662                         break;
663                     }
664                 }
665                 if ("complete".equals(status)) {
666                     svcLogic.setAttribute(CHEF_SERVER_RESULT_CODE_STR, "200");
667                     svcLogic.setAttribute(CHEF_SERVER_RESULT_MSG_STR, message);
668                 } else {
669                     if ("running".equals(status)) {
670                         svcLogic.setAttribute(CHEF_SERVER_RESULT_CODE_STR, "202");
671                         svcLogic.setAttribute(CHEF_SERVER_RESULT_MSG_STR, "chef client runtime out");
672                     } else {
673                         svcLogic.setAttribute(CHEF_SERVER_RESULT_CODE_STR, "500");
674                         svcLogic.setAttribute(CHEF_SERVER_RESULT_MSG_STR, message);
675                     }
676                 }
677             }
678             else {
679                 throw new SvcLogicException("Missing Mandatory param(s) retryTimes , retryInterval ");
680             }
681         } catch (Exception e) {
682             code = 401;
683             doFailure(ctx, code, e.getMessage());
684         }
685     }
686
687     private void sleepFor(int retryInterval) {
688         try {
689             Thread.sleep(retryInterval); // 1000 milliseconds is one second.
690         } catch (InterruptedException ex) {
691             Thread.currentThread().interrupt();
692         }
693     }
694
695     @SuppressWarnings("nls")
696     @Override
697     public void pushJob(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
698         int code;
699         try {
700             chefInfo(params, ctx);
701             String pushRequest = params.get("pushRequest");
702             String chefAction = "/pushy/jobs";
703             RequestContext rc = new RequestContext(ctx);
704             rc.isAlive();
705             SvcLogicContext svcLogic = rc.getSvcLogicContext();
706             ChefApiClient cac = new ChefApiClient(username, clientPrivatekey, chefserver, organizations);
707             ApiMethod am = cac.post(chefAction).body(pushRequest);
708
709             am.execute();
710             code = am.getReturnCode();
711             String message = am.getResponseBodyAsString();
712             if (code == 201) {
713                 int startIndex = message.indexOf("jobs") + 6;
714                 int endIndex = message.length() - 2;
715                 String jobID = message.substring(startIndex, endIndex);
716                 svcLogic.setAttribute("jobID", jobID);
717                 logger.info(jobID);
718             }
719             chefServerResult(rc, code, message);
720         } catch (Exception e) {
721             code = 401;
722             doFailure(ctx, code, e.getMessage());
723         }
724     }
725
726     @SuppressWarnings("static-method")
727     private void doFailure(RequestContext rc, int code, String message) {
728         SvcLogicContext svcLogic = rc.getSvcLogicContext();
729         String msg = (message == null) ? Integer.toString(code) : message;
730         if (msg.contains("\n")) {
731             msg = msg.substring(msg.indexOf("\n"));
732         }
733
734         String status;
735         try {
736             status = Integer.toString(code);
737         } catch (Exception e) {
738
739             status = "500";
740         }
741         svcLogic.setAttribute("chefAgent.code", status);
742         svcLogic.setAttribute("chefAgent.message", msg);
743     }
744
745     /**
746      * @param rc
747      *        The request context that manages the state and recovery of the
748      *        request for the life of its processing.
749      */
750     @SuppressWarnings("static-method")
751     private void doSuccess(RequestContext rc) {
752         SvcLogicContext svcLogic = rc.getSvcLogicContext();
753         svcLogic.setAttribute("chefAgent.code", "200");
754     }
755
756     @SuppressWarnings("static-method")
757     private void chefServerResult(RequestContext rc, int  code, String message) {
758       initSvcLogic(rc, code, message, "server");
759     }
760
761     @SuppressWarnings("static-method")
762     private void chefClientResult(RequestContext rc, int code, String message) {
763         initSvcLogic(rc, code, message, "client");
764     }
765
766     private void initSvcLogic(RequestContext rc, int code, String message, String target) {
767
768         SvcLogicContext svcLogic = rc.getSvcLogicContext();
769         String codeStr = "server".equals(target) ? CHEF_SERVER_RESULT_CODE_STR : CHEF_CLIENT_RESULT_CODE_STR;
770         String messageStr = "client".equals(target) ? CHEF_SERVER_RESULT_MSG_STR : CHEF_CLIENT_RESULT_MSG_STR;
771
772         svcLogic.setStatus(OUTCOME_SUCCESS);
773         svcLogic.setAttribute(codeStr, Integer.toString(code));
774         svcLogic.setAttribute(messageStr, message);
775         logger.info(codeStr + ": " + svcLogic.getAttribute(codeStr));
776         logger.info(messageStr + ": " + svcLogic.getAttribute(messageStr));
777     }
778
779
780     /**
781      * initialize the provider adapter by building the context cache
782      */
783     private void initialize() {
784
785         logger.info("Initialize Chef Adapter");
786     }
787
788     @SuppressWarnings("static-method")
789     private void doFailure(SvcLogicContext svcLogic, int code, String message) throws SvcLogicException {
790
791         String cutMessage = message.contains("\n") ? message.substring(message.indexOf('\n')) : message;
792
793         svcLogic.setStatus(OUTCOME_FAILURE);
794         svcLogic.setAttribute(CHEF_SERVER_RESULT_CODE_STR, Integer.toString(code));
795         svcLogic.setAttribute(CHEF_SERVER_RESULT_MSG_STR, cutMessage);
796
797         throw new SvcLogicException("Chef Adapter error:" + cutMessage);
798     }
799 }