88a5ba47039f13b1b0650d77283ae30a9992ba88
[vfc/nfvo/catalog.git] /
1 /**
2  * Copyright 2016 [ZTE] and others.
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.openo.commontosca.catalog.model.parser.yaml.zte;
18
19 import org.openo.commontosca.catalog.common.MsbAddrConfig;
20 import org.openo.commontosca.catalog.common.ToolUtil;
21 import org.openo.commontosca.catalog.db.exception.CatalogResourceException;
22 import org.openo.commontosca.catalog.db.resource.TemplateManager;
23 import org.openo.commontosca.catalog.entity.response.CsarFileUriResponse;
24 import org.openo.commontosca.catalog.model.common.TemplateDataHelper;
25 import org.openo.commontosca.catalog.model.entity.EnumDataType;
26 import org.openo.commontosca.catalog.model.entity.InputParameter;
27 import org.openo.commontosca.catalog.model.entity.NodeTemplate;
28 import org.openo.commontosca.catalog.model.entity.OutputParameter;
29 import org.openo.commontosca.catalog.model.entity.RelationShip;
30 import org.openo.commontosca.catalog.model.entity.ServiceTemplate;
31 import org.openo.commontosca.catalog.model.entity.ServiceTemplateOperation;
32 import org.openo.commontosca.catalog.model.entity.SubstitutionMapping;
33 import org.openo.commontosca.catalog.model.parser.AbstractModelParser;
34 import org.openo.commontosca.catalog.model.parser.EnumTemplateType;
35 import org.openo.commontosca.catalog.model.parser.yaml.zte.entity.EnumYamlServiceTemplateInfo;
36 import org.openo.commontosca.catalog.model.parser.yaml.zte.entity.ParseYamlRequestParemeter;
37 import org.openo.commontosca.catalog.model.parser.yaml.zte.entity.ParseYamlResult;
38 import org.openo.commontosca.catalog.model.parser.yaml.zte.entity.ParseYamlResult.Plan;
39 import org.openo.commontosca.catalog.model.parser.yaml.zte.entity.ParseYamlResult.Plan.PlanValue.PlanInput;
40 import org.openo.commontosca.catalog.model.parser.yaml.zte.entity.ParseYamlResult.TopologyTemplate.Input;
41 import org.openo.commontosca.catalog.model.parser.yaml.zte.entity.ParseYamlResult.TopologyTemplate.Output;
42 import org.openo.commontosca.catalog.model.parser.yaml.zte.entity.ParseYamlResult.TopologyTemplate.NodeTemplate.Relationship;
43 import org.openo.commontosca.catalog.model.parser.yaml.zte.service.YamlParseServiceConsumer;
44 import org.openo.commontosca.catalog.model.plan.wso2.Wso2ServiceConsumer;
45 import org.openo.commontosca.catalog.model.plan.wso2.entity.DeployPackageResponse;
46 import org.openo.commontosca.catalog.wrapper.PackageWrapper;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 import java.io.BufferedInputStream;
51 import java.io.BufferedReader;
52 import java.io.File;
53 import java.io.FileInputStream;
54 import java.io.IOException;
55 import java.io.InputStream;
56 import java.io.InputStreamReader;
57 import java.util.ArrayList;
58 import java.util.HashMap;
59 import java.util.List;
60 import java.util.Map;
61 import java.util.zip.ZipEntry;
62 import java.util.zip.ZipFile;
63 import java.util.zip.ZipInputStream;
64
65
66 public class ToscaYamlModelParser extends AbstractModelParser {
67
68   private static final Object TOSCA_META_FIELD_ENTRY_DEFINITIONS = "Entry-Definitions";
69   private static final Logger LOGGER = LoggerFactory.getLogger(ToscaYamlModelParser.class);
70
71   @Override
72   public String parse(String packageId, String fileLocation) throws CatalogResourceException {
73     ParseYamlResult result = getParseYamlResult(fileLocation);
74     
75     Map<String, String> toscaMeta = parseToscaMeta(fileLocation);
76     String stFileName = toscaMeta.get(TOSCA_META_FIELD_ENTRY_DEFINITIONS);
77     CsarFileUriResponse stDownloadUri =
78         PackageWrapper.getInstance().getCsarFileDownloadUri(packageId, stFileName);
79
80     ServiceTemplate st = parseServiceTemplate(packageId, result, stDownloadUri.getDownloadUri());
81     ServiceTemplateOperation[] operations = parseOperations(result.getPlanList(), fileLocation);
82     st.setOperations(operations);
83     List<NodeTemplate> ntList = parseNodeTemplates(packageId, st.getServiceTemplateId(), result);
84     st.setType(getTemplateType(result, ntList).toString());
85
86     TemplateManager.getInstance().addServiceTemplate(
87         TemplateDataHelper.convert2TemplateData(st, ToolUtil.toJson(result), ntList));
88
89     SubstitutionMapping stm = parseSubstitutionMapping(st.getServiceTemplateId(), result);
90     if (stm != null) {
91       TemplateManager.getInstance()
92           .addServiceTemplateMapping(TemplateDataHelper.convert2TemplateMappingData(stm));
93     }
94
95     return st.getServiceTemplateId();
96   }
97
98   private ParseYamlResult getParseYamlResult(String fileLocation) throws CatalogResourceException {
99     String destPath = copyTemporaryFile2HttpServer(fileLocation);
100     try {
101       String url = getUrl(toTempFileLocalPath(fileLocation));
102       return YamlParseServiceConsumer.getServiceTemplates(comboRequest(url));
103     } finally {
104       if (destPath != null && !destPath.isEmpty() && (new File(destPath)).exists()) {
105         (new File(destPath)).delete();
106       }
107     }
108   }
109
110   private String toTempFileLocalPath(String fileLocation) {
111     return File.separator + "temp" + File.separator + (new File(fileLocation)).getName();
112   }
113   
114   private String getUrl(String uri) {
115     String url = null;
116     if ((MsbAddrConfig.getMsbAddress().endsWith("/")) && uri.startsWith("/")) {
117       url = MsbAddrConfig.getMsbAddress() + uri.substring(1);
118     }
119     url = MsbAddrConfig.getMsbAddress() + uri;
120     String urlresult = url.replace("\\", "/");
121     return urlresult;
122   }
123
124   private String copyTemporaryFile2HttpServer(String fileLocation) throws CatalogResourceException {
125     String destPath = Class.class.getClass().getResource("/").getPath()
126         + org.openo.commontosca.catalog.filemanage.http.ToolUtil.getHttpServerPath()
127         + toTempFileLocalPath(fileLocation);
128     if (!org.openo.commontosca.catalog.filemanage.http.ToolUtil.copyFile(fileLocation, destPath,
129         true)) {
130       throw new CatalogResourceException("Copy Temporary To HttpServer Failed.");
131     }
132     return destPath;
133   }
134
135   @SuppressWarnings("resource")
136   private Map<String, String> parseToscaMeta(String fileLocation) throws CatalogResourceException {
137     Map<String, String> toscaMeta = new HashMap<>();
138
139     ZipInputStream zin = null;
140     BufferedReader br = null;
141     try {
142       InputStream in = new BufferedInputStream(new FileInputStream(fileLocation));
143       zin = new ZipInputStream(in);
144       ZipEntry ze;
145       while ((ze = zin.getNextEntry()) != null) {
146         if (("TOSCA-Metadata" + File.separator + "TOSCA.meta").equals(ze.getName())
147             || "TOSCA-Metadata/TOSCA.meta".equals(ze.getName())) {
148           ZipFile zf = new ZipFile(fileLocation);
149           br = new BufferedReader(new InputStreamReader(zf.getInputStream(ze)));
150           String line;
151           String[] tmps;
152           while ((line = br.readLine()) != null) {
153             if (line.indexOf(":") > 0) {
154               tmps = line.split(":");
155               toscaMeta.put(tmps[0].trim(), tmps[1].trim());
156             }
157           }
158
159           return toscaMeta;
160         }
161       }
162
163     } catch (IOException e1) {
164       throw new CatalogResourceException("Parse Tosca Meta Fail.", e1);
165     } finally {
166       closeStreamAndReader(zin, br);
167     }
168
169     return toscaMeta;
170   }
171
172   private void closeStreamAndReader(ZipInputStream zin, BufferedReader br) {
173     if (br != null) {
174       try {
175         br.close();
176       } catch (IOException e1) {
177         LOGGER.error("Buffered reader close failed !");
178       }
179     }
180     if (zin != null) {
181       try {
182         zin.closeEntry();
183       } catch (IOException e2) {
184         LOGGER.error("Zip inputStream close failed !");
185       }
186     }
187   }
188
189   private ParseYamlRequestParemeter comboRequest(String fileLocation) {
190     ParseYamlRequestParemeter request = new ParseYamlRequestParemeter();
191     request.setPath(fileLocation);
192     return request;
193   }
194
195   private SubstitutionMapping parseSubstitutionMapping(String serviceTemplateId,
196       ParseYamlResult result) {
197     String type = getSubstitutionMappingType(result);
198     if (ToolUtil.isTrimedEmptyString(type)) {
199       return null;
200     }
201
202     org.openo.commontosca.catalog.model.parser.yaml.zte.entity.ParseYamlResult
203         .TopologyTemplate.SubstitutionMapping stm =
204         result.getTopologyTemplate().getSubstitutionMappings();
205     return new SubstitutionMapping(serviceTemplateId, type, stm.getRequirementList(),
206         stm.getCapabilityList());
207   }
208
209   private ServiceTemplate parseServiceTemplate(String packageId, ParseYamlResult result,
210       String stDownloadUri) {
211     ServiceTemplate st = new ServiceTemplate();
212
213     st.setServiceTemplateId(ToolUtil.generateId());
214     st.setTemplateName(result.getMetadata().get(EnumYamlServiceTemplateInfo.ID.getName()));
215     st.setVendor(result.getMetadata().get(EnumYamlServiceTemplateInfo.PROVIDER.getName()));
216     st.setVersion(result.getMetadata().get(EnumYamlServiceTemplateInfo.VERSION.getName()));
217     st.setCsarid(packageId);
218     st.setDownloadUri(stDownloadUri);
219     st.setInputs(parseInputs(result));
220     st.setOutputs(parseOutputs(result));
221     return st;
222   }
223
224   private InputParameter[] parseInputs(ParseYamlResult result) {
225     List<Input> inputList = result.getTopologyTemplate().getInputs();
226     if (inputList == null) {
227       return new InputParameter[0];
228     }
229     List<InputParameter> retList = new ArrayList<InputParameter>();
230     for (Input input : inputList) {
231       retList.add(new InputParameter(input.getName(), getEnumDataType(input.getType()),
232           input.getDescription(), input.getDefault(), input.isRequired()));
233     }
234     return retList.toArray(new InputParameter[0]);
235   }
236
237   private OutputParameter[] parseOutputs(ParseYamlResult result) {
238     List<Output> outputList = result.getTopologyTemplate().getOutputs();
239     if (outputList == null || outputList.isEmpty()) {
240       return new OutputParameter[0];
241     }
242     List<OutputParameter> retList = new ArrayList<OutputParameter>();
243     for (Output output : outputList) {
244       retList
245           .add(new OutputParameter(output.getName(), output.getDescription(), output.getValue()));
246     }
247     return retList.toArray(new OutputParameter[0]);
248   }
249
250   private ServiceTemplateOperation[] parseOperations(List<Plan> planList, String zipFileLocation)
251       throws CatalogResourceException {
252     if (planList == null || planList.isEmpty()) {
253       return new ServiceTemplateOperation[0];
254     }
255
256     List<ServiceTemplateOperation> opList = new ArrayList<>();
257     for (Plan plan : planList) {
258       ServiceTemplateOperation op = new ServiceTemplateOperation();
259       op.setName(plan.getName());
260       op.setDescription(plan.getDescription());
261       checkPlanLanguage(plan.getPlanLanguage());
262       DeployPackageResponse response =
263           Wso2ServiceConsumer.deployPackage(zipFileLocation, plan.getReference());
264       op.setPackageName(parsePackageName(response));
265       op.setProcessId(response.getProcessId());
266       op.setInputs(parsePlanInputs(plan.getInputList()));
267
268       opList.add(op);
269
270     }
271     return opList.toArray(new ServiceTemplateOperation[0]);
272   }
273
274   private String parsePackageName(DeployPackageResponse response) {
275     String packageName = response.getPackageName();
276     if (packageName != null && packageName.indexOf("-") > 0) {
277       packageName = packageName.substring(0, packageName.lastIndexOf("-"));
278     }
279     return packageName;
280   }
281
282   private void checkPlanLanguage(String planLanguage) throws CatalogResourceException {
283     if (planLanguage == null || planLanguage.isEmpty()) {
284       throw new CatalogResourceException("Plan Language is empty.");
285     }
286     if (planLanguage.equalsIgnoreCase("bpel")) {
287       return;
288     }
289     if (planLanguage.equalsIgnoreCase("bpmn")) {
290       return;
291     }
292     if (planLanguage.equalsIgnoreCase("bpmn4tosca")) {
293       return;
294     }
295     throw new CatalogResourceException(
296         "Plan Language is not supported. Language = " + planLanguage);
297   }
298
299   private InputParameter[] parsePlanInputs(List<PlanInput> inputList) {
300     if (inputList == null || inputList.isEmpty()) {
301       return new InputParameter[0];
302     }
303
304     List<InputParameter> retList = new ArrayList<>();
305     for (PlanInput input : inputList) {
306       retList.add(new InputParameter(input.getName(), getEnumDataType(input.getType()),
307           input.getDescription(), input.getDefault(), input.isRequired()));
308     }
309     return retList.toArray(new InputParameter[0]);
310   }
311
312   private EnumDataType getEnumDataType(String type) {
313     if (EnumDataType.INTEGER.toString().equalsIgnoreCase(type)) {
314       return EnumDataType.INTEGER;
315     }
316
317     if (EnumDataType.FLOAT.toString().equalsIgnoreCase(type)) {
318       return EnumDataType.FLOAT;
319     }
320
321     if (EnumDataType.BOOLEAN.toString().equalsIgnoreCase(type)) {
322       return EnumDataType.BOOLEAN;
323     }
324
325     return EnumDataType.STRING;
326   }
327
328   private List<NodeTemplate> parseNodeTemplates(String csarId, String templateId,
329       ParseYamlResult result) {
330     List<ParseYamlResult.TopologyTemplate.NodeTemplate> nodetemplateList =
331         result.getTopologyTemplate().getNodeTemplates();
332     if (nodetemplateList == null) {
333       return null;
334     }
335
336     List<NodeTemplate> retList = new ArrayList<>();
337     for (ParseYamlResult.TopologyTemplate.NodeTemplate nodeTemplate : nodetemplateList) {
338       NodeTemplate ret = new NodeTemplate();
339       ret.setId(nodeTemplate.getName());
340       ret.setName(nodeTemplate.getName());
341       ret.setType(nodeTemplate.getNodeType());
342       ret.setProperties(nodeTemplate.getPropertyList());
343       List<RelationShip> relationShipList =
344           parseNodeTemplateRelationShip(nodeTemplate.getRelationships());
345       ret.setRelationShips(relationShipList);
346
347       retList.add(ret);
348     }
349
350     return retList;
351   }
352
353
354   private List<RelationShip> parseNodeTemplateRelationShip(List<Relationship> relationshipList) {
355     List<RelationShip> retList = new ArrayList<>();
356
357     if (relationshipList == null) {
358       return retList;
359     }
360
361     for (Relationship relationship : relationshipList) {
362       RelationShip ret = new RelationShip();
363       ret.setSourceNodeId(relationship.getSourceNodeName());
364       ret.setSourceNodeName(relationship.getSourceNodeName());
365       ret.setTargetNodeId(relationship.getTargetNodeName());
366       ret.setTargetNodeName(relationship.getTargetNodeName());
367       ret.setType(relationship.getType());
368       retList.add(ret);
369     }
370
371     return retList;
372   }
373
374   private EnumTemplateType getTemplateType(ParseYamlResult result, List<NodeTemplate> ntList) {
375     String type = getSubstitutionMappingType(result);
376     if (isNsType(type)) {
377       return EnumTemplateType.NS;
378     }
379
380     if (isVnfType(type)) {
381       return EnumTemplateType.VNF;
382     }
383
384     return getTemplateTypeFromNodeTemplates(ntList);
385   }
386
387   private String getSubstitutionMappingType(ParseYamlResult result) {
388     if (result.getTopologyTemplate().getSubstitutionMappings() == null) {
389       return null;
390     }
391     return result.getTopologyTemplate().getSubstitutionMappings().getNodeType();
392   }
393
394   private EnumTemplateType getTemplateTypeFromNodeTemplates(List<NodeTemplate> ntList) {
395     for (NodeTemplate nt : ntList) {
396       if (isNsType(nt.getType()) || isVnfType(nt.getType())) {
397         return EnumTemplateType.NS;
398       }
399     }
400
401     return EnumTemplateType.VNF;
402   }
403
404   private boolean isVnfType(String type) {
405     if (ToolUtil.isTrimedEmptyString(type)) {
406       return false;
407     }
408     return type.toUpperCase().contains(".VNF");
409   }
410
411   private boolean isNsType(String type) {
412     if (ToolUtil.isTrimedEmptyString(type)) {
413       return false;
414     }
415     return type.toUpperCase().contains(".NS");
416   }
417 }