-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit d513c25
Showing
4 changed files
with
340 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>com.amartus.y2s</groupId> | ||
<artifactId>yang2swagger-tapi-cli</artifactId> | ||
<version>1.0</version> | ||
<properties> | ||
<y2s.version>1.1.7</y2s.version> | ||
</properties> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.3</version> | ||
<configuration> | ||
<source>1.8</source> | ||
<target>1.8</target> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-shade-plugin</artifactId> | ||
<version>2.4.3</version> | ||
<configuration></configuration> | ||
<executions> | ||
<execution> | ||
<goals> | ||
<goal>shade</goal> | ||
</goals> | ||
<phase>package</phase> | ||
<configuration> | ||
<transformers> | ||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> | ||
<mainClass>com.amartus.y2s.Generator</mainClass> | ||
</transformer> | ||
</transformers> | ||
<shadedArtifactAttached>true</shadedArtifactAttached> | ||
<shadedClassifierName>cli</shadedClassifierName> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>com.mrv.yangtools</groupId> | ||
<artifactId>swagger-generator</artifactId> | ||
<version>${y2s.version}</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>com.mrv.yangtools</groupId> | ||
<artifactId>common</artifactId> | ||
<version>${y2s.version}</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>args4j</groupId> | ||
<artifactId>args4j</artifactId> | ||
<version>2.33</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.swagger</groupId> | ||
<artifactId>swagger-parser</artifactId> | ||
<version>1.0.22</version> | ||
</dependency> | ||
</dependencies> | ||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* Copyright (c) 2018 Amartus. All rights reserved. | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v1.0 which accompanies this distribution, | ||
* and is available at http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Contributors: | ||
* Bartosz Michalik <bartosz.michalik@amartus.com> | ||
*/ | ||
package com.amartus.y2s; | ||
|
||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import com.fasterxml.jackson.core.JsonFactory; | ||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; | ||
import com.mrv.yangtools.codegen.SwaggerGenerator; | ||
import com.mrv.yangtools.codegen.impl.postprocessor.RemoveUnusedDefinitions; | ||
import com.mrv.yangtools.codegen.impl.postprocessor.SingleParentInheritenceModel; | ||
import com.mrv.yangtools.codegen.impl.postprocessor.SortComplexModels; | ||
import com.mrv.yangtools.common.SwaggerUtils; | ||
import io.swagger.models.Swagger; | ||
import io.swagger.parser.Swagger20Parser; | ||
import org.kohsuke.args4j.CmdLineException; | ||
import org.kohsuke.args4j.CmdLineParser; | ||
import org.kohsuke.args4j.Option; | ||
|
||
import java.io.*; | ||
|
||
/** | ||
* @author bartosz.michalik@amartus.com | ||
*/ | ||
public class Converter { | ||
@Option(name = "-output", usage = "File to generate, containing the output - defaults to stdout", metaVar = "file") | ||
public String output = ""; | ||
|
||
@Option(name = "-input", usage = "File with original swagger, containing the input - defaults to stdin", metaVar = "file") | ||
public String input = ""; | ||
|
||
@Option(name="-format", usage = "Define format for swagger input/output") | ||
public SwaggerGenerator.Format format = SwaggerGenerator.Format.YAML; | ||
private ObjectMapper mapper; | ||
|
||
|
||
public static void main(String[] args) throws IOException { | ||
Converter cli = new Converter(); | ||
CmdLineParser parser = new CmdLineParser(cli); | ||
try { | ||
parser.parseArgument(args); | ||
cli.convert(); | ||
} catch (CmdLineException e) { | ||
System.err.println(e.getMessage()); | ||
parser.printUsage(System.err); | ||
} | ||
|
||
|
||
} | ||
|
||
private void convert() throws IOException { | ||
mapper = format == SwaggerGenerator.Format.JSON ? new ObjectMapper(new JsonFactory()) | ||
: new ObjectMapper(new YAMLFactory()); | ||
|
||
try( | ||
Reader in = "".equals(input) ? new InputStreamReader(System.in) : new FileReader(input); | ||
Writer out = "".equals(output) ? new OutputStreamWriter(System.out) : new FileWriter(output) | ||
) { | ||
JsonNode jsonNode = mapper.reader().readTree(in); | ||
|
||
Swagger swagger = new Swagger20Parser().read(jsonNode); | ||
new SingleParentInheritenceModel().andThen(new RemoveUnusedDefinitions()).accept(swagger); | ||
|
||
new SortComplexModels().accept(swagger); | ||
|
||
swagger.setDefinitions(SwaggerUtils.sortMap(swagger.getDefinitions())); | ||
swagger.setPaths(SwaggerUtils.sortMap(swagger.getPaths())); | ||
|
||
write(out, swagger); | ||
|
||
} | ||
} | ||
|
||
private void write(Writer target, Swagger swagger) throws IOException { | ||
|
||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); | ||
mapper.writeValue(target, swagger); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
/* | ||
* Copyright (c) 2018 Amartus. All rights reserved. | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v1.0 which accompanies this distribution, | ||
* and is available at http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Contributors: | ||
* Bartosz Michalik <bartosz.michalik@amartus.com> | ||
*/ | ||
package com.amartus.y2s; | ||
|
||
import com.mrv.yangtools.codegen.SwaggerGenerator; | ||
import com.mrv.yangtools.codegen.impl.path.rfc8040.PathHandlerBuilder; | ||
import com.mrv.yangtools.codegen.impl.postprocessor.PathPrunner; | ||
import com.mrv.yangtools.codegen.impl.postprocessor.RemoveUnusedDefinitions; | ||
import com.mrv.yangtools.codegen.impl.postprocessor.SingleParentInheritenceModel; | ||
import com.mrv.yangtools.common.ContextHelper; | ||
import org.kohsuke.args4j.Argument; | ||
import org.kohsuke.args4j.CmdLineException; | ||
import org.kohsuke.args4j.CmdLineParser; | ||
import org.kohsuke.args4j.Option; | ||
import org.opendaylight.yangtools.yang.model.api.Module; | ||
import org.opendaylight.yangtools.yang.model.api.SchemaContext; | ||
import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.io.*; | ||
import java.nio.file.FileSystems; | ||
import java.nio.file.Path; | ||
import java.nio.file.PathMatcher; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.function.Predicate; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
/** | ||
* @author bartosz.michalik@amartus.com | ||
*/ | ||
public class Generator { | ||
private static final Logger log = LoggerFactory.getLogger(Generator.class); | ||
|
||
@Option(name = "-yang-dir", usage = "Directory to search for YANG modules - defaults to current directory. " + | ||
"Multiple dirs might be separated by system path separator", metaVar = "path") | ||
public String yangDir = ""; | ||
|
||
@Option(name = "-output", usage = "File to generate, containing the output - defaults to stdout", metaVar = "file") | ||
public String output = ""; | ||
|
||
@Argument(multiValued = true, usage = "List of YANG module names to generate in swagger output", metaVar = "module ...") | ||
List<String> modules; | ||
|
||
@Option(name = "-format", usage = "Output format of generated file - defaults to yaml with options of json or yaml", metaVar = "enum") | ||
public SwaggerGenerator.Format outputFormat = SwaggerGenerator.Format.YAML; | ||
|
||
@Option(name = "-api-version", usage = "Version of api generated - default 1.0", metaVar = "version") | ||
public String apiVersion = "1.0"; | ||
|
||
// RESTCONF uses yang-data+json or yang-data+xml as the content type. | ||
@Option(name= "-content-type", usage = "Content type the API generates / consumes - default application/yang-data+json") | ||
public String contentType = "application/yang-data+json"; | ||
|
||
@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 = "-use-namespaces", usage="Use namespaces in resource URI") | ||
public boolean useNamespaces = false; | ||
|
||
OutputStream out = System.out; | ||
|
||
|
||
public enum ElementType { | ||
DATA, RPC, DATA_AND_RPC; | ||
} | ||
|
||
@Option(name="-elements", usage="Define YANG elements to focus on. Defaul DATA + RPC") | ||
public ElementType elementType = ElementType.DATA_AND_RPC; | ||
|
||
public static void main(String[] args) { | ||
Generator cli = new Generator(); | ||
CmdLineParser parser = new CmdLineParser(cli); | ||
|
||
try { | ||
parser.parseArgument(args); | ||
cli.init(); | ||
cli.generate(); | ||
} catch (CmdLineException e) { | ||
System.err.println(e.getMessage()); | ||
parser.printUsage(System.err); | ||
} catch (Throwable t) { | ||
log.error("Error while generating Swagger", t); | ||
} | ||
} | ||
|
||
protected void init() throws FileNotFoundException { | ||
if (output != null && output.trim().length() > 0) { | ||
out = new FileOutputStream(output); | ||
} | ||
} | ||
|
||
protected void generate() throws IOException, ReactorException { | ||
final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.yang"); | ||
|
||
final SchemaContext context = buildSchemaContext(yangDir, p -> matcher.matches(p.getFileName())); | ||
final Set<Module> toGenerate = context.getModules().stream().filter(m -> modules == null || modules.contains(m.getName())) | ||
.collect(Collectors.toSet()); | ||
|
||
|
||
PathHandlerBuilder pathHandler = new PathHandlerBuilder().withoutFullCrud(); | ||
if(useNamespaces) | ||
pathHandler = pathHandler.useModuleName(); | ||
|
||
|
||
final SwaggerGenerator generator = new SwaggerGenerator(context, toGenerate) | ||
.version(apiVersion) | ||
.format(outputFormat).consumes(contentType).produces(contentType) | ||
.host("localhost:1234").elements(map(elementType)) | ||
.pathHandler(pathHandler) | ||
.appendPostProcessor(new PathPrunner("/operations").withType("tapi.common.GlobalClass")); | ||
|
||
if(simplified) { | ||
generator.appendPostProcessor(new SingleParentInheritenceModel()); | ||
} | ||
|
||
|
||
generator.appendPostProcessor(new RemoveUnusedDefinitions()); | ||
|
||
generator.generate(new OutputStreamWriter(out)); | ||
} | ||
|
||
private SwaggerGenerator.Elements[] map(ElementType elementType) { | ||
switch(elementType) { | ||
case DATA: | ||
return new SwaggerGenerator.Elements[]{SwaggerGenerator.Elements.DATA}; | ||
case RPC: | ||
return new SwaggerGenerator.Elements[]{SwaggerGenerator.Elements.RCP}; | ||
case DATA_AND_RPC: | ||
default: | ||
return new SwaggerGenerator.Elements[]{SwaggerGenerator.Elements.DATA, SwaggerGenerator.Elements.RCP}; | ||
} | ||
|
||
} | ||
|
||
protected SchemaContext buildSchemaContext(String dir, Predicate<Path> accept) | ||
throws ReactorException { | ||
if(dir.contains(File.pathSeparator)) { | ||
return ContextHelper.getFromDir(Arrays.stream(dir.split(File.pathSeparator)).map(s -> FileSystems.getDefault().getPath(s)), accept); | ||
} else { | ||
return ContextHelper.getFromDir(Stream.of(FileSystems.getDefault().getPath(dir)), accept); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<!-- | ||
~ Copyright (c) 2016 MRV Communications, Inc. All rights reserved. | ||
~ This program and the accompanying materials are made available under the | ||
~ terms of the Eclipse Public License v1.0 which accompanies this distribution, | ||
~ and is available at http://www.eclipse.org/legal/epl-v10.html | ||
~ | ||
~ Contributors: | ||
~ Christopher Murch <cmurch@mrv.com> | ||
~ Bartosz Michalik <bartosz.michalik@amartus.com> | ||
--> | ||
|
||
<configuration> | ||
<appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender"> | ||
<target>System.err</target> | ||
<encoder> | ||
<pattern>%date [%thread] %-5level %logger{36} - %msg%n</pattern> | ||
</encoder> | ||
</appender> | ||
|
||
<logger name="root" level="INFO"> | ||
<appender-ref ref="STDERR" /> | ||
</logger> | ||
</configuration> |