fix example string generation for types with isBasicLatin pattern 64/93464/2
authorCmarada, Michal <michal.cmarada@pantheon.tech>
Tue, 27 Oct 2020 13:30:10 +0000 (14:30 +0100)
committerTomas Cere <tomas.cere@pantheon.tech>
Mon, 2 Nov 2020 13:29:01 +0000 (13:29 +0000)
Generex generator fails to create example if pattern contains
{isBasicLatin} condition. The issue is fixed by replacing original
condition by range of allowed basic latin characters (0x00 - 0x7F).

JIRA: NETCONF-737
Signed-off-by: Cmarada, Michal <michal.cmarada@pantheon.tech>
Change-Id: I7bc5bf3621a40804122acd4604cfe8c132ffff24

restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/DefinitionGenerator.java
restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/SwaggerObjectTest.java
restconf/sal-rest-docgen/src/test/resources/yang/string-types.yang [new file with mode: 0644]

index a73e754c54a256b0baebe70100184bb67f136bff..6b7b73e36c3bec44646aba681ad043e6d7b9840b 100644 (file)
@@ -834,8 +834,14 @@ public class DefinitionGenerator {
             final PatternConstraint pattern = type.getPatternConstraints().iterator().next();
             String regex = pattern.getJavaPatternString();
             regex = regex.substring(1, regex.length() - 1);
-            final Generex generex = new Generex(regex);
-            setDefaultValue(property, generex.random());
+            String defaultValue = "";
+            try {
+                final Generex generex = new Generex(regex);
+                defaultValue = generex.random();
+            } catch (IllegalArgumentException ex) {
+                LOG.warn("Cannot create example string for type: {} with regex: {}.", stringType.getQName(), regex);
+            }
+            setDefaultValue(property, defaultValue);
         } else {
             setDefaultValue(property, "Some " + nodeName);
         }
index 8bace3ac7f971c5814b91b42b4c8dcda55a82c04..6de33841206ca864fdbe399787d9febfb85dea97 100644 (file)
@@ -54,4 +54,18 @@ public class SwaggerObjectTest {
         }
     }
 
+    @Test
+    public void testStringTypes() throws Exception {
+        Preconditions.checkArgument(this.helper.getModules() != null, "No modules found");
+        Module strTypes = this.helper.getModules().stream()
+                .filter(module -> module.getName().equals("string-types"))
+                .findFirst()
+                .orElseThrow(() -> new IllegalArgumentException("String types module not found"));
+
+        final DefinitionGenerator generator = new DefinitionGenerator();
+        final ObjectNode jsonObject = generator.convertToJsonSchema(strTypes, this.schemaContext, new DefinitionNames(),
+                ApiDocServiceImpl.OAversion.V2_0, true);
+
+        Assert.assertNotNull(jsonObject);
+    }
 }
diff --git a/restconf/sal-rest-docgen/src/test/resources/yang/string-types.yang b/restconf/sal-rest-docgen/src/test/resources/yang/string-types.yang
new file mode 100644 (file)
index 0000000..3283b1d
--- /dev/null
@@ -0,0 +1,94 @@
+module string-types {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:test:string:types";
+    prefix "str-tp";
+
+    typedef DisplayString {
+        type string {
+            length "0..255";
+            pattern "((\p{IsBasicLatin}{0,255}))";
+        }
+    }
+
+    typedef PhysAddress {
+        type string {
+            pattern "((([0-9A-Fa-f]{2}){1}):)";
+        }
+    }
+
+    typedef MacAddress {
+        type string {
+            length "6";
+            pattern "((([0-9A-Fa-f]{2}){1}):)";
+        }
+    }
+
+    typedef DateAndTime {
+        type string {
+            length "8|11";
+            pattern "((0|[1-9](([0-9]){0,4}))-(0|[1-9](([0-9]){0,2}))-(0|[1-9](([0-9]){0,2})),(0|[1-9](([0-9]){0,2})):(0|[1-9](([0-9]){0,2})):(0|[1-9](([0-9]){0,2})).(0|[1-9](([0-9]){0,2})),((\p{IsBasicLatin}{1})(0|[1-9](([0-9]){0,2})):(0|[1-9](([0-9]){0,2})))?)";
+        }
+    }
+
+    typedef Arrows {
+        type string {
+            length "10";
+            pattern "((\p{IsArrows}{5,255}))";
+        }
+    }
+
+    typedef Thai {
+        type string {
+            length "10";
+            pattern "((\p{IsThai}{8,255}))";
+        }
+    }
+
+    typedef BraillePatterns {
+        type string {
+            length "10";
+            pattern "((\p{IsBraillePatterns}{4,255}))";
+        }
+    }
+
+    typedef MathematicalOperators {
+        type string {
+            length "10";
+            pattern "((\p{IsMathematicalOperators}{4,255}))";
+        }
+    }
+
+    container test {
+        description "Tests various combinations of regex expressions found in snmp yang models,
+                     which are causing problems because of isBasicLatin expression.
+
+                     According to https://unicode.org/charts/PDF/U0000.pdf basic latin characters are in range
+                     0x00-0x7F ([\x00-\xFF] or [\u0000-\u00FF]). This means it should be safe to replace isBasicLatin
+                     in regex expressions for characters in this range.";
+
+        leaf display-string {
+                type DisplayString;
+            }
+        leaf phys-address {
+                type PhysAddress;
+            }
+        leaf mac-address {
+            type MacAddress;
+        }
+        leaf date-and-time {
+            type DateAndTime;
+        }
+        leaf arrows {
+            type Arrows;
+        }
+        leaf thai {
+            type Thai;
+        }
+        leaf braille-patterns {
+            type BraillePatterns;
+        }
+        leaf mathematical-operators {
+            type MathematicalOperators;
+        }
+    }
+}
\ No newline at end of file