[AAI] Release docker artifacts 1.12.3 for aai/schema-service
[aai/schema-service.git] / aai-schema / src / test / java / org / onap / aai / schema / ValidateOXMTest.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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
21 package org.onap.aai.schema;
22
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25
26 import java.io.*;
27 import java.nio.file.Path;
28 import java.nio.file.Paths;
29 import java.util.*;
30 import java.util.stream.Collectors;
31
32 import javax.xml.parsers.DocumentBuilder;
33 import javax.xml.parsers.DocumentBuilderFactory;
34 import javax.xml.parsers.ParserConfigurationException;
35 import javax.xml.xpath.XPath;
36 import javax.xml.xpath.XPathConstants;
37 import javax.xml.xpath.XPathExpressionException;
38 import javax.xml.xpath.XPathFactory;
39
40 import org.apache.commons.io.FileUtils;
41 import org.apache.commons.io.filefilter.DirectoryFileFilter;
42 import org.apache.commons.io.filefilter.RegexFileFilter;
43 import org.json.simple.JSONArray;
44 import org.json.simple.JSONObject;
45 import org.json.simple.parser.JSONParser;
46 import org.json.simple.parser.ParseException;
47 import org.junit.Ignore;
48 import org.junit.Test;
49 import org.w3c.dom.*;
50 import org.xml.sax.SAXException;
51
52 public class ValidateOXMTest {
53
54     private String DBEDGERULES_RULES = "rules";
55     private String DBEDGERULES_FROM = "from";
56     private String DBEDGERULES_TO = "to";
57     private String DBEDGERULES_DIRECTION = "direction";
58     private String DBEDGERULES_CONTAINS_OTHER_V = "contains-other-v";
59     private String DBEDGERULES_OUT = "OUT";
60     private String DBEDGERULES_IN = "IN";
61     private String XMLROOTELEMENT = "xml-root-element";
62     private String XMLPROPERTIES = "xml-properties";
63     private String ECOMP = "ecomp";
64     private String NARAD = "narad";
65     private String ONAP = "onap";
66
67     @Test
68     public void testFindXmlPropContainingSpace()
69         throws XPathExpressionException, IOException, SAXException, ParserConfigurationException {
70         boolean foundIssue = false;
71         List<File> fileList = getLatestFiles();
72
73         StringBuilder msg = new StringBuilder();
74         for (File file : fileList) {
75             msg.append(file.getAbsolutePath().replaceAll(".*aai-schema", ""));
76             msg.append("\n");
77             Document xmlDocument = getDocument(file);
78             XPath xPath = XPathFactory.newInstance().newXPath();
79             String expression =
80                 "/xml-bindings/java-types/java-type/xml-properties/xml-property[@name!='description' and contains(@value,' ')]";
81             NodeList nodeList =
82                 (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
83
84             for (int i = 0; i < nodeList.getLength(); i++) {
85                 foundIssue = true;
86                 msg.append("\t");
87                 msg.append(nodeList.item(i).getParentNode().getParentNode().getAttributes()
88                     .getNamedItem("name").getNodeValue());
89                 msg.append("\n");
90                 msg.append("\t");
91                 msg.append("\n");
92             }
93
94         }
95
96         if (foundIssue) {
97             System.out.println(msg.toString());
98             fail("Node type xml-property should have space.");
99         }
100
101     }
102
103     /**
104      * Verifies that all of the node types in the oxm's have their uri templates.
105      * 
106      * @throws XPathExpressionException
107      * @throws IOException
108      * @throws SAXException
109      * @throws ParserConfigurationException
110      */
111     @Test
112     public void allNodeTypesHaveAAIUriTemplate()
113         throws XPathExpressionException, IOException, SAXException, ParserConfigurationException {
114         boolean foundIssue = false;
115         List<File> fileList = getFiles();
116
117         StringBuilder msg = new StringBuilder();
118         for (File file : fileList) {
119             msg.append(file.getAbsolutePath().replaceAll(".*aai-schema", ""));
120             msg.append("\n");
121             Document xmlDocument = getDocument(file);
122             XPath xPath = XPathFactory.newInstance().newXPath();
123             String expression = "/xml-bindings/java-types/java-type[" + "("
124                 + "count(xml-properties/xml-property[@name='container']) > 0 "
125                 + "or count(xml-properties/xml-property[@name='dependentOn']) > 0" + ") "
126                 + "and count(xml-properties/xml-property[@name='uriTemplate']) = 0 " + "]";
127             NodeList nodeList =
128                 (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
129
130             for (int i = 0; i < nodeList.getLength(); i++) {
131                 String name = nodeList.item(i).getAttributes().getNamedItem("name").getNodeValue();
132                 if (name.equals("InstanceFilter") || name.equals("InventoryResponseItems")
133                     || name.equals("InventoryResponseItem")) {
134                     continue;
135                 }
136                 foundIssue = true;
137                 msg.append("\t");
138                 msg.append(name);
139                 msg.append("\n");
140             }
141         }
142         if (foundIssue) {
143             System.out.println(msg.toString());
144             fail("Missing uriTemplate in oxm.");
145         }
146
147     }
148
149     @Test
150     public void verifyAllIndexedPropertiesExistInObject()
151         throws XPathExpressionException, IOException, SAXException, ParserConfigurationException {
152
153         boolean foundIssue = false;
154         List<File> fileList = getOxmSchemaFiles();
155         fileList.addAll(getOnapOxmSchemaFiles());
156         StringBuilder msg = new StringBuilder();
157         for (File file : fileList) {
158             Document xmlDocument = getDocument(file);
159             XPath xPath = XPathFactory.newInstance().newXPath();
160             String expression =
161                 "/xml-bindings/java-types/java-type[count(xml-properties/xml-property[@name='indexedProps']) > 0]";
162             NodeList nodeList =
163                 (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
164
165             Map<String, List<String>> nodeTypeBadIndexProps = new HashMap<>();
166             for (int i = 0; i < nodeList.getLength(); i++) {
167                 String name = nodeList.item(i).getAttributes().getNamedItem("name").getNodeValue();
168
169                 NodeList javaAttributesList =
170                     ((Element) nodeList.item(i)).getElementsByTagName("java-attributes");
171
172                 Set<String> properties = new HashSet<>();
173
174                 for (int j = 0; j < javaAttributesList.getLength(); j++) {
175                     NodeList elementList =
176                         ((Element) javaAttributesList.item(j)).getElementsByTagName("xml-element");
177                     for (int k = 0; k < elementList.getLength(); k++) {
178                         properties.add(elementList.item(k).getAttributes().getNamedItem("name")
179                             .getNodeValue());
180                     }
181                 }
182
183                 NodeList xmlPropertiesList =
184                     ((Element) nodeList.item(i)).getElementsByTagName("xml-properties");
185                 List<String> badIndexedProps = new ArrayList<>();
186                 boolean foundIssueInNodeType = false;
187
188                 for (int j = 0; j < xmlPropertiesList.getLength(); j++) {
189                     NodeList xmlProperties =
190                         ((Element) xmlPropertiesList.item(j)).getElementsByTagName("xml-property");
191                     for (int k = 0; k < xmlProperties.getLength(); k++) {
192                         String xmlProp = xmlProperties.item(k).getAttributes().getNamedItem("name")
193                             .getNodeValue();
194                         if ("indexedProps".equals(xmlProp)) {
195                             String xmlPropValue = xmlProperties.item(k).getAttributes()
196                                 .getNamedItem("value").getNodeValue();
197
198                             List<String> indexProps =
199                                 Arrays.stream(xmlPropValue.split(",")).collect(Collectors.toList());
200
201                             for (String indexProp : indexProps) {
202                                 if (!properties.contains(indexProp)) {
203                                     foundIssueInNodeType = true;
204                                     badIndexedProps.add(indexProp);
205                                 }
206                             }
207
208                         }
209                     }
210                 }
211
212                 if (foundIssueInNodeType) {
213                     foundIssue = true;
214                     nodeTypeBadIndexProps.put(name, badIndexedProps);
215                 }
216             }
217
218             if (!nodeTypeBadIndexProps.isEmpty()) {
219                 msg.append("\n");
220                 msg.append("File: " + file.getAbsolutePath().replaceAll(".*aai-schema", ""));
221                 msg.append("\n");
222                 for (Map.Entry<String, List<String>> nodeTypeBadIndex : nodeTypeBadIndexProps
223                     .entrySet()) {
224                     msg.append("NodeType: " + nodeTypeBadIndex.getKey());
225                     msg.append(
226                         " contains following indexed props that are not properties in object: ");
227                     msg.append(String.join(",", nodeTypeBadIndex.getValue()));
228                     msg.append("\n");
229                 }
230             }
231
232         }
233
234         if (foundIssue) {
235             fail(msg.toString());
236         }
237     }
238
239     @Test
240     public void verifyAllUniquePropertiesExistInObject()
241         throws XPathExpressionException, IOException, SAXException, ParserConfigurationException {
242
243         boolean foundIssue = false;
244         List<File> fileList = getOxmSchemaFiles();
245         fileList.addAll(getOnapOxmSchemaFiles());
246         StringBuilder msg = new StringBuilder();
247         for (File file : fileList) {
248             Document xmlDocument = getDocument(file);
249             XPath xPath = XPathFactory.newInstance().newXPath();
250             String expression =
251                 "/xml-bindings/java-types/java-type[count(xml-properties/xml-property[@name='uniqueProps']) > 0]";
252             NodeList nodeList =
253                 (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
254
255             Map<String, List<String>> nodeTypeBadUniqueProps = new HashMap<>();
256             for (int i = 0; i < nodeList.getLength(); i++) {
257                 String name = nodeList.item(i).getAttributes().getNamedItem("name").getNodeValue();
258
259                 NodeList javaAttributesList =
260                     ((Element) nodeList.item(i)).getElementsByTagName("java-attributes");
261
262                 Set<String> properties = new HashSet<>();
263
264                 for (int j = 0; j < javaAttributesList.getLength(); j++) {
265                     NodeList elementList =
266                         ((Element) javaAttributesList.item(j)).getElementsByTagName("xml-element");
267                     for (int k = 0; k < elementList.getLength(); k++) {
268                         properties.add(elementList.item(k).getAttributes().getNamedItem("name")
269                             .getNodeValue());
270                     }
271                 }
272
273                 NodeList xmlPropertiesList =
274                     ((Element) nodeList.item(i)).getElementsByTagName("xml-properties");
275                 List<String> badUniqueProps = new ArrayList<>();
276                 boolean foundIssueInNodeType = false;
277
278                 for (int j = 0; j < xmlPropertiesList.getLength(); j++) {
279                     NodeList xmlProperties =
280                         ((Element) xmlPropertiesList.item(j)).getElementsByTagName("xml-property");
281                     for (int k = 0; k < xmlProperties.getLength(); k++) {
282                         String xmlProp = xmlProperties.item(k).getAttributes().getNamedItem("name")
283                             .getNodeValue();
284                         if ("uniqueProps".equals(xmlProp)) {
285                             String xmlPropValue = xmlProperties.item(k).getAttributes()
286                                 .getNamedItem("value").getNodeValue();
287
288                             List<String> uniqueProps =
289                                 Arrays.stream(xmlPropValue.split(",")).collect(Collectors.toList());
290
291                             for (String uniqueProp : uniqueProps) {
292                                 if (!properties.contains(uniqueProp)) {
293                                     foundIssueInNodeType = true;
294                                     badUniqueProps.add(uniqueProp);
295                                 }
296                             }
297
298                         }
299                     }
300                 }
301
302                 if (foundIssueInNodeType) {
303                     foundIssue = true;
304                     nodeTypeBadUniqueProps.put(name, badUniqueProps);
305                 }
306             }
307
308             if (!nodeTypeBadUniqueProps.isEmpty()) {
309                 msg.append("\n");
310                 msg.append("File: " + file.getAbsolutePath().replaceAll(".*aai-schema", ""));
311                 msg.append("\n");
312                 for (Map.Entry<String, List<String>> nodeTypeBadUnique : nodeTypeBadUniqueProps
313                     .entrySet()) {
314                     msg.append("NodeType: " + nodeTypeBadUnique.getKey());
315                     msg.append(
316                         " contains following unique props that are not properties in object: ");
317                     msg.append(String.join(",", nodeTypeBadUnique.getValue()));
318                     msg.append("\n");
319                 }
320             }
321
322         }
323
324         if (foundIssue) {
325             fail(msg.toString());
326         }
327     }
328
329     /**
330      * Verifies that all of the top level node types in the oxm's have their namespace in uri
331      * templates.
332      * 
333      * @throws XPathExpressionException
334      * @throws IOException
335      * @throws SAXException
336      * @throws ParserConfigurationException
337      */
338     @Test
339     public void verifyAllUriTemplateHaveNamespace()
340         throws XPathExpressionException, IOException, SAXException, ParserConfigurationException {
341         boolean foundIssue = false;
342         List<File> fileList = getOxmSchemaFiles();
343         fileList.addAll(getOnapOxmSchemaFiles());
344         StringBuilder msg = new StringBuilder();
345         for (File file : fileList) {
346             msg.append(file.getAbsolutePath().replaceAll(".*aai-schema", ""));
347             msg.append("\n");
348             Document xmlDocument = getDocument(file);
349             XPath xPath = XPathFactory.newInstance().newXPath();
350             String expression = "/xml-bindings/java-types/java-type["
351                 + "count(xml-properties/xml-property[@name='namespace']) > 0 " + "]";
352             NodeList nodeList =
353                 (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
354
355             for (int i = 0; i < nodeList.getLength(); i++) {
356                 String name = nodeList.item(i).getAttributes().getNamedItem("name").getNodeValue();
357
358                 NodeList childNodeList = (NodeList) nodeList.item(i).getChildNodes();
359                 for (int j = 0; j < childNodeList.getLength(); j++) {
360
361                     String nodeName = childNodeList.item(j).getNodeName();
362                     NodeList xmlPropertyNodeList = childNodeList.item(j).getChildNodes();
363                     if (XMLPROPERTIES.equals(nodeName)) {
364
365                         String namespaceVal = "";
366                         String uriTemplateVal = "";
367                         for (int k = 0; k < xmlPropertyNodeList.getLength(); k++) {
368
369                             if ("xml-property".equals(xmlPropertyNodeList.item(k).getNodeName())) {
370
371                                 NamedNodeMap attributes =
372                                     xmlPropertyNodeList.item(k).getAttributes();
373
374                                 if ("namespace"
375                                     .equals(attributes.getNamedItem("name").getNodeValue())) {
376                                     namespaceVal = attributes.getNamedItem("value").getNodeValue();
377                                 }
378                                 if ("uriTemplate"
379                                     .equals(attributes.getNamedItem("name").getNodeValue())) {
380                                     uriTemplateVal =
381                                         attributes.getNamedItem("value").getNodeValue();
382                                 }
383
384                             }
385
386                         }
387
388                         if (!uriTemplateVal.startsWith("/" + namespaceVal + "/")) {
389                             foundIssue = true;
390                             msg.append("\t");
391                             msg.append(uriTemplateVal);
392                             msg.append("\n");
393                         }
394
395                     }
396                 }
397
398             }
399         }
400         if (foundIssue) {
401             System.out.println(msg.toString());
402             fail("uriTemplate doesnt start with /namespace/.");
403         }
404
405     }
406
407     /**
408      * Verifies that all specified properties are indexed
409      * Currently set to check that "model-invariant-id","model-version-id" which are aliased are
410      * indexed
411      * 
412      * @throws XPathExpressionException
413      * @throws IOException
414      * @throws SAXException
415      * @throws ParserConfigurationException
416      */
417     @Test
418     public void aliasedIndexedPropsAreInIndexedListWithPropName()
419         throws XPathExpressionException, IOException, SAXException, ParserConfigurationException {
420
421         final List<String> props = Arrays.asList("model-invariant-id", "model-version-id");
422
423         boolean foundIssue = false;
424         List<File> fileList = getLatestFiles();
425         StringBuilder msg = new StringBuilder();
426
427         for (File file : fileList) {
428             msg.append(file.getAbsolutePath().replaceAll(".*aai-schema", ""));
429             msg.append("\n");
430             for (String prop : props) {
431                 Document xmlDocument = getDocument(file);
432                 XPath xPath = XPathFactory.newInstance().newXPath();
433                 String expression = "/xml-bindings/java-types/java-type[" + "("
434                     + "count(xml-properties/xml-property[@name='container']) > 0 "
435                     + "or count(xml-properties/xml-property[@name='dependentOn']) > 0" + ") "
436                     + "and count(xml-properties/xml-property[@name='indexedProps' and not(contains(@value,'"
437                     + prop + "'))]) > 0 " + // prop is not in indexed props list
438                     "and count(java-attributes/xml-element[@name='" + prop + "']) > 0 " + // prop is
439                                                                                           // a
440                                                                                           // property
441                                                                                           // on obj
442                     "]";
443
444                 NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument,
445                     XPathConstants.NODESET);
446
447                 if (nodeList.getLength() > 0) {
448                     msg.append("\t").append(prop).append("\n");
449                 }
450                 for (int i = 0; i < nodeList.getLength(); i++) {
451                     String name =
452                         nodeList.item(i).getAttributes().getNamedItem("name").getNodeValue();
453                     if (name.equals("InstanceFilter") || name.equals("InventoryResponseItems")
454                         || name.equals("InventoryResponseItem")) {
455                         continue;
456                     }
457                     foundIssue = true;
458                     msg.append("\t\t").append(name).append("\n");
459                 }
460             }
461         }
462
463         if (foundIssue) {
464             System.out.println(msg.toString());
465             fail("Missing index entry in oxm.");
466         }
467
468     }
469
470     /**
471      * Check schema versions against their respective dbEdgeRules file and check if the
472      * dependentOn relationship matches what is listed in the edge rules.
473      *
474      */
475     @Ignore
476     @Test
477     public void testSchemaValidationAgainstEdgeRules() throws XPathExpressionException, IOException,
478         SAXException, ParserConfigurationException, ParseException {
479         Path currentRelativePath = Paths.get("../aai-schema/src/main/resources/").toAbsolutePath();
480         List<File> subDirs =
481             Arrays.asList(currentRelativePath.toFile().listFiles(File::isDirectory));
482         boolean success = true;
483         for (File subDir : subDirs) {
484             List<String> oxmSchemaList = new ArrayList<>();
485             List<String> dbEdgeRulesList = new ArrayList<>();
486             String oxm = subDir.getAbsolutePath() + "/oxm";
487             File[] oxms = new File(oxm).listFiles(File::isDirectory);
488             Arrays.stream(oxms).map(File::getAbsolutePath).max(new Comparator<String>() {
489                 public int compare(String o1, String o2) {
490                     return extractInt(o1) - extractInt(o2);
491                 }
492
493                 int extractInt(String s) {
494                     String num = s.replaceAll("\\D", "");
495                     return num.isEmpty() ? 0 : Integer.parseInt(num);
496                 }
497             }).ifPresent(oxmSchemaList::add);
498
499             String edgeRule = subDir.getAbsolutePath() + "/dbedgerules";
500             File[] edgeRules = new File(edgeRule).listFiles(File::isDirectory);
501             Arrays.stream(edgeRules).map(File::getAbsolutePath).max(new Comparator<String>() {
502                 public int compare(String o1, String o2) {
503                     return extractInt(o1) - extractInt(o2);
504                 }
505
506                 int extractInt(String s) {
507                     String num = s.replaceAll("\\D", "");
508                     return num.isEmpty() ? 0 : Integer.parseInt(num);
509                 }
510             }).ifPresent(dbEdgeRulesList::add);
511
512             List<File> oxmSchemaFileList = new ArrayList<>();
513             List<File> dbEdgeRulesFileList = new ArrayList<>();
514             oxmSchemaList.forEach(s -> FileUtils
515                 .listFiles(new File(s), new RegexFileFilter(".*\\.xml"),
516                     DirectoryFileFilter.DIRECTORY)
517                 .stream().filter(file -> file.getAbsolutePath().contains("oxm"))
518                 .forEach(oxmSchemaFileList::add));
519
520             dbEdgeRulesList.forEach(s -> FileUtils
521                 .listFiles(new File(s), new RegexFileFilter(".*\\.json"),
522                     DirectoryFileFilter.DIRECTORY)
523                 .stream().filter(file -> file.getAbsolutePath().contains("DbEdgeRules"))
524                 .forEach(dbEdgeRulesFileList::add));
525
526             // Map the dbEdgeRules json file into a HashMap for reference
527             Map<String, Set<String>> dbEdgeRules = new HashMap<>();
528             JSONParser jsonParser = new JSONParser();
529             for (File file : dbEdgeRulesFileList) {
530                 FileReader reader = new FileReader(file);
531                 // Read JSON file. Expecting JSON file to read an object with a JSONArray names
532                 // "rules"
533                 JSONObject jsonObj = (JSONObject) jsonParser.parse(reader);
534                 JSONArray rules = (JSONArray) jsonObj.get(DBEDGERULES_RULES);
535                 for (int i = 0; i < rules.size(); i++) {
536                     JSONObject rule = (JSONObject) rules.get(i);
537                     String fromNode = rule.get(DBEDGERULES_FROM).toString();
538                     String toNode = rule.get(DBEDGERULES_TO).toString();
539                     String direction = rule.get(DBEDGERULES_DIRECTION).toString();
540                     String containsOtherV = rule.get(DBEDGERULES_CONTAINS_OTHER_V).toString();
541
542                     // special case - cvlan-tag should be replaced with cvlan-tag-entry
543                     if (fromNode.equals("cvlan-tag"))
544                         fromNode = "cvlan-tag-entry";
545                     if (toNode.equals("cvlan-tag"))
546                         toNode = "cvlan-tag-entry";
547                     if (containsOtherV.equals("!${direction}")) {
548                         if (direction.equals(DBEDGERULES_IN)) {
549                             direction = DBEDGERULES_OUT;
550                         } else if (direction.equals(DBEDGERULES_OUT)) {
551                             direction = DBEDGERULES_IN;
552                         }
553                     }
554                     // If this value is none, the edge rule is for cousin nodes. Ignore.
555                     else if (containsOtherV.equals("NONE"))
556                         continue;
557                     dbEdgeRulesMapPut(dbEdgeRules, fromNode, toNode, direction);
558                 }
559             }
560
561             // Iterate through the most recent oxm schema files. Map the parent child relationships
562             Map<String, Set<String>> oxmSchemaFile = new HashMap<>();
563             for (File file : oxmSchemaFileList) {
564                 Document xmlDocument = getDocument(file);
565                 XPath xPath = XPathFactory.newInstance().newXPath();
566                 String parentNodeExpression =
567                     "/xml-bindings/java-types/java-type/xml-properties/xml-property[@name='dependentOn']";
568                 NodeList parentNodeList = (NodeList) xPath.compile(parentNodeExpression)
569                     .evaluate(xmlDocument, XPathConstants.NODESET);
570                 String childNodeExpression = "/xml-bindings/java-types/java-type[" + "("
571                     + "count(xml-properties/xml-property[@name='dependentOn']) > 0" + ")]";
572                 NodeList childNodeList = (NodeList) xPath.compile(childNodeExpression)
573                     .evaluate(xmlDocument, XPathConstants.NODESET);
574
575                 for (int i = 0; i < parentNodeList.getLength(); i++) {
576
577                     // Obtain the xml-root-element field by tracing the childNodes from the
578                     // java-type parent node
579                     for (int j = 0; j < childNodeList.item(i).getChildNodes().getLength(); j++) {
580                         if (childNodeList.item(i).getChildNodes().item(j).getNodeName()
581                             .equals(XMLROOTELEMENT)) {
582
583                             // The parent node
584                             String dependentOn = parentNodeList.item(i).getAttributes()
585                                 .getNamedItem("value").getNodeValue();
586
587                             // The child node
588                             String xmlRootElement = childNodeList.item(i).getChildNodes().item(j)
589                                 .getAttributes().getNamedItem("name").getNodeValue();
590
591                             Set<String> childSet;
592                             String[] parents = dependentOn.split(",");
593                             for (int k = 0; k < parents.length; k++) {
594                                 String parent = parents[k];
595                                 if (oxmSchemaFile.containsKey(parent)) {
596                                     childSet = oxmSchemaFile.get(parent);
597                                 } else {
598                                     childSet = new HashSet<>();
599                                 }
600                                 childSet.add(xmlRootElement);
601                                 oxmSchemaFile.put(parent, childSet);
602                             }
603
604                         }
605                     }
606                 }
607             }
608
609             // Compare the OXM file against the dbEdgeRules file. check what is missing in
610             // dbEdgeRules from the oxm files.
611             Set<String> oxmKeySet = oxmSchemaFile.keySet();
612             for (String key : oxmKeySet) {
613                 Set<String> oxmChildren = oxmSchemaFile.get(key);
614                 Set<String> dbEdgeRulesChildren = dbEdgeRules.get(key);
615
616                 // Check if the parent vertex exists at all in the dbEdgeRules file
617                 if (dbEdgeRulesChildren == null || dbEdgeRulesChildren.isEmpty()) {
618                     for (String oxmChild : oxmChildren) {
619                         System.out.println("ERROR: dbEdgeRules under directory '"
620                             + subDir.toString() + "' does not contain parent '" + key
621                             + "' and child '" + oxmChild + "' relationship");
622                     }
623                     success = false;
624                     continue;
625                 }
626
627                 // Compare both parent-child relationships between both files
628                 if (!oxmChildren.equals(dbEdgeRulesChildren)) {
629                     for (String oxmChild : oxmChildren) {
630                         if (!dbEdgeRulesChildren.contains(oxmChild)) {
631                             System.out.println("ERROR: dbEdgeRules under directory '"
632                                 + subDir.toString() + "' does not contain parent '" + key
633                                 + "' and child '" + oxmChild + "' relationship");
634                             success = false;
635                         }
636                     }
637                 }
638             }
639
640             // Compare the dbEdgeRules against the OXM File
641             Set<String> dbEdgeRuleKeySet = dbEdgeRules.keySet();
642             for (String key : dbEdgeRuleKeySet) {
643                 Set<String> dbEdgeRulesChildren = dbEdgeRules.get(key);
644                 Set<String> oxmChildren = oxmSchemaFile.get(key);
645
646                 // Check if the parent vertex exists at all in the dbEdgeRules file
647                 if (oxmChildren == null || oxmChildren.isEmpty()) {
648                     for (String dbEdgeRuleChild : dbEdgeRulesChildren) {
649                         System.out.println("ERROR: oxms under directory '" + subDir.toString()
650                             + "' do not contain parent '" + key + "' and child '" + dbEdgeRuleChild
651                             + "' relationship");
652                     }
653                     success = false;
654                     continue;
655                 }
656
657                 // Compare both parent-child relationships between both files
658                 if (!dbEdgeRulesChildren.equals(oxmChildren)) {
659                     for (String dbEdgeRuleChild : dbEdgeRulesChildren) {
660                         if (!oxmChildren.contains(dbEdgeRuleChild)) {
661                             System.out.println("ERROR: oxms under directory '" + subDir.toString()
662                                 + "' do not contain parent '" + key + "' and child '"
663                                 + dbEdgeRuleChild + "' relationship");
664                             success = false;
665                         }
666                     }
667                 }
668             }
669         }
670         assertTrue(success);
671     }
672
673     /**
674      * Check dataOwner elements to ensure that they have ownerCheck side effect added to it.
675      *
676      */
677     @Test
678     public void testDataOwnerWithOwnerCheck() throws XPathExpressionException, IOException,
679         SAXException, ParserConfigurationException, ParseException {
680         List<File> fileList = getLatestFiles();
681
682         for (File file : fileList) {
683             Document xmlDocument = getDocument(file);
684             XPath xPath = XPathFactory.newInstance().newXPath();
685             String expression =
686                 "/xml-bindings/java-types/java-type/java-attributes/xml-element[@name='data-owner']";
687             NodeList nodeList =
688                 (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
689
690             List<String> typeMissingOwnerCheck = new ArrayList<>();
691
692             for (int i = 0; i < nodeList.getLength(); i++) {
693                 String type = nodeList.item(i).getParentNode().getParentNode().getAttributes()
694                     .getNamedItem("name").getNodeValue();
695                 NodeList xmlPropertiesList =
696                     ((Element) nodeList.item(i)).getElementsByTagName("xml-properties");
697
698                 boolean missingOwnerCheck = true;
699                 for (int j = 0; j < xmlPropertiesList.getLength(); j++) {
700                     NodeList xmlProperties =
701                         ((Element) xmlPropertiesList.item(j)).getElementsByTagName("xml-property");
702
703                     for (int k = 0; k < xmlProperties.getLength(); k++) {
704                         String xmlProp = xmlProperties.item(k).getAttributes().getNamedItem("name")
705                             .getNodeValue();
706
707                         if ("ownerCheck".equals(xmlProp)) {
708                             missingOwnerCheck = false;
709                             break;
710                         }
711                     }
712
713                     if (!missingOwnerCheck) {
714                         break;
715                     }
716                 }
717
718                 if (missingOwnerCheck) {
719                     typeMissingOwnerCheck.add(type);
720                 }
721             }
722
723             if (!typeMissingOwnerCheck.isEmpty()) {
724                 fail(file.getAbsolutePath().replaceAll(".*aai-schema", "") + ": "
725                     + String.join(", ", typeMissingOwnerCheck));
726             }
727         }
728     }
729
730     /**
731      * Null check for strings
732      * 
733      * @param s
734      * @return
735      */
736     private boolean isStringEmpty(String s) {
737         return (s == null || s.isEmpty()) ? true : false;
738     }
739
740     /**
741      * Creating a hashmap to map what child nodes are associated to which parent nodes
742      * according to the dbEdgeRules json files. A HashMap was chosen for the value of the map for
743      * O(1) lookup time.
744      * 
745      * @param from this variable will act as the key or value depending on the direction
746      * @param to this variable will act as the key or value depending on the direction
747      * @param direction dictates the direction of which vertex is dependent on which
748      * @return The map returned will act as a dictionary to keep track of the parent nodes. Value of
749      *         the map is a hashmap to help handle collision of multiple children to one parent
750      */
751     private Map<String, Set<String>> dbEdgeRulesMapPut(Map<String, Set<String>> dbEdgeRules,
752         String from, String to, String direction) {
753         if (isStringEmpty(from) || isStringEmpty(to) || isStringEmpty(direction))
754             return dbEdgeRules;
755
756         // Assigning the strings to parent and child for readability
757         String parent = "", child = "";
758         if (direction.equals(DBEDGERULES_OUT)) {
759             parent = from;
760             child = to;
761         } else if (direction.equals(DBEDGERULES_IN)) {
762             parent = to;
763             child = from;
764         }
765         // Add to the dbEdgeRules mapping
766         Set<String> children;
767         if (!dbEdgeRules.containsKey(parent)) {
768             children = new HashSet<>();
769             children.add(child);
770             dbEdgeRules.put(parent, children);
771         } else {
772             children = dbEdgeRules.get(parent);
773             children.add(child);
774             dbEdgeRules.put(parent, children);
775         }
776         return dbEdgeRules;
777     }
778
779     private List<File> getFiles() {
780         Path currentRelativePath = Paths.get("../aai-schema/src/main/resources/").toAbsolutePath();
781         return FileUtils
782             .listFiles(currentRelativePath.toFile(), new RegexFileFilter(".*\\.xml"),
783                 DirectoryFileFilter.DIRECTORY)
784             .stream().filter(file -> file.getAbsolutePath().contains("oxm"))
785             .filter(file -> !file.getAbsolutePath().contains("onap")) // skips onap for checks
786             .collect(Collectors.toList());
787     }
788
789     private List<File> getOxmSchemaFiles() {
790
791         Path currentRelativePath = Paths.get("../aai-schema/src/main/resources/").toAbsolutePath();
792         return FileUtils
793             .listFiles(currentRelativePath.toFile(), new RegexFileFilter(".*\\.xml"),
794                 DirectoryFileFilter.DIRECTORY)
795             .stream().filter(file -> file.getAbsolutePath().contains("oxm"))
796             .filter(file -> file.getAbsolutePath().contains("aai_schema_oxm"))
797             .filter(file -> !file.getAbsolutePath().contains("onap")) // skips onap for checks
798             .collect(Collectors.toList());
799
800     }
801
802     private List<File> getOnapOxmSchemaFiles() {
803
804         Path currentRelativePath = Paths.get("../aai-schema/src/main/resources/").toAbsolutePath();
805         return FileUtils
806             .listFiles(currentRelativePath.toFile(), new RegexFileFilter(".*\\.xml"),
807                 DirectoryFileFilter.DIRECTORY)
808             .stream().filter(file -> file.getAbsolutePath().contains("oxm"))
809             .filter(file -> file.getAbsolutePath().contains("aai_oxm"))
810             .collect(Collectors.toList());
811
812     }
813
814     private List<File> getAaiSchemaOxmFiles() {
815         Path currentRelativePath = Paths.get("../aai-schema/src/main/resources/").toAbsolutePath();
816         return FileUtils
817             .listFiles(currentRelativePath.toFile(), new RegexFileFilter(".*\\.xml"),
818                 DirectoryFileFilter.DIRECTORY)
819             .stream().filter(file -> file.getAbsolutePath().contains("oxm"))
820             .filter(file -> !file.getAbsolutePath().contains("onap")) // skips onap for checks
821             .collect(Collectors.toList());
822     }
823
824     private List<File> getDbEdgeRulesFiles() {
825         Path currentRelativePath = Paths.get("../aai-schema/src/main/resources/").toAbsolutePath();
826         return FileUtils
827             .listFiles(currentRelativePath.toFile(), new RegexFileFilter(".*\\.json"),
828                 DirectoryFileFilter.DIRECTORY)
829             .stream().filter(file -> file.getAbsolutePath().contains("DbEdgeRules"))
830             .filter(file -> !file.getAbsolutePath().contains("onap")) // skips onap for checks
831             .collect(Collectors.toList());
832     }
833
834     /**
835      * Finds all of the oxm files for the latest version.
836      * 
837      * @return list of the latest version of the oxm files.
838      */
839     private List<File> getLatestDbEdgeRulesFiles(String fileDirectory) {
840         List<String> latest = new ArrayList<>();
841         String currentRelativePath =
842             Paths.get("../aai-schema/src/main/resources/" + fileDirectory + "/dbedgerules")
843                 .toAbsolutePath().toString();
844         File[] oxms = new File(currentRelativePath).listFiles(File::isDirectory);
845         Arrays.stream(oxms).map(File::getAbsolutePath).max(new Comparator<String>() {
846             public int compare(String o1, String o2) {
847                 return extractInt(o1) - extractInt(o2);
848             }
849
850             int extractInt(String s) {
851                 String num = s.replaceAll("\\D", "");
852                 return num.isEmpty() ? 0 : Integer.parseInt(num);
853             }
854         }).ifPresent(latest::add);
855
856         List<File> latestFiles = new ArrayList<>();
857         latest.forEach(s -> FileUtils
858             .listFiles(new File(s), new RegexFileFilter(".*\\.json"), DirectoryFileFilter.DIRECTORY)
859             .stream().filter(file -> file.getAbsolutePath().contains("DbEdgeRules"))
860             .forEach(latestFiles::add));
861
862         return latestFiles;
863     }
864
865     /**
866      * Finds all of the oxm files for the latest version.
867      * 
868      * @return list of the latest version of the oxm files.
869      */
870     private List<File> getLatestFiles() {
871         List<String> latest = new ArrayList<>();
872         Path currentRelativePath = Paths.get("../aai-schema/src/main/resources/").toAbsolutePath();
873         List<File> subDirs =
874             Arrays.asList(currentRelativePath.toFile().listFiles(File::isDirectory));
875         for (File subDir : subDirs) {
876             String oxm = subDir.getAbsolutePath() + "/oxm";
877             File[] oxms = new File(oxm).listFiles(File::isDirectory);
878             Arrays.stream(oxms).map(File::getAbsolutePath).max(new Comparator<String>() {
879                 public int compare(String o1, String o2) {
880                     return extractInt(o1) - extractInt(o2);
881                 }
882
883                 int extractInt(String s) {
884                     String num = s.replaceAll("\\D", "");
885                     return num.isEmpty() ? 0 : Integer.parseInt(num);
886                 }
887             }).ifPresent(latest::add);
888         }
889
890         List<File> latestFiles = new ArrayList<>();
891         latest.forEach(s -> FileUtils
892             .listFiles(new File(s), new RegexFileFilter(".*\\.xml"), DirectoryFileFilter.DIRECTORY)
893             .stream().filter(file -> file.getAbsolutePath().contains("oxm"))
894             .forEach(latestFiles::add));
895
896         return latestFiles;
897     }
898
899     /**
900      * Finds all of the oxm files for the latest version.
901      * 
902      * @return list of the latest version of the oxm files.
903      */
904     private List<File> getLatestFiles(String fileDirectory) {
905         List<String> latest = new ArrayList<>();
906         String currentRelativePath =
907             Paths.get("../aai-schema/src/main/resources/" + fileDirectory + "/oxm").toAbsolutePath()
908                 .toString();
909         File[] oxms = new File(currentRelativePath).listFiles(File::isDirectory);
910         Arrays.stream(oxms).map(File::getAbsolutePath).max(new Comparator<String>() {
911             public int compare(String o1, String o2) {
912                 return extractInt(o1) - extractInt(o2);
913             }
914
915             int extractInt(String s) {
916                 String num = s.replaceAll("\\D", "");
917                 return num.isEmpty() ? 0 : Integer.parseInt(num);
918             }
919         }).ifPresent(latest::add);
920
921         List<File> latestFiles = new ArrayList<>();
922         latest.forEach(s -> FileUtils
923             .listFiles(new File(s), new RegexFileFilter(".*\\.xml"), DirectoryFileFilter.DIRECTORY)
924             .stream().filter(file -> file.getAbsolutePath().contains("oxm"))
925             .forEach(latestFiles::add));
926
927         return latestFiles;
928     }
929
930     // TODO test that all oxm xml are valid xml
931
932     public String printNodeList(NodeList nodeList, Document doc) throws IOException {
933         StringBuilder stringBuilder = new StringBuilder();
934         for (int i = 0; i < nodeList.getLength(); i++) {
935             stringBuilder.append(printNode(nodeList.item(i), doc)).append("\n");
936         }
937         return stringBuilder.toString();
938     }
939
940     public String printNode(Node node, Document document) throws IOException {
941         StringWriter stringWriter = new StringWriter();
942         return stringWriter.toString();
943
944     }
945
946     private Document getDocument(File file)
947         throws ParserConfigurationException, SAXException, IOException {
948         InputStream fileIS = new FileInputStream(file);
949         DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
950         DocumentBuilder builder = builderFactory.newDocumentBuilder();
951         return builder.parse(fileIS);
952     }
953
954 }