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