Update gvnfm-driver .gitreview file
[vfc/nfvo/driver/vnfm/gvnfm.git] / juju / juju-vnfmadapter / Juju-vnfmadapterService / service / src / main / java / org / onap / vfc / nfvo / vnfm / gvnfm / jujuvnfmadapter / service / adapter / impl / JujuClientManager.java
1 /*
2  * Copyright 2016 Huawei Technologies Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.onap.vfc.nfvo.vnfm.gvnfm.jujuvnfmadapter.service.adapter.impl;
18
19 import java.io.*;
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.apache.commons.lang3.StringUtils;
26 import org.onap.vfc.nfvo.vnfm.gvnfm.jujuvnfmadapter.common.EntityUtils;
27 import org.onap.vfc.nfvo.vnfm.gvnfm.jujuvnfmadapter.common.FileUtils;
28 import org.onap.vfc.nfvo.vnfm.gvnfm.jujuvnfmadapter.common.JujuConfigUtil;
29 import org.onap.vfc.nfvo.vnfm.gvnfm.jujuvnfmadapter.common.YamlUtil;
30 import org.onap.vfc.nfvo.vnfm.gvnfm.jujuvnfmadapter.common.EntityUtils.ExeRes;
31 import org.onap.vfc.nfvo.vnfm.gvnfm.jujuvnfmadapter.common.servicetoken.VnfmRestfulUtil;
32 import org.onap.vfc.nfvo.vnfm.gvnfm.jujuvnfmadapter.service.adapter.inf.IJujuClientManager;
33 import org.onap.vfc.nfvo.vnfm.gvnfm.jujuvnfmadapter.service.constant.Constant;
34 import org.onap.vfc.nfvo.vnfm.gvnfm.jujuvnfmadapter.service.constant.UrlConstant;
35 import org.onap.vfc.nfvo.vnfm.gvnfm.jujuvnfmadapter.service.juju.JujuHelper;
36 import org.openo.baseservice.roa.util.restclient.RestfulResponse;
37 import org.openo.baseservice.util.impl.SystemEnvVariablesFactory;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 import net.sf.json.JSON;
42 import net.sf.json.JSONObject;
43
44
45 /**
46  * <br/>
47  * <p>
48  * </p>
49  * 
50  * @author        
51  * @version     NFVO 0.5  Sep 7, 2016
52  */
53 public class JujuClientManager implements IJujuClientManager {
54     private static final Logger LOG = LoggerFactory.getLogger(JujuClientManager.class);
55     
56     public static final String ADDRESOURCE="addResource";
57     public static final String REMOVERESOURCE = "removeResource";
58
59     /**
60      * <br/>
61      * 
62      * @param charmPath
63      * @param appName
64      * @return
65      * @since   NFVO 0.5
66      */
67     @Override
68     public JSONObject deploy(String charmPath, String appName) {
69         JSONObject result = new JSONObject();
70         if(charmPath == null || appName == null){
71             String msg = "the 'charmPath' or 'appName' can not be null";
72             result.put(EntityUtils.RESULT_CODE_KEY, -1);
73             result.put(EntityUtils.MSG_KEY, msg);
74             LOG.error(msg);
75             return result;
76         }
77         String modelName = JujuHelper.getModelName(appName);
78         //add-model
79         this.addModel(modelName);//use appName as modelName
80         //switch model
81         this.switchModel(modelName);
82         //deploy service
83         List<String> commands = new ArrayList<>();
84         commands.add("juju");
85         commands.add("deploy");
86         if(StringUtils.isNotBlank(charmPath)){
87             String fullPath = charmPath+appName;
88             commands.add(fullPath);
89         }else{
90             commands.add(appName);
91         }
92         commands.add("-m"); 
93         commands.add(modelName);
94         ExeRes exeRes = EntityUtils.execute(charmPath,commands);
95         if(exeRes.getCode() == ExeRes.SUCCESS){
96             LOG.info("deploy success. command:"+EntityUtils.formatCommand(commands));
97             result.put(EntityUtils.RESULT_CODE_KEY, 0);
98             result.put(EntityUtils.DATA_KEY, exeRes.getBody());
99         }else{
100             LOG.error("deploy failed. command:"+EntityUtils.formatCommand(commands)+"\n"+exeRes);
101             result.put(EntityUtils.RESULT_CODE_KEY, -1);
102             result.put(EntityUtils.MSG_KEY, "deploy failed:"+exeRes.getBody());
103         }
104         
105         return result;
106     }
107     
108     /**
109      * 
110      * <br/>
111      * 
112      * @param modelName
113      * @return
114      * @since  NFVO 0.5
115      */
116     private JSONObject addModel(String modelName) {
117         JSONObject result = new JSONObject();
118         List<String> commands = new ArrayList<>();
119         commands.add("juju");
120         commands.add("add-model");
121         commands.add(modelName);
122         getExtraParam(commands);
123         ExeRes exeRes = EntityUtils.execute(null,commands);
124         if(exeRes.getCode() == ExeRes.SUCCESS){
125             LOG.info("addModel success. command:"+EntityUtils.formatCommand(commands));
126             result.put(EntityUtils.RESULT_CODE_KEY, 0);
127             result.put(EntityUtils.DATA_KEY, exeRes.getBody());
128         }else{
129             LOG.error("addModel failed. command:"+EntityUtils.formatCommand(commands)+"\n"+exeRes);
130             result.put(EntityUtils.RESULT_CODE_KEY, -1);
131             result.put(EntityUtils.MSG_KEY, "addModel failed:"+exeRes.getBody());
132         }
133         
134         return result;
135     }
136
137     /**
138      * getExtraParam
139      * add model
140         juju add-model <model-name> --config image-metadata-url=http://192.168.20.106/images --config network=demo-net --config use-floating-ip=True --config use-default-secgroup=True
141      * @return
142      */
143     private void getExtraParam(List<String> commands){
144         try {
145             String configInfo = readJujuConfigInfo();
146             if(configInfo != null){
147                 JSONObject json = JSONObject.fromObject(configInfo);
148                 commands.add("--config");
149                 commands.add("image-metadata-url="+json.getString("image-metadata-url"));
150                 commands.add("--config");
151                 commands.add("network="+json.getString("network"));
152                 commands.add("--config");
153                 commands.add("use-floating-ip="+json.getString("use-floating-ip"));
154                 commands.add("--config");
155                 commands.add("use-default-secgroup="+json.getString("use-default-secgroup"));
156             }
157         } catch (Exception e) {
158             LOG.error("read juju command config error:",e);
159         }
160     }
161
162     /**
163      * Get csar package information.<br>
164      *
165      * @return
166      * @throws IOException
167      * @since  NFVO 0.5
168      */
169     public static String readJujuConfigInfo() {
170         InputStream ins = null;
171
172         BufferedInputStream bins = null;
173         String fileContent = null;
174         String fileName = SystemEnvVariablesFactory.getInstance().getAppRoot() + System.getProperty("file.separator")
175                 + "etc" + System.getProperty("file.separator") + "conf" + System.getProperty("file.separator")
176                 + "juju_conf.json";
177         try {
178             ins = new FileInputStream(fileName);
179             bins = new BufferedInputStream(ins);
180
181             byte[] contentByte = new byte[ins.available()];
182             int num = bins.read(contentByte);
183
184             if (num > 0) {
185                 fileContent = new String(contentByte);
186             }
187         } catch (Exception e) {
188             LOG.error(fileName + "is not found!", e);
189         } finally {
190             try {
191                 if (ins != null) {
192                     ins.close();
193                 }
194                 if (bins != null) {
195                     bins.close();
196                 }
197             } catch (IOException e) {
198             }
199         }
200         return fileContent;
201     }
202     private JSONObject changeDir(String charmPath) {
203         JSONObject result = new JSONObject();
204         List<String> commands = new ArrayList<>();
205         commands.add("cd");
206         commands.add(charmPath);
207         ExeRes exeRes = EntityUtils.execute(null,commands);
208         if(exeRes.getCode() == ExeRes.SUCCESS){
209             LOG.info("changeDir success. command:"+EntityUtils.formatCommand(commands));
210             result.put(EntityUtils.RESULT_CODE_KEY, 0);
211             result.put(EntityUtils.DATA_KEY, exeRes.getBody());
212         }else{
213             LOG.error("changeDir failed. command:"+EntityUtils.formatCommand(commands)+"\n"+exeRes);
214             result.put(EntityUtils.RESULT_CODE_KEY, -1);
215             result.put(EntityUtils.MSG_KEY, "addModel failed:"+exeRes.getBody());
216         }
217         
218         return result;
219     }
220     
221     /**
222      * 
223      * <br/>
224      * 
225      * @param modelName
226      * @return
227      * @since  NFVO 0.5
228      */
229     private JSONObject switchModel(String modelName) {
230         JSONObject result = new JSONObject();
231         List<String> commands = new ArrayList<>();
232         commands.add("juju");
233         commands.add("switch");
234         commands.add(modelName);
235         ExeRes exeRes = EntityUtils.execute(null,commands);
236         if(exeRes.getCode() == ExeRes.SUCCESS){
237             LOG.info("switchModel success. command:"+EntityUtils.formatCommand(commands));
238             result.put(EntityUtils.RESULT_CODE_KEY, 0);
239             result.put(EntityUtils.DATA_KEY, exeRes.getBody());
240         }else{
241             LOG.error("switchModel failed. command:"+EntityUtils.formatCommand(commands)+"\n"+exeRes);
242             result.put(EntityUtils.RESULT_CODE_KEY, -1);
243             result.put(EntityUtils.MSG_KEY, "addModel failed:"+exeRes.getBody());
244         }
245         
246         return result;
247     }
248
249     /**
250      * <br/>
251      * 
252      * @param appName
253      * @return
254      * @since   NFVO 0.5
255      */
256     @Override
257     public JSONObject destroy(String appName) {
258         String modelName = JujuHelper.getModelName(appName);
259         JSONObject result = new JSONObject();
260         List<String> commands = new ArrayList<>();
261         commands.add("juju");
262         commands.add("destroy-model");
263         commands.add("-y");
264         commands.add(modelName);
265         
266         ExeRes exeRes = EntityUtils.execute(null,commands);
267         if(exeRes.getCode() == ExeRes.SUCCESS){
268             LOG.info("remove success. command:"+EntityUtils.formatCommand(commands));
269             result.put(EntityUtils.RESULT_CODE_KEY, 0);
270             result.put(EntityUtils.DATA_KEY, exeRes.getBody());
271         }else{
272             LOG.error("remove failed. command:"+EntityUtils.formatCommand(commands)+"\n"+exeRes);
273             result.put(EntityUtils.RESULT_CODE_KEY, -1);
274             result.put(EntityUtils.MSG_KEY, "remove failed:"+exeRes.getBody());
275         }
276         
277         return result;
278        
279     }
280
281     /**
282      * <br/>
283      * 
284      * @param appName
285      * @return
286      * @since   NFVO 0.5
287      */
288     @Override
289     public JSONObject getStatus(String appName) {
290         String modelName = JujuHelper.getModelName(appName);
291         JSONObject result = new JSONObject();
292         List<String> commands = new ArrayList<>();
293         commands.add("juju");
294         commands.add("status");
295         if(StringUtils.isNotBlank(modelName)){
296             commands.add("-m"); 
297             commands.add(modelName);
298         }
299         commands.add("--format=json");
300         
301         ExeRes exeRes = EntityUtils.execute(null,commands);
302         if(exeRes.getCode() == ExeRes.SUCCESS){
303             LOG.info("getStatus success. command:"+EntityUtils.formatCommand(commands));
304             result.put(EntityUtils.RESULT_CODE_KEY, 0);
305             JSONObject dataObj = buildDataObj(exeRes);
306             result.put(EntityUtils.DATA_KEY, dataObj);
307         }else{
308             LOG.error("getStatus failed. command:"+EntityUtils.formatCommand(commands)+"\n"+exeRes);
309             result.put(EntityUtils.RESULT_CODE_KEY, -1);
310             result.put(EntityUtils.MSG_KEY, "getStatus failed:"+exeRes.getBody());
311         }
312         
313         return result;
314     }
315
316     /**
317      * <br/>
318      * 
319      * @param exeRes
320      * @return
321      * @since  NFVO 0.5
322      */
323     private JSONObject buildDataObj(ExeRes exeRes) {
324         JSONObject dataObj = null;
325         if(StringUtils.isNotBlank(exeRes.getBody())){
326             dataObj = JSONObject.fromObject(exeRes.getBody());
327             //according to appName to select
328         }
329         return dataObj;
330     }
331     
332     
333     /**
334      * call the juju vnfm to grant resource(disk,mem,cpu)
335      * <br/>
336      *  (fields:cpu,mem,disk,action(addResource/removeResource))
337      * @param vnfId
338      * @param appName
339      * @param action
340      * @since  NFVO 0.5
341      * @return
342      */
343     @Override
344     public boolean grantResource(String charmPath, String appName,String action , String vnfId){
345         //1.parse yaml file
346         JSONObject params;
347         try {
348             params = this.parseYaml(charmPath, appName, action);
349         } catch(Exception e) {
350             LOG.error("ParseYaml error,please check it.",e);
351             return false;
352         }
353         if(params == null){
354             LOG.error("ParseYaml fail,please check it.");
355             return false;
356         }
357         
358         //2. call grant service
359         String url = JujuConfigUtil.getValue("grant_jujuvnfm_url");
360         Map<String, String> paramsMap = new HashMap<>(6);
361         paramsMap.put("url", url);
362         paramsMap.put(Constant.METHOD_TYPE, Constant.PUT);
363         paramsMap.put("path", String.format(UrlConstant.REST_JUJU_VNFM_GRANT_URL,vnfId));
364         paramsMap.put(Constant.AUTH_MODE, Constant.AuthenticationMode.ANONYMOUS);
365         RestfulResponse rsp = VnfmRestfulUtil.getRemoteResponse(paramsMap, params.toString(), null);
366         if(rsp == null || rsp.getStatus() != Constant.HTTP_OK) {
367             LOG.error("function=grantResource, msg=send grantResource msg to juju-vnfm get wrong results");
368             return false;
369         }
370         //3.process result
371         String response = rsp.getResponseContent();
372         LOG.info("grant resource result:"+response);
373         return true;
374     }
375     
376     /**
377      * 
378      * <br/>
379      * "constraints":"arch=amd64 cpu-cores=1 cpu-power=100 mem=1740 root-disk=8192"
380      * @param charmPath
381      * @param appName
382      * @param action
383      * @return
384      * @since  NFVO 0.5
385      */
386     public JSONObject parseYaml(String charmPath, String appName,String action){
387         JSONObject compute = new JSONObject();
388         compute.put("action", action);
389         if(StringUtils.isBlank(charmPath)){
390             LOG.error("the charmPath can't be null! [in unzipFileAndParseYaml]");
391             return null;
392         }
393       //set default values for non 'yaml' type
394         if(!appName.endsWith(".yaml")){
395             compute.put("cpu", 4);
396             compute.put("mem", 2);
397             compute.put("disk", 40);
398             return compute;
399         }
400         String yaml = FileUtils.getFriendlyPath(charmPath)+appName;
401         File yamlFile = new File(yaml);
402         if(yamlFile.exists()){
403             JSON json = YamlUtil.yamlToJson(yamlFile.getAbsolutePath());
404             LOG.info(yaml+":\n"+json);
405             if(json.isArray()){
406                 LOG.error("the yaml file has error format,please check it!"+yamlFile);
407                 return null;
408             }
409             JSONObject jsonObj = (JSONObject)json;
410             JSONObject services = jsonObj.getJSONObject("services");
411             int cpu = 0;
412             int mem = 0;
413             int disk = 0;
414             for(Object key: services.keySet()){
415                 JSONObject app = services.getJSONObject(key.toString());
416                 if(app.containsKey("constraints")){
417                     String constraints = app.getString("constraints");
418                     String[] vals = constraints.split("\\s+");
419                     LOG.info(key+"="+constraints);
420                     for(String val : vals){
421                         String[] kv = val.split("=");
422                         if("cpu-cores".equals(kv[0]) && StringUtils.isNotBlank(kv[1])){
423                             cpu+=Integer.valueOf(kv[1]);
424                         }else if("mem".equals(kv[0]) && StringUtils.isNotBlank(kv[1])){
425                             mem+=Integer.valueOf(kv[1]);
426                         }else if("root-disk".equals(kv[0]) && StringUtils.isNotBlank(kv[1])){
427                             disk+=Integer.valueOf(kv[1]);
428                         }
429                     }
430                 }
431             }
432             compute.put("cpu", cpu);
433             compute.put("mem", mem);
434             compute.put("disk", disk);
435         }else{
436             LOG.error("the yaml file not exist!file="+yamlFile); 
437             return null;
438         }
439         LOG.info("parse yaml result-->"+compute);
440         return compute;
441     }
442
443   
444     public static void main(String[] args) {
445         JujuClientManager jujuClientManager = new JujuClientManager();
446         jujuClientManager.parseYaml("E:/workspace/openo-common-utils/src/org/openo/common/yaml", "test.yaml", "addResource");
447     }
448     
449 }