048d362d49fb349a3e466a4e1be6247b260db2da
[appc.git] / appc-adapters / appc-chef-adapter / appc-chef-adapter-bundle / src / main / java / org / openecomp / 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
25 package org.openecomp.appc.adapter.chef.impl;
26
27 import com.att.eelf.configuration.EELFLogger;
28 import com.att.eelf.configuration.EELFManager;
29 import org.apache.http.HttpEntity;
30 import org.apache.http.HttpResponse;
31 import org.apache.http.client.HttpClient;
32 import org.apache.http.client.methods.HttpGet;
33 import org.apache.http.impl.client.HttpClients;
34 import org.apache.http.util.EntityUtils;
35 import org.json.JSONObject;
36 import org.openecomp.appc.Constants;
37 import org.openecomp.appc.adapter.chef.ChefAdapter;
38 import org.openecomp.appc.adapter.chef.chefapi.ApiMethod;
39 import org.openecomp.appc.adapter.chef.chefclient.ChefApiClient;
40 import org.openecomp.appc.configuration.Configuration;
41 import org.openecomp.appc.configuration.ConfigurationFactory;
42 import org.openecomp.sdnc.sli.SvcLogicContext;
43
44 import java.io.File;
45 import java.util.Map;
46
47 /**
48  * This class implements the {@link ChefAdapter} interface. This interface
49  * defines the behaviors that our service provides.
50  */
51 public class ChefAdapterImpl implements ChefAdapter {
52     //chef server Initialize variable
53     private String clientName="";
54     private String clientPrivatekey="";
55     private String chefserver="";
56     private String serverAddress="";
57     private String organizations="";
58
59     /**
60      * The constant for the status code for a successful outcome
61      */
62     private static final String OUTCOME_SUCCESS = "success";
63
64     /**
65      * The logger to be used
66      */
67     private final EELFLogger logger = EELFManager.getInstance().getLogger(ChefAdapterImpl.class);
68
69     /**
70      * A reference to the adapter configuration object.
71      */
72     private Configuration configuration;
73
74     /**
75      * This default constructor is used as a work around because the activator
76      * wasnt getting called
77      */
78     public ChefAdapterImpl() {
79         initialize();
80
81     }
82
83     /**
84      * This constructor is used primarily in the test cases to bypass
85      * initialization of the adapter for isolated, disconnected testing
86      *
87      * @param initialize
88      *            True if the adapter is to be initialized, can false if not
89      */
90     public ChefAdapterImpl(boolean initialize) {
91         configuration = ConfigurationFactory.getConfiguration();
92         if (initialize) {
93             initialize();
94
95         }
96     }
97
98     public ChefAdapterImpl(String key) {
99         initialize(key);
100
101     }
102
103     /**
104      * Returns the symbolic name of the adapter
105      *
106      * @return The adapter name
107      * @see org.openecomp.appc.adapter.chef.ChefAdapter#getAdapterName()
108      */
109     @Override
110     public String getAdapterName() {
111         return configuration.getProperty(Constants.PROPERTY_ADAPTER_NAME);
112     }
113
114     private void X__________________________________X() {
115     }
116
117     /**
118      * @see org.openecomp.appc.adapter.chef.ChefAdapter#evacuateServer(java.util.Map,
119      *      org.openecomp.sdnc.sli.SvcLogicContext)
120      */
121
122     private void X___________________________________X() {
123     }
124
125     /**
126      * @see org.openecomp.appc.adapter.chef.ProviderAdapter#rebuildServer(java.util.Map,
127      *      org.openecomp.sdnc.sli.SvcLogicContext)
128      */
129
130
131     /**
132      * build node object
133      */
134
135     @SuppressWarnings("nls")
136     @Override
137     public void nodeObejctBuilder(Map<String, String> params, SvcLogicContext ctx) {
138         logger.info("nodeObejctBuilder");
139         String name = params.get("org.openecomp.appc.instance.nodeobject.name");
140         String normal = params.get("org.openecomp.appc.instance.nodeobject.normal");
141         String overrides = params.get("org.openecomp.appc.instance.nodeobject.overrides");
142         String defaults = params.get("org.openecomp.appc.instance.nodeobject.defaults");
143         String run_list = params.get("org.openecomp.appc.instance.nodeobject.run_list");
144         String chef_environment = params.get("org.openecomp.appc.instance.nodeobject.chef_environment");
145         String nodeObject = "{\"json_class\":\"Chef::Node\",\"default\":{" + defaults
146             + "},\"chef_type\":\"node\",\"run_list\":[" + run_list + "],\"override\":{" + overrides
147             + "},\"normal\": {" + normal + "},\"automatic\":{},\"name\":\"" + name + "\",\"chef_environment\":\""
148             + chef_environment + "\"}";
149         logger.info(nodeObject);
150
151         RequestContext rc = new RequestContext(ctx);
152         rc.isAlive();
153         SvcLogicContext svcLogic = rc.getSvcLogicContext();
154         svcLogic.setAttribute("org.openecomp.appc.chef.nodeObject", nodeObject);
155
156     }
157
158     /**
159      * Nicolas send get request to chef server
160      */
161     public void chefInfo(Map<String, String> params) {
162         clientName = params.get("org.openecomp.appc.instance.username");
163         serverAddress = params.get("org.openecomp.appc.instance.serverAddress");
164         organizations = params.get("org.openecomp.appc.instance.organizations");
165         chefserver = "https://" + serverAddress + "/organizations/" + organizations;
166         clientPrivatekey = "/opt/app/bvc/chef/" + serverAddress + "/" + organizations + "/" + clientName + ".pem";
167     }
168
169     public Boolean privateKeyCheck() {
170         File f = new File(clientPrivatekey);
171         return f.exists();
172     }
173
174     @SuppressWarnings("nls")
175     @Override
176     public void retrieveData(Map<String, String> params, SvcLogicContext ctx) {
177         String allConfigData = params.get("org.openecomp.appc.instance.allConfig");
178         String key = params.get("org.openecomp.appc.instance.key");
179         String dgContext = params.get("org.openecomp.appc.instance.dgContext");
180         JSONObject josnConfig = new JSONObject(allConfigData);
181
182         String contextData;
183         try {
184             contextData = josnConfig.getString(key);
185         } catch (Exception ex) {
186             try {
187                 contextData = josnConfig.getJSONObject(key).toString();
188             } catch (Exception exc) {
189                 contextData = josnConfig.getJSONArray(key).toString();
190             }
191         }
192
193         RequestContext rc = new RequestContext(ctx);
194         rc.isAlive();
195         SvcLogicContext svcLogic = rc.getSvcLogicContext();
196         svcLogic.setAttribute(dgContext, contextData);
197     }
198
199     @SuppressWarnings("nls")
200     @Override
201     public void combineStrings(Map<String, String> params, SvcLogicContext ctx) {
202
203         String String1 = params.get("org.openecomp.appc.instance.String1");
204         String String2 = params.get("org.openecomp.appc.instance.String2");
205         String dgContext = params.get("org.openecomp.appc.instance.dgContext");
206         String contextData = String1 + String2;
207         RequestContext rc = new RequestContext(ctx);
208         rc.isAlive();
209         SvcLogicContext svcLogic = rc.getSvcLogicContext();
210         svcLogic.setAttribute(dgContext, contextData);
211     }
212
213
214     /**
215      * Send GET request to chef server
216      */
217
218     @SuppressWarnings("nls")
219     @Override
220     public void chefGet(Map<String, String> params, SvcLogicContext ctx) {
221         logger.info("chef get method");
222         chefInfo(params);
223         String chefAction = params.get("org.openecomp.appc.instance.chefAction");
224         RequestContext rc = new RequestContext(ctx);
225         rc.isAlive();
226         int code;
227         String message;
228         if (privateKeyCheck()) {
229             ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
230             ApiMethod am = cac.get(chefAction);
231             am.execute();
232             code = am.getReturnCode();
233             message = am.getResponseBodyAsString();
234         } else {
235             code = 500;
236             message = "Cannot find the private key in the APPC file system, please load the private key to "
237                 + clientPrivatekey;
238         }
239         chefServerResult(rc, Integer.toString(code), message);
240
241     }
242
243     /**
244      * Send PUT request to chef server
245      */
246     @SuppressWarnings("nls")
247     @Override
248     public void chefPut(Map<String, String> params, SvcLogicContext ctx) {
249         chefInfo(params);
250         String chefAction = params.get("org.openecomp.appc.instance.chefAction");
251         String CHEF_NODE_STR = params.get("org.openecomp.appc.instance.chefRequestBody");
252         RequestContext rc = new RequestContext(ctx);
253         rc.isAlive();
254         int code;
255         String message;
256         if (privateKeyCheck()) {
257             ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
258
259             ApiMethod am = cac.put(chefAction).body(CHEF_NODE_STR);
260             am.execute();
261             code = am.getReturnCode();
262             message = am.getResponseBodyAsString();
263         } else {
264             code = 500;
265             message = "Cannot find the private key in the APPC file system, please load the private key to "
266                 + clientPrivatekey;
267         }
268         logger.info(code + "   " + message);
269         chefServerResult(rc, Integer.toString(code), message);
270
271     }
272
273     /**
274      * Nicolas send Post request to chef server
275      */
276
277     @SuppressWarnings("nls")
278     @Override
279     public void chefPost(Map<String, String> params, SvcLogicContext ctx) {
280         chefInfo(params);
281         logger.info("chef Post method");
282         logger.info(clientName + " " + clientPrivatekey + " " + chefserver + " " + organizations);
283         String CHEF_NODE_STR = params.get("org.openecomp.appc.instance.chefRequestBody");
284         String chefAction = params.get("org.openecomp.appc.instance.chefAction");
285
286         RequestContext rc = new RequestContext(ctx);
287         rc.isAlive();
288         int code;
289         String message;
290         // should load pem from somewhere else
291         if (privateKeyCheck()) {
292             ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
293
294             // need pass path into it
295             // "/nodes/testnode"
296             ApiMethod am = cac.post(chefAction).body(CHEF_NODE_STR);
297             am.execute();
298             code = am.getReturnCode();
299             message = am.getResponseBodyAsString();
300         } else {
301             code = 500;
302             message = "Cannot find the private key in the APPC file system, please load the private key to "
303                 + clientPrivatekey;
304         }
305         logger.info(code + "   " + message);
306         chefServerResult(rc, Integer.toString(code), message);
307     }
308
309     /**
310      * Nicolas send delete request to chef server
311      */
312
313     @SuppressWarnings("nls")
314     @Override
315     public void chefDelete(Map<String, String> params, SvcLogicContext ctx) {
316         logger.info("chef delete method");
317         chefInfo(params);
318         String chefAction = params.get("org.openecomp.appc.instance.chefAction");
319         RequestContext rc = new RequestContext(ctx);
320         rc.isAlive();
321         int code;
322         String message;
323         if (privateKeyCheck()) {
324             ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
325             ApiMethod am = cac.delete(chefAction);
326             am.execute();
327             code = am.getReturnCode();
328             message = am.getResponseBodyAsString();
329         } else {
330             code = 500;
331             message = "Cannot find the private key in the APPC file system, please load the private key to "
332                 + clientPrivatekey;
333         }
334         logger.info(code + "   " + message);
335         chefServerResult(rc, Integer.toString(code), message);
336     }
337
338
339     /**
340      * Trigger target vm run chef
341      */
342
343     @SuppressWarnings("nls")
344     @Override
345     public void trigger(Map<String, String> params, SvcLogicContext ctx) {
346         logger.info("Run trigger method");
347         String tVmIp = params.get("org.openecomp.appc.instance.ip");
348         //String tUrl = "http://" + tVmIp;
349         RequestContext rc = new RequestContext(ctx);
350         rc.isAlive();
351
352         try {
353             HttpGet httpGet = new HttpGet(tVmIp);
354             HttpClient httpClient = HttpClients.createDefault();
355             HttpResponse response;
356             response = httpClient.execute(httpGet);
357             int responseCode=response.getStatusLine().getStatusCode();
358             HttpEntity entity = response.getEntity();
359             String responseOutput=EntityUtils.toString(entity);
360             chefClientResult(rc,Integer.toString(responseCode),responseOutput);
361             doSuccess(rc);
362         } catch (Exception ex) {
363             doFailure(rc, 500 , ex.toString());
364         }
365     }
366
367
368     @SuppressWarnings("nls")
369     @Override
370     public void checkPushJob(Map<String, String> params, SvcLogicContext ctx) {
371         chefInfo(params);
372         String jobID = params.get("org.openecomp.appc.instance.jobid");
373         int retryTimes = Integer.parseInt(params.get("org.openecomp.appc.instance.retryTimes"));
374         int retryInterval = Integer.parseInt(params.get("org.openecomp.appc.instance.retryInterval"));
375         String chefAction = "/pushy/jobs/" + jobID;
376
377         RequestContext rc = new RequestContext(ctx);
378         rc.isAlive();
379         SvcLogicContext svcLogic = rc.getSvcLogicContext();
380         String message = "";
381         String status = "";
382         for (int i = 0; i < retryTimes; i++) {
383             try {
384                 Thread.sleep(retryInterval); // 1000 milliseconds is one second.
385             } catch (InterruptedException ex) {
386                 Thread.currentThread().interrupt();
387             }
388             ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
389             ApiMethod am = cac.get(chefAction);
390             am.execute();
391             int code = am.getReturnCode();
392             message = am.getResponseBodyAsString();
393             JSONObject obj = new JSONObject(message);
394             status = obj.getString("status");
395             if (!status.equals("running")) {
396                 logger.info(i + " time " + code + "   " + status);
397                 break;
398             }
399
400         }
401         if (status.equals("complete")) {
402             svcLogic.setAttribute("org.openecomp.appc.chefServerResult.code", "200");
403             svcLogic.setAttribute("org.openecomp.appc.chefServerResult.message", message);
404         } else {
405             if (status.equals("running")) {
406                 svcLogic.setAttribute("org.openecomp.appc.chefServerResult.code", "202");
407                 svcLogic.setAttribute("org.openecomp.appc.chefServerResult.message", "chef client runtime out");
408             } else {
409                 svcLogic.setAttribute("org.openecomp.appc.chefServerResult.code", "500");
410                 svcLogic.setAttribute("org.openecomp.appc.chefServerResult.message", message);
411             }
412         }
413     }
414
415
416     @SuppressWarnings("nls")
417     @Override
418     public void pushJob(Map<String, String> params, SvcLogicContext ctx) {
419         chefInfo(params);
420         String pushRequest = params.get("org.openecomp.appc.instance.pushRequest");
421         String chefAction = "/pushy/jobs";
422         RequestContext rc = new RequestContext(ctx);
423         rc.isAlive();
424         SvcLogicContext svcLogic = rc.getSvcLogicContext();
425         ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations);
426         ApiMethod am = cac.post(chefAction).body(pushRequest);
427
428         am.execute();
429         int code = am.getReturnCode();
430         String message = am.getResponseBodyAsString();
431         if (code == 201) {
432             int startIndex = message.indexOf("jobs") + 6;
433             int endIndex = message.length() - 2;
434             String jobID = message.substring(startIndex, endIndex);
435             svcLogic.setAttribute("org.openecomp.appc.jobID", jobID);
436             logger.info(jobID);
437         }
438         chefServerResult(rc, Integer.toString(code), message);
439     }
440
441
442     @SuppressWarnings("static-method")
443     private void doFailure(RequestContext rc, int code, String message) {
444         SvcLogicContext svcLogic = rc.getSvcLogicContext();
445         String msg = (message == null) ? Integer.toString(code) : message;
446         if (msg.contains("\n")) {
447             msg = msg.substring(msg.indexOf("\n"));
448         }
449
450         String status;
451         try {
452             status = Integer.toString(code);
453         } catch (Exception e) {
454             status = "500";
455         }
456         svcLogic.setAttribute("org.openecomp.appc.chefAgent.code", status);
457         svcLogic.setAttribute("org.openecomp.appc.chefAgent.message", msg);
458     }
459
460     /**
461      * @param rc
462      *            The request context that manages the state and recovery of the
463      *            request for the life of its processing.
464      */
465
466     @SuppressWarnings("static-method")
467     private void doSuccess(RequestContext rc) {
468         SvcLogicContext svcLogic = rc.getSvcLogicContext();
469         svcLogic.setAttribute("org.openecomp.appc.chefAgent.code", "200");
470     }
471
472
473     @SuppressWarnings("static-method")
474     private void chefServerResult(RequestContext rc, String code ,String message) {
475         SvcLogicContext svcLogic = rc.getSvcLogicContext();
476         svcLogic.setStatus(OUTCOME_SUCCESS);
477         svcLogic.setAttribute("org.openecomp.appc.chefServerResult.code", code);
478         svcLogic.setAttribute("org.openecomp.appc.chefServerResult.message", message);
479     }
480
481     @SuppressWarnings("static-method")
482     private void chefClientResult(RequestContext rc, String code ,String message) {
483         SvcLogicContext svcLogic = rc.getSvcLogicContext();
484         svcLogic.setStatus(OUTCOME_SUCCESS);
485         svcLogic.setAttribute("org.openecomp.appc.chefClientResult.code", code);
486         svcLogic.setAttribute("org.openecomp.appc.chefClientResult.message", message);
487     }
488
489     /**
490      * initialize the provider adapter by building the context cache
491      */
492     private void initialize() {
493         configuration = ConfigurationFactory.getConfiguration();
494         //need to fetch data from appc configurator or form some file in the appc vms
495         clientName="testnode";
496         clientPrivatekey="/etc/chef/client.pem";
497         serverAddress="http://example.com";
498         organizations="test";
499         chefserver=serverAddress+"/organizations/"+organizations;
500         logger.info("Initialize Chef Adapter");
501     }
502
503     private void initialize(String key) {
504         configuration = ConfigurationFactory.getConfiguration();
505         //need to fetch data from appc configurator or form some file in the appc vms
506         clientName="testnode";
507         clientPrivatekey=key;
508         serverAddress="http://example.com";
509         organizations="test";
510         chefserver=serverAddress+"/organizations/"+organizations;
511         logger.info("Initialize Chef Adapter");
512     }
513
514 }