Skip to content

Repository files navigation

Overview

This is the next gen (v4) of AutoRest Java generator. It's built on AutoRest v3, written in Java, and supports OpenAPI3. It generates clients that work with com.azure:azure-core.

Prerequisites

You need to have the following installed on your machine:

  • Node.JS v10.x - v13.x
  • Java 8+
  • Maven 3.x

You need to have autorest installed through NPM:

npm install -g autorest

Usage

To use the latest released preview(https://github.com/Azure/autorest.java/releases), run

autorest --java
--use:@autorest/java@4.0.x
--input-file:path/to/specs.json
--output-folder:where/to/generate/java/files
--namespace:specified.java.package

The first time running it will take a little longer to download and install all the components.

To build from source code, clone this repo and checkout to v4 branch. Make sure all prerequisites are met, and run

mvn package -P local

This will build a file javagen-jar-with-dependencies.jar under javagen module, a preprocess-jar-with-dependencies.jar under preprocessor module, a fluentgen-jar-with-dependencies.jar under fluentgen module, and a fluentnamer-jar-with-dependencies.jar under fluentnamer module.

And then run AutoRest

autorest --java
--use:where/this/repo/is/cloned/autorest.java
--input-file:path/to/specs.json
--output-folder:where/to/generate/java/files
--namespace:specified.java.package

Java files will be generated under where/to/generate/java/files/src/main/java/specified/java/package.

To debug, add --java.debugger to the argument list. The JVM will suspend at the beginning of the execution. Then attach a remote debugger in your IDE to localhost:5005. Make sure you detach the debugger before killing the AutoRest process. Otherwise it will fail to shutdown the JVM and leave it orphaned. (which can be killed in the Task Manager)

Settings

Settings can be provided on the command line through --name:value or in a README file through name: value. The list of settings for AutoRest in general can be found at https://github.com/Azure/autorest/blob/main/docs/user/command-line-interface.md. The list of settings for AutoRest.Java specifically are listed below:

Option Description
--enable-xmlGenerates models and clients that can be sent in XML over the wire. Default is false
--client-side-validationsGenerate validations for required parameters and required model properties. Default is false.
--generate-client-as-implAppend "Impl" to the names of service clients and method groups and place them in the implementation sub-package. Default is false.
--generate-client-interfacesImplies --generate-client-as-impl and generates interfaces for all the "Impl"s. Default is false.
--generate-sync-async-clientsImplies --generate-client-as-impl and generates sync and async convenience layer clients for all the "Impl"s. Default is false.
--implementation-subpackage=STRINGThe sub-package that the Service client and Method Group client implementation classes will be put into. Default is implementation.
--models-subpackage=STRINGThe sub-package that Enums, Exceptions, and Model types will be put into. Default is models.
--add-context-parameterIndicates whether the com.azure.core.util.Context parameter should be included in generated proxy methods. Default is false.
--context-client-method-parameterImplies --add-context-parameter and indicates whether the com.azure.core.util.Context parameter should also be included in generated client methods. Default is false.
--sync-methods=all|essential|noneSpecifies mode for generating sync wrappers. Supported value are
essential - generates only one sync returning body or header (default)
all - generates one sync method for each async method
none - does not generate any sync methods
--required-parameter-client-methodsIndicates whether client method overloads with only required parameters should be generated. Default is false.
--custom-types=COMMA,SEPARATED,STRINGSSpecifies a list of files to put in the package specified in --custom-types-subpackage.
--custom-types-subpackage=STRINGThe sub-package that the custom types should be generated in. The types that custom types reference, or inherit from will also be automatically moved to this sub-package. Recommended usage: You can set this value to models and set --models-subpackage=implementation.modelsto generate models to implementation.models by default and pick specific models to be public through --custom-types=.
--client-type-prefix=STRINGThe prefix that will be added to each generated client type.
--model-override-setter-from-superclassIndicates whether to override the superclass setter method in model. Default is false.
--service-interface-as-publicIndicates whether to generate service interfaces as public. This resolves SecurityManager issues to prevent reflectively access non-public APIs. Default is false.
--require-x-ms-flattened-to-flattenIndicates whether x-ms-flattened is required to annotated a class with @JsonFlatten if the discriminator has . in its name. Default is false.
--client-flattened-annotation-target=TYPE,FIELD,NONEIndicates the target of @JsonFlatten annotation for x-ms-client-flatten. Default is TYPE. If value is FIELD, it implies require-x-ms-flattened-to-flatten=true.
--skip-formattingIndicates whether to skip formatting Java file. Default is false.

Additional settings for Fluent

fluent option enables the generator extension for Azure Management Libraries for Java.

Following settings only works when fluent option is specified.

OptionDescription
--fluentEnum. LITE for Fluent Lite; PREMIUM for Fluent Premium. Case insensitive. Default is PREMIUM if provided as other values.
--fluent-subpackageString. The sub-package that vanilla client and builder will be put into. Default is fluent.
--pom-fileString. Name for Maven POM file. Default is pom.xml.
--package-versionString. Version number for Maven artifact. Default is 1.0.0-beta.1.
--service-nameString. Service name used in Manager class and other documentations. If not provided, service name is deduced from title configure (from swagger or readme).
--sdk-integrationBoolean. Integrate to azure-sdk-for-java. Default is false. Provide output-folder as absolute path for best performance.
--generate-samplesBoolean. Generate samples from x-ms-examples in swagger. Default is false.
--add-innerCSV. Treat as inner class (move to fluent.models namespace, append Inner to class name).
--remove-innerCSV. Exclude from inner classes.
--rename-modelCSV. Rename classes. Each item is of pattern from:to.
--remove-modelCSV. Remove classes.
--preserve-modelCSV. Preserve classes from clean-up.
--name-for-ungrouped-operationsString. Name for ungrouped operation group. Default to ResourceProviders for Lite.

fluent option will change the default value for some vanilla options. For example, generate-client-interfaces, context-client-method-parameter, required-parameter-client-methods, model-override-setter-from-superclass option is by default true.

The code formatter would require Java 11+ runtime.

Customizations

To set up customizations, create a Maven project with dependency:

<dependency>
<groupId>com.azure.tools</groupId>
<artifactId>azure-autorest-customization</artifactId>
<version>1.0.0-beta.4</version>
</dependency>

Create a customization class extending from com.azure.autorest.customization.Customization and override the void customize(LibraryCustomization) method. You will have access to a LibraryCustomization class where you will be able to customize the generated Java code before it's written to the disk. Currently, the following customizations are supported:

Navigate through the packages and classes

There are 4 customization classes currently available, LibraryCustomization, PackageCustomization, ClassCustomization and JavadocCustomization. From a given LibraryCustomization, you can navigate through the packages and classes intuitively with the following methods:

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
/* code to customize on the package level */ClassCustomizationfoo = models.getClass("Foo");
/* code to customize the Foo class */JavadocCustomizationgetBarJavadoc = foo.methodJavadoc("getBar");
/* code to customize javadoc for getBar() method */
}

Change class modifier

A class Foo

publicclassFoo {
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationfoo = models.getClass("Foo");
foo.changeClassModifier(""); // change to package private
}

will generate

classFoo {
}

Change method modifier

A method getBar in the Foo class

publicclassFoo {
privateBarbar;
publicBargetBar() {
returnthis.bar;
}
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationfoo = models.getClass("Foo");
foo.changeMethodModifier("getBar", "private"); // change to private
}

will generate

publicclassFoo {
privateBarbar;
privateBargetBar() {
returnthis.bar;
}
}

Change method return type

You can change a method's return type, and pass a String formatter to transform the original return value statement. If the original return type is void, simply pass the full return value String expression in place of the String formatter; if the new return type is void, simply pass null.

A method getId in the Foo class

publicclassFoo {
privateStringid;
publicStringgetId() {
returnthis.id;
}
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationfoo = models.getClass("Foo");
foo.changeMethodReturnType("getId", "UUID", "UUID.fromString(%s)"); // change to private
}

will generate

publicclassFoo {
privateStringid;
publicUUIDgetId() {
StringreturnValue = this.id;
returnUUID.fromString(returnValue);
}
}

The UUID class will be automatically imported.

Add an annotation to a class

A class Foo

publicclassFoo {
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationfoo = models.getClass("Foo");
foo.addClassAnnotation("JsonFlatten");
}

will generate

@JsonFlattenpublicclassFoo {
}

The JsonFlatten class will be automatically imported.

Add an annotation to a method

A method getBar in the Foo class

publicclassFoo {
privateBarbar;
publicBargetBar() {
returnthis.bar;
}
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationfoo = models.getClass("Foo");
foo.addMethodAnnotation("getBar", "Deprecated");
}

will generate

publicclassFoo {
privateBarbar;
@DeprecatedpublicBargetBar() {
returnthis.bar;
}
}

The Deprecated class will be automatically imported.

Remove an annotation from a class

A class Foo

@FluentpublicclassFoo {
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationfoo = models.getClass("Foo");
foo.removeClassAnnotation("Fluent");
}

will generate

publicclassFoo {
}

Refactor: Rename a class

A class Foo

publicclassFoo {
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
models.renameClass("Foo", "FooInfo");
}

will generate

classFooInfo {
}

All references of Foo will be modified to FooInfo. When a valid value is provided, this customization is guaranteed to not break the build.

Refactor: Rename a method

A method isSupportsUnicode in the Foo class

publicclassFoo {
privatebooleansupportsUnicode;
publicbooleanisSupportsUnicode() {
returnthis.supportsUnicode;
}
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationfoo = models.getClass("Foo");
foo.renameMethod("isSupportsUnicode", "supportsUnicode");
}

will generate

publicclassFoo {
privatebooleansupportsUnicode;
publicbooleansupportsUnicode() {
returnthis.supportsUnicode;
}
}

All references of isSupportsUnicode() will be modified to supportsUnicode(). When a valid value is provided, this customization is guaranteed to not break the build.

Refactor: Generate the getter and setter methods for a property

A property active in the Foo class

publicclassFoo {
privatebooleanactive;
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationfoo = models.getClass("Foo");
foo.generateGetterAndSetter("active");
}

will generate

publicclassFoo {
privatebooleanactive;
publicbooleanisActive() {
returnthis.active;
}
publicFoosetActive(booleanactive) {
this.active = active;
returnthis;
}
}

If the class already contains a getter or a setter method, the current method will be kept. This customization is guaranteed to not break the build.

Refactor: Rename a property and its corresponding getter and setter methods

A property whitelist in the Foo class

publicclassFoo {
privateList<String> whiteList;
publicList<String> getWhiteList() {
returnthis.whiteList;
}
publicFoosetWhiteList(List<String> whiteList) {
this.whiteList = whiteList;
returnthis;
}
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationfoo = models.getClass("Foo");
foo.renameProperty("whiteList", "allowList");
}

will generate

publicclassFoo {
privateList<String> allowList;
publicList<String> getAllowList() {
returnthis.allowList;
}
publicFoosetAllowList(List<String> allowList) {
this.allowList = allowList;
returnthis;
}
}

This customization is guaranteed to not break the build.

Refactor: Rename an enum member name

An enum member JPG in an enum class ImageFileType:

publicenumImageFileType {
GIF("gif"),
JPG("jpg"),
TIFF("tiff"),
PNG("png");
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationimageFileType = models.getClass("ImageFileType");
foo.renameEnumMember("JPG", "JPEG");
}

will generate

publicenumImageFileType {
GIF("gif"),
JPEG("jpg"),
TIFF("tiff"),
PNG("png");
}

This customization is guaranteed to not break the build.

Javadoc: Set the description for a class / method

A class Foo

/** Class Foo. */publicclassFoo {
privatebooleanactive;
publicbooleanisActive() {
returnthis.active;
}
publicFoosetActive(booleanactive) {
this.active = active;
returnthis;
}
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationfoo = models.getClass("Foo");
foo.classJavadoc().setDescription("A Foo object stored in Azure.")
foo.methodJavadoc("setActive").setDescription("Set the active value.");
}

will generate

/** * A Foo object stored in Azure. */publicclassFoo {
privatebooleanactive;
publicbooleanisActive() {
returnthis.active;
}
/** * Set the active value. */publicFoosetActive(booleanactive) {
this.active = active;
returnthis;
}
}

Javadoc: Set / remove a parameter's javadoc on a method

A class Foo

publicclassFoo {
privatebooleanactive;
publicbooleanisActive() {
returnthis.active;
}
/** * Set the active value. */publicFoosetActive(booleanactive) {
this.active = active;
returnthis;
}
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationfoo = models.getClass("Foo");
foo.methodJavadoc("setActive").setParam("active", "if the foo object is in active state");
}

will generate

publicclassFoo {
privatebooleanactive;
publicbooleanisActive() {
returnthis.active;
}
/** * Set the active value. * * @param active if the foo object is in active state */publicFoosetActive(booleanactive) {
this.active = active;
returnthis;
}
}

Javadoc: Set the return javadoc on a method

A Foo class

publicclassFoo {
privatebooleanactive;
publicbooleanisActive() {
returnthis.active;
}
/** * Set the active value. * * @param active if the foo object is in active state */publicFoosetActive(booleanactive) {
this.active = active;
returnthis;
}
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationmodels = customization.getPackage("com.azure.myservice.models");
ClassCustomizationfoo = models.getClass("Foo");
foo.methodJavadoc("setActive").setReturn("the current foo object");
}

will generate

publicclassFoo {
privatebooleanactive;
publicbooleanisActive() {
returnthis.active;
}
/** * Set the active value. * * @param active if the foo object is in active state * @return the current foo object */publicFoosetActive(booleanactive) {
this.active = active;
returnthis;
}
}

Javadoc: Add / remove an exception's javadoc on a method

A FooClient class

publicclassFooClient {
/** * Create a Foo object. * * @param foo the foo object to create in Azure * @return the response for creating the foo object */publicCreateFooResponsecreateFoo(Foofoo) {
/* REST call to create foo */
}
}

with customization

@Overridepublicvoidcustomize(LibraryCustomizationcustomization) {
PackageCustomizationroot = customization.getPackage("com.azure.myservice");
ClassCustomizationfooClient = root.getClass("FooClient");
fooClient.methodJavadoc("createFoo").addThrows("HttpResponseException", "An unsuccessful response is received");
}

will generate

publicclassFooClient {
/** * Create a Foo object. * * @param foo the foo object to create in Azure * @return the response for creating the foo object * @throws HttpResponseException An unsuccessful response is received */publicCreateFooResponsecreateFoo(Foofoo) {
/* REST call to create foo */
}
}

Project structure

extension-base

This contains the base classes and utilities for creating an AutoRest extension in Java. It handles the JSON RPC communications with AutoRest core, provides JSON and YAML parsers, and provides the POJO models for the code model output from modelerfour.

Extend from NewPlugin.java class if you are writing a new extension in Java.

javagen

This contains the actual generator extension, including mappers that maps a code model to a Java client model, and templates that writes the Java client models into .java files.

fluentgen

This contains the generator extension for Azure Management Libraries.

tests

This contains the generated classes from the test swaggers in src/main. The code here should always be kept up-to-date with the output of the generator in javagen.

This also contains test code for these generated code under src/test. Running the tests will hit the test server running locally (see https://github.com/Azure/autorest.testserver for instructions) and verify the correctness of the generated code.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Autorest plugin configuration

Javagen

use: $(this-folder)/javagen
use: $(this-folder)/fluentgen
use: $(this-folder)/androidgen

Help

help-content:
java:
activationScope: javacategoryFriendlyName: Java Generatorsettings:
- key: enable-xmltype: booldescription: Generates models and clients that can be sent in XML over the wire. Default is false
- key: client-side-validationstype: booldescription: Generate validations for required parameters and required model properties. Default is false.
- key: generate-client-as-impltype: booldescription: Append "Impl" to the names of service clients and method groups and place them in the `implementation` sub-package. Default is false.
- key: generate-client-interfacestype: booldescription: Implies `--generate-client-as-impl` and generates interfaces for all the "Impl"s. Default is false.
- key: generate-sync-async-clientstype: booldescription: Implies `--generate-client-as-impl` and generates sync and async convenience layer clients for all the "Impl"s. Default is false.
- key: implementation-subpackage=STRINGtype: stringdescription: The sub-package that the Service client and Method Group client implementation classes will be put into. Default is `implementation`.
- key: models-subpackage=STRINGtype: stringdescription: The sub-package that Enums, Exceptions, and Model types will be put into. Default is `models`.
- key: add-context-parametertype: booldescription: Indicates whether the `com.azure.core.util.Context` parameter should be included in generated proxy methods. Default is false.
- key: context-client-method-parametertype: booldescription: Implies `--add-context-parameter` and indicates whether the `com.azure.core.util.Context` parameter should also be included in generated client methods. Default is false.
- key: sync-methodstype: stringdescription: \[all|essential|none] Specifies mode for generating sync wrappers. Supported value are <br>&nbsp;&nbsp;`essential` - generates only one sync returning body or header (default) <br>&nbsp;&nbsp;`all` - generates one sync method for each async method<br>&nbsp;&nbsp;`none` - does not generate any sync methods
- key: required-parameter-client-methodstype: booldescription: Indicates whether client method overloads with only required parameters should be generated. Default is false.
- key: custom-typestype: stringdescription: \[COMMA,SEPARATED,STRINGS] Specifies a list of files to put in the package specified in `--custom-types-subpackage`.
- key: custom-types-subpackagetype: stringdescription: The sub-package that the custom types should be generated in. The types that custom types reference, or inherit from will also be automatically moved to this sub-package. **Recommended usage** You can set this lue to `models` and set `--models-subpackage=implementation.models`to generate models to `implementation.models` by default and pick specific models to be public through `--custom-types=`.
- key: client-type-prefixtype: stringdescription: The prefix that will be added to each generated client type.
- key: model-override-setter-from-superclasstype: booldescription: Indicates whether to override the superclass setter method in model. Default is false.
- key: client-flattened-annotation-targettype: stringdescription: \[TYPE,FIELD] Indicates the target of `@JsonFlatten` annotation for `x-ms-client-flatten`. Default is `TYPE`. If value is `FIELD`, it implies `require-x-ms-flattened-to-flatten=true`.
- key: skip-formattingtype: booldescription: Indicates whether to skip formatting Java file. Default is false.javafluent:
activationScope: fluentcategoryFriendlyName: Java fluent Generatorsettings:
- key: fluenttype: stringdescription: Enum. `LITE` for Fluent Lite; `PREMIUM` for Fluent Premium. Case insensitive. Default is `PREMIUM` if provided as other values.
- key: fluent-subpackagetype: stringdescription: String. The sub-package that vanilla client and builder will be put into. Default is `fluent`.
- key: pom-filetype: stringdescription: String. Name for Maven POM file. Default is `pom.xml`.
- key: package-versiontype: stringdescription: String. Version number for Maven artifact. Default is `1.0.0-beta.1`.
- key: service-nametype: stringdescription: String. Service name used in Manager class and other documentations. If not provided, service name is deduced from `title` configure (from swagger or readme).
- key: sdk-integrationtype: booldescription: Boolean. Integrate to [azure-sdk-for-java](https://github.com/Azure/azure-sdk-for-java/). Default is `false`. Provide `output-folder` as absolute path for best performance.
- key: generate-samplestype: booldescription: Boolean. Generate samples from `x-ms-examples` in swagger. Default is `false`.
- key: add-innertype: stringdescription: CSV. Treat as inner class (move to `fluent.models` namespace, append `Inner` to class name).
- key: remove-innertype: stringdescription: CSV. Exclude from inner classes.
- key: rename-modeltype: stringdescription: CSV. Rename classes. Each item is of pattern `from:to`.
- key: remove-modeltype: stringdescription: CSV. Remove classes.
- key: preserve-modeltype: stringdescription: CSV. Preserve classes from clean-up.
- key: name-for-ungrouped-operationstype: stringdescription: String. Name for ungrouped operation group. Default to `ResourceProviders` for Lite.

About

Extension for AutoRest (https://github.com/Azure/autorest) that generates Java code

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages