org.onap migration
[vid.git] / vid-app-common / src / main / java / org / onap / vid / asdc / parser / ToscaParserImpl.java
1 package org.onap.vid.asdc.parser;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.nio.file.Path;
6 import java.text.DateFormat;
7 import java.text.SimpleDateFormat;
8 import java.util.Date;
9 import java.util.HashMap;
10 import java.util.Map;
11 import java.util.Set;
12 import java.util.UUID;
13 import java.util.Map.Entry;
14 import java.util.zip.ZipFile;
15
16 import org.apache.commons.lang3.mutable.MutableBoolean;
17 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
18 import org.openecomp.sdc.tosca.parser.exceptions.SdcToscaParserException;
19 import org.onap.vid.asdc.AsdcCatalogException;
20 import org.onap.vid.asdc.beans.Service;
21 import org.onap.vid.asdc.beans.tosca.NodeTemplate;
22 import org.onap.vid.asdc.beans.tosca.ToscaCsar;
23 import org.onap.vid.asdc.beans.tosca.ToscaMeta;
24 import org.onap.vid.asdc.beans.tosca.ToscaModel;
25 import org.onap.vid.model.ModelConstants;
26 import org.onap.vid.model.Network;
27 import org.onap.vid.model.Node;
28 import org.onap.vid.model.ServiceModel;
29 import org.onap.vid.model.VNF;
30 import org.onap.vid.properties.VidProperties;
31 import org.springframework.beans.factory.annotation.Autowired;
32 import org.yaml.snakeyaml.Yaml;
33 import org.yaml.snakeyaml.error.YAMLException;
34
35 public class ToscaParserImpl implements ToscaParser {
36         /** The Constant LOG. */
37         static final EELFLoggerDelegate LOG = EELFLoggerDelegate.getLogger(ToscaParserImpl.class);
38
39         @Autowired
40         private final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
41
42
43         private static final String asdcModelNamespace = VidProperties.getAsdcModelNamespace();
44         private static final String vnfTag = asdcModelNamespace + ModelConstants.VNF;
45         private static final String networkTag = asdcModelNamespace + ModelConstants.NETWORK;
46         private static final String vfModuleTag = asdcModelNamespace + ModelConstants.VF_MODULE;
47
48
49         @Override
50         public ToscaCsar parse(Path path) throws AsdcCatalogException {
51                 return getToscaCsar(path);
52         }
53
54         private ToscaCsar getToscaCsar(final Path csarFile) throws AsdcCatalogException {
55                 try (final ZipFile csar = new ZipFile(csarFile.toFile())) {
56
57                         final InputStream toscaMetaStream = csar.getInputStream(csar.getEntry("TOSCA-Metadata/TOSCA.meta"));
58                         final ToscaMeta toscaMeta = new ToscaMeta.Builder(toscaMetaStream).build();
59                         final String entryDefinitions = toscaMeta.get("Entry-Definitions");
60                         final InputStream toscaParentEntryYamlStream = csar.getInputStream(csar.getEntry(entryDefinitions));
61
62                         try {
63                                 final Yaml yaml = new Yaml();
64                                 final ToscaModel parentModel = yaml.loadAs(toscaParentEntryYamlStream, ToscaModel.class);
65
66                                 final ToscaCsar.Builder csarBuilder = new ToscaCsar.Builder(parentModel);
67
68                                 for (Map<String, Map<String, String>> imports : parentModel.getImports()) {
69                                         LOG.debug("imports = " + imports.toString());
70                                         for (Entry<String, Map<String, String>> entry : imports.entrySet()) {
71                                                 if (entry.getValue() != null) {
72                                                         String fname = entry.getValue().get("file");
73                                                         if ((fname != null) && (fname.startsWith("service") || fname.startsWith("resource"))) {
74                                                                 LOG.debug("fname = " + fname);
75                                                                 final InputStream toscaChildEntryYamlStream = csar
76                                                                                 .getInputStream(csar.getEntry("Definitions/" + fname));
77
78                                                                 final ToscaModel childModel = yaml.loadAs(toscaChildEntryYamlStream, ToscaModel.class);
79                                                                 csarBuilder.addVnf(childModel);
80                                                         }
81                                                 }
82                                         }
83                                 }
84
85                                 return csarBuilder.build();
86                         } catch (YAMLException e) {
87                                 throw new AsdcCatalogException("Caught exception while processing TOSCA YAML", e);
88                         }
89                 } catch (IOException e) {
90                         throw new AsdcCatalogException("Caught IOException while processing CSAR", e);
91                 }
92         }
93
94         public ServiceModel makeServiceModel(String uuid, final Path serviceCsar,Service service ) throws AsdcCatalogException, SdcToscaParserException {
95
96
97                 final ServiceModel serviceModel = new ServiceModel();
98                 ToscaCsar toscaCsar = getToscaCsar(serviceCsar);
99                 String methodName = "getServices";
100                 LOG.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + methodName + " start");
101                 MutableBoolean isNewFlow = new MutableBoolean(false);
102                 final Map<String, VNF> vnfs = new HashMap<String, VNF>();
103                 final Map<String, Network> networks = new HashMap<String, Network>();
104                 final ToscaModel asdcServiceToscaModel = toscaCsar.getParent();
105                 serviceModel.setService(ServiceModel.extractService(asdcServiceToscaModel, service));
106
107
108                 populateVnfsAndNetwork(methodName, isNewFlow, vnfs, networks, asdcServiceToscaModel, serviceModel);
109
110                 // If we see customization uuid under vnf or network, follow 1702 flow
111                 if (isNewFlow.getValue()) {
112                         return (getCustomizedServices(asdcServiceToscaModel, serviceModel));
113                 } else {
114                         VNF vnf = null;
115                         for (ToscaModel vnfModel : toscaCsar.getChildren()) {
116                                 // using uuid to match should only be valid for 1610 models
117                                 final String vnfUuid = (vnfModel.getMetadata().getUUID());
118                                 // find the VNF with that uuid, uuid is not the key anymore
119                                 vnf = findVNFAccordingToUUID(vnfs, vnfUuid);
120                                 if (vnf == null) {
121                                         LOG.warn("Couldn't find VNF object " + vnfUuid + ". Problem with Tosca model?");
122                                         continue;
123                                 }
124                                 extractAndUpdateInputs(vnf, vnfModel);
125                                 ServiceModel.extractGroups(vnfModel, serviceModel);
126                         }
127
128                         serviceModel.setVnfs(vnfs);
129                         serviceModel.setNetworks(networks);
130                         return serviceModel;
131                 }
132         }
133
134         private VNF findVNFAccordingToUUID(final Map<String, VNF> vnfs,  final String vnfUuid) {
135                 VNF vnf = null;
136                 for (Entry<String, VNF> vnfComp : vnfs.entrySet()) {
137                         if (((vnfComp.getValue().getUuid()).equalsIgnoreCase(vnfUuid))) {
138                                 // found the vnf
139                                 vnf = vnfComp.getValue();
140                         }
141                 }
142                 return vnf;
143         }
144
145         private void extractAndUpdateInputs(VNF vnf, ToscaModel vnfModel) {
146                 vnf.setInputs(vnfModel.gettopology_template().getInputs());
147         }
148
149         private static void populateVnfsAndNetwork(String methodName, MutableBoolean isNewFlow, final Map<String, VNF> vnfs,
150                                                                                            final Map<String, Network> networks, final ToscaModel asdcServiceToscaModel, ServiceModel serviceModel)
151                         throws AsdcCatalogException, SdcToscaParserException {
152                 for (Entry<String, NodeTemplate> component : extractNodeTemplates(asdcServiceToscaModel)) {
153                         final String modelCustomizationName = component.getKey();
154                         LOG.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + methodName
155                                         + " model customization name: " + modelCustomizationName);
156                         final NodeTemplate nodeTemplate = component.getValue();
157                         final String type = nodeTemplate.getType();
158
159                         if (type.startsWith(vnfTag)) {
160                                 LOG.debug(EELFLoggerDelegate.debugLogger,
161                                                 dateFormat.format(new Date()) + methodName + " found node template type: " + type);
162                                 final VNF vnf = new VNF();
163                                 vnf.extractVnf(modelCustomizationName, nodeTemplate);
164 //                              populateNodeVersionIfMissing(nodeTemplate, vnf,service);
165                                 LOG.debug(EELFLoggerDelegate.debugLogger,
166                                                 dateFormat.format(new Date()) + methodName + " VNF commands: " + vnf.getCommands());
167                                 vnfs.put(modelCustomizationName, vnf);
168                                 isNewFlow.setValue(isNewFlow(vnf));
169                         }
170                         // Networks
171                         if (type.startsWith(networkTag)) {
172                                 LOG.debug(EELFLoggerDelegate.debugLogger,
173                                                 dateFormat.format(new Date()) + methodName + " found node template type: " + type);
174                                 final Network network = new Network();
175                                 network.extractNetwork(modelCustomizationName, nodeTemplate);
176 //                              populateNodeVersionIfMissing(nodeTemplate, network, service);
177                                 isNewFlow.setValue(isNewFlow(network));
178                                 networks.put(modelCustomizationName, network);
179
180                         }
181                 }
182                 serviceModel.setVnfs(vnfs);
183                 serviceModel.setNetworks(networks);
184
185         }
186
187         private static Set<Entry<String, NodeTemplate>> extractNodeTemplates(final ToscaModel asdcServiceToscaModel) {
188                 return asdcServiceToscaModel.gettopology_template().getnode_templates().entrySet();
189         }
190
191         private static boolean isNewFlow(Node node) {
192                 return (node.getCustomizationUuid() != null) && (node.getCustomizationUuid().length() > 0);
193         }
194
195         private static boolean isNodeVersionMissing(Node Node) {
196                 return Node.getVersion() == null;
197         }
198
199         private static void populateNodeVersionIfMissing(final NodeTemplate nodeTemplate, final Node node, Service service)
200                         throws AsdcCatalogException {
201                 if (isNodeVersionMissing(node)) {
202                         node.setVersion(service.getVersion());
203                 }
204         }
205
206         private ServiceModel getCustomizedServices(ToscaModel asdcServiceToscaModel, ServiceModel serviceModel) {
207                 String methodName = "asdcServiceToscaModel";
208                 LOG.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + methodName + " start");
209
210                 // asdcServiceToscaModel should have vf modules and vol groups populated
211                 // at this point but
212                 // they are not associated with the VNFs
213                 ServiceModel.extractGroups(asdcServiceToscaModel,serviceModel);
214                 // Now put the vf modules and volume groups under the VNF they belong
215                 // too
216                 serviceModel.associateGroups();
217                 return (serviceModel);
218         }
219
220
221         private UUID extractUUIDFromNodeTemplate(final NodeTemplate nodeTemplate) {
222                 return UUID.fromString(nodeTemplate.getMetadata().getUUID());
223         }
224
225
226 }