Skip to content

Commit

Permalink
Fix for #57 (#58)
Browse files Browse the repository at this point in the history
fix for #57
  • Loading branch information
bartoszm authored Sep 13, 2022
1 parent ea19702 commit 47f8512
Show file tree
Hide file tree
Showing 19 changed files with 466 additions and 351 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
*.yaml
.idea/
**/*.iml
target/
Expand Down
54 changes: 39 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,50 @@ we have prepared our own version of the code generator. You might run it standal

You can easily run ```SwaggerGenerator``` from the command-line:
```
java -jar ~/.m2/repository/com/mrv/yangtools/swagger-generator-cli/1.0-SNAPSHOT/swagger-generator-cli-1.0-SNAPSHOT-executable.jar
java -jar swagger-generator-cli-<<version>>-executable.jar
Argument "module ..." is required
module ... : List of YANG module names to generate in swagger output
-output file : File to generate, containing the output - defaults to stdout
(default: )
-yang-dir path : Directory to search for YANG modules - defaults to current
directory (default: )
-api-version string : The current version of your API (default: 1.0)
-format enum : The output format (options: YAML, JSON) (default: YAML)
-content-type string: Content type the API generates / consumes (default: application/yang-data+json)
-simplify-hierarchy : Use it to generate Swagger which with simplified inheritence model which can be used with standard code generators. (default: false)
-use-namespaces : Use namespaces in resource URI (default: false)
-fullCrud : If the flag is set to false path are generated for GET operations only. (default: true)
-elements : Define YANG elements to focus on. (default: DATA + RPC)
-authentication : Authentication definition (options: BASIC, NONE) (default: NONE)
module ... : List of YANG module names to generate
in swagger output
-api-version file : Version of api generated - default 1.0
(default: 1.0)
-authentication [BASIC | NONE] : Authentication definition (default:
NONE)
-content-type VAL : Content type the API generates /
consumes - default application/yang-dat
a+json (default: application/yang-data+
json)
-elements [DATA | RPC | DATA_AND_RPC] : Define YANG elements to focus on.
Defaul DATA + RPC (default:
DATA_AND_RPC)
-format [YAML | JSON] : Output format of generated file -
defaults to yaml with options of json
or yaml (default: YAML)
-fullCrud : If the flag is set to false path are
generated for GET operations only.
Default true (default: true)
-output file : File to generate, containing the
output - defaults to stdout (default: )
-reuse-groupings : Use it to generate Swagger which
attempts to reuse structurally
identical grouping types. Default
false (default: false)
-simplify-hierarchy : Use it to generate Swagger which with
simplified inheritence model which can
be used with standard code generators.
Default false (default: false)
-use-namespaces : Use namespaces in resource URI
(default: false)
-use-odl-path-format : Select to use bierman-02 RESTCONF path
format. Default false (default: false)
-yang-dir path : Directory to search for YANG modules -
defaults to current directory.
Multiple dirs might be separated by
system path separator (default: )
```

For example:
```
java -jar ~/.m2/repository/com/mrv/yangtools/swagger-generator-cli/1.0-SNAPSHOT/swagger-generator-cli-1.0-SNAPSHOT-executable.jar \
java -jar swagger-generator-cli-<<version>>-executable.jar \
-yang-dir examples/build-standalone/src/main/resources \
-output swagger.yaml \
mef-services
Expand Down
14 changes: 10 additions & 4 deletions cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@
</parent>
<modelVersion>4.0.0</modelVersion>

<properties>
<swagger.version>1.5.9</swagger.version>
</properties>

<artifactId>swagger-generator-cli</artifactId>

<dependencies>
Expand All @@ -34,6 +30,16 @@
<artifactId>args4j</artifactId>
<version>2.33</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-parser</artifactId>
<version>1.0.61</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
16 changes: 11 additions & 5 deletions cli/src/main/java/com/mrv/yangtools/codegen/main/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ public class Main {
@Option(name = "-simplify-hierarchy", usage = "Use it to generate Swagger which with simplified inheritence model which can be used with standard code generators. Default false")
public boolean simplified = false;

@Option(name = "-reuse-groupings", usage = "Use it to generate Swagger which attempts to reuse structurally identical grouping types. Default false")
public boolean reuseGroupings = false;

@Option(name = "-use-namespaces", usage="Use namespaces in resource URI")
public boolean useNamespaces = false;

Expand All @@ -84,7 +87,7 @@ public enum AuthenticationMechanism {
BASIC, NONE
}

OutputStream out = System.out;
public OutputStream out = System.out;

public static void main(String[] args) {

Expand All @@ -104,13 +107,13 @@ public static void main(String[] args) {
}
}

protected void init() throws FileNotFoundException {
void init() throws FileNotFoundException {
if (output != null && output.trim().length() > 0) {
out = new FileOutputStream(output);
}
}

protected void generate() throws IOException, ReactorException {
void generate() throws IOException, ReactorException {
final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.yang");

final SchemaContext context = buildSchemaContext(yangDir, p -> matcher.matches(p.getFileName()));
Expand Down Expand Up @@ -149,13 +152,16 @@ protected void generate() throws IOException, ReactorException {
.pathHandler(pathHandler)
.elements(map(elementType));

generator
.appendPostProcessor(new CollapseTypes());


if(AuthenticationMechanism.BASIC.equals(authenticationMechanism)) {
generator.appendPostProcessor(new AddSecurityDefinitions().withSecurityDefinition("api_sec", new BasicAuthDefinition()));
}

if(reuseGroupings) {
generator.appendPostProcessor(new CollapseTypes());
}

if(simplified) {
generator.appendPostProcessor(new SingleParentInheritenceModel());
}
Expand Down
82 changes: 82 additions & 0 deletions cli/src/test/java/com/mrv/yangtools/codegen/main/Issue57.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.mrv.yangtools.codegen.main;

import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
import org.junit.Assert;
import org.junit.Test;
import org.kohsuke.args4j.CmdLineParser;

import java.io.ByteArrayOutputStream;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Issue57 {
private static String path;

static {
try {
path = Paths.get(Issue57.class.getResource("/bug_57/").toURI()).toAbsolutePath().toString();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}

@Test
public void testRegular() {

List<String> args = Stream.of(
"-yang-dir",
path
).collect(Collectors.toList());

Swagger swagger = runParser(args);
assertContainsOnly(swagger, s -> s.endsWith("Input"),
"objects.createobject.Input","objects.updateobject.Input");
}

@Test
public void testOptimized() {

List<String> args = Stream.of(
"-reuse-groupings",
"-yang-dir",
path
).collect(Collectors.toList());

Swagger swagger = runParser(args);

assertContainsOnly(swagger, s -> s.endsWith("Input"), "objects.createobject.Input");
}

private void assertContainsOnly(Swagger swagger, Predicate<String> filterDefs, String... name) {
Set<String> result = swagger.getDefinitions().keySet().stream()
.filter(filterDefs)
.collect(Collectors.toSet());
Set<String> expected = Stream.of(name)
.collect(Collectors.toSet());
Assert.assertEquals(expected, result);
}

private Swagger runParser(List<String> args) {
Main main = new Main();
CmdLineParser parser = new CmdLineParser(main);
try {
parser.parseArgument(args);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
main.out = baos;
main.init();
main.generate();

return new SwaggerParser().parse(new String(baos.toByteArray(), StandardCharsets.UTF_8));
} catch (Exception e) {
throw new RuntimeException(e);
}

}
}
36 changes: 36 additions & 0 deletions cli/src/test/resources/bug_57/input.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module objects {

yang-version "1.1";
namespace "urn:objects";
prefix "obje";

grouping id_1 {
leaf id_1 {
type "string";
}
}

grouping id_2 {
leaf id_2 {
type "string";
}
}

rpc create-object {
input {
uses id_1;
uses id_2;
}
output {
}
}

rpc update-object {
input {
uses id_1;
uses id_2;
}
output {
}
}
}
Loading

0 comments on commit 47f8512

Please sign in to comment.