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