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