1bd77c81a7040d637ebe6c011adc187ca4c969c3
[aai/model-loader.git] / src / main / java / org / openecomp / modelloader / entity / model / ModelArtifactParser.java
1 /**
2  * ============LICENSE_START=======================================================
3  * Model Loader
4  * ================================================================================
5  * Copyright © 2017 AT&T Intellectual Property.
6  * Copyright © 2017 Amdocs
7  * All rights reserved.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * http://www.apache.org/licenses/LICENSE-2.0
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  *
20  * ECOMP and OpenECOMP are trademarks
21  * and service marks of AT&T Intellectual Property.
22  */
23 package org.openecomp.modelloader.entity.model;
24
25 import org.openecomp.cl.api.Logger;
26 import org.openecomp.cl.eelf.LoggerFactory;
27 import org.openecomp.modelloader.entity.Artifact;
28 import org.openecomp.modelloader.entity.ArtifactType;
29 import org.openecomp.modelloader.service.ModelLoaderMsgs;
30 import org.openecomp.modelloader.util.JsonXmlConverter;
31
32 import org.w3c.dom.Document;
33 import org.w3c.dom.Element;
34 import org.w3c.dom.Node;
35 import org.w3c.dom.NodeList;
36 import org.xml.sax.InputSource;
37
38 import java.io.StringReader;
39 import java.io.StringWriter;
40 import java.util.ArrayList;
41 import java.util.List;
42
43 import javax.xml.XMLConstants;
44 import javax.xml.parsers.DocumentBuilder;
45 import javax.xml.parsers.DocumentBuilderFactory;
46 import javax.xml.transform.OutputKeys;
47 import javax.xml.transform.Transformer;
48 import javax.xml.transform.TransformerException;
49 import javax.xml.transform.TransformerFactory;
50 import javax.xml.transform.dom.DOMSource;
51 import javax.xml.transform.stream.StreamResult;
52
53
54 public class ModelArtifactParser {
55
56         private static String MODELS_ELEMENT = "models";
57         private static String MODEL_ELEMENT = "model";
58         private static String NAMED_QUERIES_ELEMENT = "named-queries";
59         private static String NAMED_QUERY_ELEMENT = "named-query";
60         private static String MODEL_NAME_VERSION_ID = "model-name-version-id";
61         private static String MODEL_VER = "model-ver";
62         private static String MODEL_VERSION_ID = "model-version-id";
63         private static String MODEL_INVARIANT_ID = "model-invariant-id";
64         private static String NAMED_QUERY_VERSION_ID = "named-query-uuid";
65         private static String RELATIONSHIP_DATA = "relationship-data";
66         private static String RELATIONSHIP_KEY = "relationship-key";
67         private static String RELATIONSHIP_VALUE = "relationship-value";
68         private static String MODEL_ELEMENT_RELATIONSHIP_KEY = "model.model-invariant-id";
69         private static String MODEL_VER_ELEMENT_RELATIONSHIP_KEY = "model-ver.model-version-id";
70         
71         private  static Logger logger = LoggerFactory.getInstance().getLogger(ModelArtifactParser.class.getName());
72         
73         public List<Artifact> parse(byte[] artifactPayload, String artifactName) {
74           String payload = new String(artifactPayload);
75           List<Artifact> modelList = new ArrayList<Artifact>();
76
77           try {
78             // Artifact could be JSON or XML
79             if (JsonXmlConverter.isValidJson(payload)) {
80               payload = JsonXmlConverter.convertJsonToXml(payload);
81             }
82
83             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
84             DocumentBuilder builder = factory.newDocumentBuilder();
85             InputSource is = new InputSource(new StringReader(payload));
86             Document doc = builder.parse(is);
87
88             if ( (doc.getDocumentElement().getNodeName().equalsIgnoreCase(MODEL_ELEMENT)) || 
89                 (doc.getDocumentElement().getNodeName().equalsIgnoreCase(NAMED_QUERY_ELEMENT)) ) {
90
91               ModelArtifact model = parseModel(doc.getDocumentElement(), payload);
92
93               if (model != null) {
94                 if ( ArtifactType.MODEL.equals(model.getType())) {
95                   logger.info( ModelLoaderMsgs.DISTRIBUTION_EVENT, "Model parsed =====>>>> "
96                       + "Model-invariant-Id: "+ model.getModelInvariantId()
97                       + " Model-Version-Id: "+ model.getModelVerId());
98                 }
99                 modelList.add(model);
100               }
101               else {
102                 logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse artifact " + artifactName);
103                 return null;
104               }
105             }
106             else if ( (doc.getDocumentElement().getNodeName().equalsIgnoreCase(MODELS_ELEMENT)) ||
107                 (doc.getDocumentElement().getNodeName().equalsIgnoreCase(NAMED_QUERIES_ELEMENT)) ) {
108               // The complete set of models/named-queries were contained in this artifact
109               NodeList nodeList = doc.getDocumentElement().getChildNodes();
110               for (int i = 0; i < nodeList.getLength(); i++) {
111                 Node childNode = nodeList.item(i);
112                 if ( (childNode.getNodeName().equalsIgnoreCase(MODEL_ELEMENT)) || 
113                     (childNode.getNodeName().equalsIgnoreCase(NAMED_QUERY_ELEMENT)) ) {
114                   String modelPayload = nodeToString(childNode);
115                   ModelArtifact model = parseModel(childNode, modelPayload);
116                   if (model != null) {
117                     modelList.add(model);
118                   }
119                   else {
120                     logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse artifact " + artifactName);
121                     modelList.clear();
122                     break;
123                   }
124                 }
125               }
126             }
127           }
128           catch (Exception ex) {
129             logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse artifact " + artifactName + ": " + ex.getLocalizedMessage());
130           }
131
132           return modelList;
133         }
134
135         private void printDetails(Node modelVer) throws TransformerException {
136           logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, nodeToString(modelVer));
137         }
138
139         private ModelArtifact parseModel(Node modelNode, String payload) {
140           ModelArtifact model = new ModelArtifact();
141           model.setPayload(payload);
142
143           if (modelNode.getNodeName().equalsIgnoreCase(MODEL_ELEMENT)) {
144             //compare with Model-ver
145             model.setType(ArtifactType.MODEL);
146           }
147           else {
148             model.setType(ArtifactType.NAMED_QUERY);
149           }
150
151           Element e = (Element)modelNode;
152           model.setModelNamespace(e.getAttribute("xmlns"));
153
154           parseNode(modelNode, model);
155
156           if (model.getModelInvariantId() == null  && model.getNameVersionId() == null) {
157             return null;
158           }
159
160           return model;
161         }
162
163         private void parseNode(Node node, ModelArtifact model) {
164
165           if(node.getNodeName().equalsIgnoreCase(MODEL_NAME_VERSION_ID)){
166             model.setModelVerId(node.getTextContent().trim());
167             model.setV9Artifact(false);
168           }
169           else if(node.getNodeName().equalsIgnoreCase("model-id")){
170             model.setModelInvariantId(node.getTextContent().trim());
171             model.setV9Artifact(false);
172           }
173
174           else if (node.getNodeName().equalsIgnoreCase(MODEL_INVARIANT_ID)) {
175             model.setModelInvariantId(node.getTextContent().trim());
176           }
177           else if (node.getNodeName().equalsIgnoreCase(MODEL_VERSION_ID)) {
178             model.setModelVerId(node.getTextContent().trim());
179             //Change to Model Invariant Id
180           }
181           else if (node.getNodeName().equalsIgnoreCase(NAMED_QUERY_VERSION_ID)) {
182             model.setNameVersionId(node.getTextContent().trim());
183           }
184           else if (node.getNodeName().equalsIgnoreCase(RELATIONSHIP_DATA)) {
185             parseRelationshipNode(node, model);
186             if(model.getModelModelInvariantId()!=null && model.getModelVerModelVersionId()!=null && !model.getModelModelInvariantId().isEmpty() && !model.getModelVerModelVersionId().isEmpty()){
187               model.addDependentModelId(model.getModelModelInvariantId() + "|" + model.getModelVerModelVersionId());
188               model.setModelModelInvariantId("");
189               model.setModelVerModelVersionId("");
190             }
191           }
192           else {
193
194             if (node.getNodeName().equalsIgnoreCase(MODEL_VER)) {
195               model.setModelVer(node);
196               if ( (model.getModelNamespace() != null) && (!model.getModelNamespace().isEmpty()) ) {
197                 Element e = (Element) node;
198                 e.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns", model.getModelNamespace());
199               }
200             }
201
202             NodeList nodeList = node.getChildNodes();
203
204             for (int i = 0; i < nodeList.getLength(); i++) {
205               Node childNode = nodeList.item(i); 
206               parseNode(childNode, model);
207             }
208           }
209         }
210
211         private void parseRelationshipNode(Node node, ModelArtifact model) {
212
213           //invariant-id comes before model-version-id .. create a list of values
214           String key = null;
215           String value = null;
216           String modelVersionIdKey=null;
217           String modelInvariantIdIdKey=null;
218           String modelVersionIdValue=null;
219           String modelInvariantIdIdValue=null;
220
221           NodeList nodeList = node.getChildNodes();
222           for (int i = 0; i < nodeList.getLength(); i++) {
223             Node childNode = nodeList.item(i);
224
225
226             if (childNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_KEY)) {
227               key = childNode.getTextContent().trim();
228               if(key.equalsIgnoreCase(MODEL_VER_ELEMENT_RELATIONSHIP_KEY)){
229                 modelVersionIdKey = key;
230               }
231               else if(key.equalsIgnoreCase(MODEL_ELEMENT_RELATIONSHIP_KEY)){
232                 modelInvariantIdIdKey = key;
233               }
234             }
235             else if (childNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_VALUE)) {
236               value = childNode.getTextContent().trim();
237               if(modelVersionIdKey!=null){
238                 modelVersionIdValue = value;
239                 model.setModelVerModelVersionId(modelVersionIdValue);
240               }
241               else if(modelInvariantIdIdKey!=null){
242                 modelInvariantIdIdValue = value;
243                 model.setModelModelInvariantId(modelInvariantIdIdValue);
244               } 
245
246             }
247           }
248
249           if ( (key != null) && (key.equalsIgnoreCase(MODEL_ELEMENT_RELATIONSHIP_KEY )) && 
250               (model.isV9Artifact == false ||ArtifactType.NAMED_QUERY.equals(model.getType())) ) {
251             if (value != null) {
252               model.addDependentModelId(value);
253             }
254           }
255         }
256
257         private String nodeToString(Node node) throws TransformerException {
258           StringWriter sw = new StringWriter();
259           Transformer t = TransformerFactory.newInstance().newTransformer();
260           t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
261           t.transform(new DOMSource(node), new StreamResult(sw));
262           return sw.toString();
263         }
264 }