Skip to content

Commit

Permalink
[java-micronaut] Return HTTP 501 in default implementation (#12365)
Browse files Browse the repository at this point in the history
The default controller implementation returns an empty response. This
might result in unexpected behavior when an operation isn't implemented,
as a consumer of the API there is no way to notice the difference
between an unimplemented method and an actual empty response.

By changing the default behavior to return HTTP 501 Not Implemented the
user will be made aware of unimplemented methods. The former default
behavior, returning an empty response by default, can be activated with
a configuration option.
  • Loading branch information
auke- authored May 18, 2022
1 parent d38cb1b commit a575096
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 23 deletions.
2 changes: 2 additions & 0 deletions bin/configs/java-micronaut-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ additionalProperties:
test: "spock"
requiredPropertiesInConstructor: "true"
useAuth: "false"
generateControllerAsAbstract: "false"
generateOperationsToReturnNotImplemented: "true"
1 change: 1 addition & 0 deletions docs/generators/java-micronaut-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|fullJavaUtil|whether to use fully qualified name for classes under java.util. This option only works for Java API client| |false|
|generateControllerAsAbstract|Generate an abstract class for controller to be extended. (apiPackage is then used for the abstract class, and controllerPackage is used for implementation that extends it.)| |false|
|generateControllerFromExamples|Generate the implementation of controller and tests from parameter and return examples that will verify that the api works as desired (for testing)| |false|
|generateOperationsToReturnNotImplemented|Return HTTP 501 Not Implemented instead of an empty response in the generated controller methods.| |true|
|groupId|groupId in generated pom.xml| |org.openapitools|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |false|
|ignoreAnyOfInEnum|Ignore anyOf keyword in enum| |false|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


public class JavaMicronautServerCodegen extends JavaMicronautAbstractCodegen {
public static final String OPT_CONTROLLER_PACKAGE = "controllerPackage";
public static final String OPT_GENERATE_CONTROLLER_FROM_EXAMPLES = "generateControllerFromExamples";
public static final String OPT_GENERATE_CONTROLLER_AS_ABSTRACT = "generateControllerAsAbstract";
public static final String OPT_GENERATE_OPERATIONS_TO_RETURN_NOT_IMPLEMENTED = "generateOperationsToReturnNotImplemented";

public static final String EXTENSION_ROLES = "x-roles";
public static final String ANONYMOUS_ROLE_KEY = "isAnonymous()";
Expand All @@ -35,6 +35,7 @@ public class JavaMicronautServerCodegen extends JavaMicronautAbstractCodegen {

protected String controllerPackage = "org.openapitools.controller";
protected boolean generateControllerAsAbstract = false;
protected boolean generateOperationsToReturnNotImplemented = true;
protected boolean generateControllerFromExamples = false;
protected boolean useAuth = true;

Expand Down Expand Up @@ -65,6 +66,10 @@ public JavaMicronautServerCodegen() {
" is then used for the abstract class, and " + OPT_CONTROLLER_PACKAGE +
" is used for implementation that extends it.)",
generateControllerAsAbstract));
cliOptions.add(CliOption.newBoolean(OPT_GENERATE_OPERATIONS_TO_RETURN_NOT_IMPLEMENTED,
"Return HTTP 501 Not Implemented instead of an empty response in the generated controller methods.",
generateOperationsToReturnNotImplemented));

cliOptions.add(CliOption.newBoolean(OPT_USE_AUTH, "Whether to import authorization and to annotate controller methods accordingly", useAuth));

// Set the type mappings
Expand Down Expand Up @@ -96,6 +101,11 @@ public void processOpts() {
}
writePropertyBack(OPT_GENERATE_CONTROLLER_AS_ABSTRACT, generateControllerAsAbstract);

if (additionalProperties.containsKey(OPT_GENERATE_OPERATIONS_TO_RETURN_NOT_IMPLEMENTED)) {
generateOperationsToReturnNotImplemented = convertPropertyToBoolean(OPT_GENERATE_OPERATIONS_TO_RETURN_NOT_IMPLEMENTED);
}
writePropertyBack(OPT_GENERATE_OPERATIONS_TO_RETURN_NOT_IMPLEMENTED, generateOperationsToReturnNotImplemented);

if (additionalProperties.containsKey(OPT_CONTROLLER_PACKAGE)) {
controllerPackage = (String) additionalProperties.get(OPT_CONTROLLER_PACKAGE);
} else if (!generateControllerAsAbstract && additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import reactor.core.publisher.Mono;
{{#wrapInHttpResponse}}
import io.micronaut.http.HttpResponse;
{{/wrapInHttpResponse}}
{{#generateOperationsToReturnNotImplemented}}
import io.micronaut.http.HttpStatus;
import io.micronaut.http.exceptions.HttpStatusException;
{{/generateOperationsToReturnNotImplemented}}
{{#imports}}
import {{import}};
{{/imports}}
Expand Down Expand Up @@ -119,8 +123,9 @@ public {{#generateControllerAsAbstract}}abstract {{/generateControllerAsAbstract
*
* This method will be delegated to when the controller gets a request
*/
public abstract {{>common/operationReturnType}} {{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
{{/generateControllerAsAbstract}}
public {{^generateOperationsToReturnNotImplemented}}abstract {{/generateOperationsToReturnNotImplemented}}{{>common/operationReturnType}} {{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}){{^generateOperationsToReturnNotImplemented}};{{/generateOperationsToReturnNotImplemented}}{{#generateOperationsToReturnNotImplemented}} {{openbrace}}
{{>server/controllerOperationBody}}
{{closebrace}}{{/generateOperationsToReturnNotImplemented}}{{/generateControllerAsAbstract}}
{{^-last}}

{{/-last}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
{{^generateControllerFromExamples}}
{{!The body needs to be implemented by user}}
// TODO implement {{nickname}}();
{{^generateOperationsToReturnNotImplemented}}
{{#reactive}}{{#wrapInHttpResponse}}return Mono.fromCallable(HttpResponse::ok);{{/wrapInHttpResponse}}{{^wrapInHttpResponse}}return Mono.empty();{{/wrapInHttpResponse}}{{/reactive}}{{^reactive}}{{#wrapInHttpResponse}}return HttpResponse.ok();{{/wrapInHttpResponse}}{{^wrapInHttpResponse}}{{#returnType}}return null;{{/returnType}}{{/wrapInHttpResponse}}{{/reactive}}
{{/generateOperationsToReturnNotImplemented}}
{{#generateOperationsToReturnNotImplemented}}
{{#reactive}}{{#wrapInHttpResponse}}return Mono.just(HttpResponse.status(HttpStatus.NOT_IMPLEMENTED));{{/wrapInHttpResponse}}{{^wrapInHttpResponse}}return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));{{/wrapInHttpResponse}}{{/reactive}}{{^reactive}}{{#wrapInHttpResponse}}return HttpResponse.status(HttpStatus.NOT_IMPLEMENTED);{{/wrapInHttpResponse}}{{^wrapInHttpResponse}}throw new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null);{{/wrapInHttpResponse}}{{/reactive}}
{{/generateOperationsToReturnNotImplemented}}
{{/generateControllerFromExamples}}
{{#generateControllerFromExamples}}
{{!The body is generated to verify that example values are passed correctly}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.convert.format.Format;
import reactor.core.publisher.Mono;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.exceptions.HttpStatusException;
import io.micronaut.http.multipart.CompletedFileUpload;
import org.openapitools.model.ModelApiResponse;
import org.openapitools.model.Pet;
Expand Down Expand Up @@ -60,9 +62,10 @@ public Mono<Pet> addPet(
@Body @NotNull @Valid Pet pet
) {
// TODO implement addPet();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Deletes a pet
*
Expand Down Expand Up @@ -90,9 +93,10 @@ public Mono<Void> deletePet(
@Header(value="api_key") @Nullable String apiKey
) {
// TODO implement deletePet();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Finds Pets by status
* Multiple status values can be provided with comma separated strings
Expand Down Expand Up @@ -121,9 +125,10 @@ public Mono<List<Pet>> findPetsByStatus(
@QueryValue(value="status") @NotNull List<String> status
) {
// TODO implement findPetsByStatus();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Finds Pets by tags
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
Expand Down Expand Up @@ -152,9 +157,10 @@ public Mono<List<Pet>> findPetsByTags(
@QueryValue(value="tags") @NotNull List<String> tags
) {
// TODO implement findPetsByTags();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Find pet by ID
* Returns a single pet
Expand All @@ -181,9 +187,10 @@ public Mono<Pet> getPetById(
@PathVariable(value="petId") @NotNull Long petId
) {
// TODO implement getPetById();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Update an existing pet
*
Expand Down Expand Up @@ -215,9 +222,10 @@ public Mono<Pet> updatePet(
@Body @NotNull @Valid Pet pet
) {
// TODO implement updatePet();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Updates a pet in the store with form data
*
Expand Down Expand Up @@ -248,9 +256,10 @@ public Mono<Void> updatePetWithForm(
@Nullable String status
) {
// TODO implement updatePetWithForm();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* uploads an image
*
Expand Down Expand Up @@ -283,6 +292,7 @@ public Mono<ModelApiResponse> uploadFile(
@Nullable CompletedFileUpload _file
) {
// TODO implement uploadFile();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.convert.format.Format;
import reactor.core.publisher.Mono;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.exceptions.HttpStatusException;
import org.openapitools.model.Order;
import javax.annotation.Generated;
import java.util.ArrayList;
Expand Down Expand Up @@ -50,9 +52,10 @@ public Mono<Void> deleteOrder(
@PathVariable(value="orderId") @NotNull String orderId
) {
// TODO implement deleteOrder();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Returns pet inventories by status
* Returns a map of status codes to quantities
Expand All @@ -75,9 +78,10 @@ public Mono<Void> deleteOrder(
@Produces(value = {"application/json"})
public Mono<Map<String, Integer>> getInventory() {
// TODO implement getInventory();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Find purchase order by ID
* For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generated exceptions
Expand All @@ -102,9 +106,10 @@ public Mono<Order> getOrderById(
@PathVariable(value="orderId") @NotNull @Min(1L) @Max(5L) Long orderId
) {
// TODO implement getOrderById();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Place an order for a pet
*
Expand All @@ -129,6 +134,7 @@ public Mono<Order> placeOrder(
@Body @NotNull @Valid Order order
) {
// TODO implement placeOrder();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.convert.format.Format;
import reactor.core.publisher.Mono;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.exceptions.HttpStatusException;
import java.time.OffsetDateTime;
import org.openapitools.model.User;
import javax.annotation.Generated;
Expand Down Expand Up @@ -53,9 +55,10 @@ public Mono<Void> createUser(
@Body @NotNull @Valid User user
) {
// TODO implement createUser();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Creates list of users with given input array
*
Expand All @@ -79,9 +82,10 @@ public Mono<Void> createUsersWithArrayInput(
@Body @NotNull List<User> user
) {
// TODO implement createUsersWithArrayInput();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Creates list of users with given input array
*
Expand All @@ -105,9 +109,10 @@ public Mono<Void> createUsersWithListInput(
@Body @NotNull List<User> user
) {
// TODO implement createUsersWithListInput();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Delete user
* This can only be done by the logged in user.
Expand All @@ -131,9 +136,10 @@ public Mono<Void> deleteUser(
@PathVariable(value="username") @NotNull String username
) {
// TODO implement deleteUser();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Get user by user name
*
Expand All @@ -158,9 +164,10 @@ public Mono<User> getUserByName(
@PathVariable(value="username") @NotNull String username
) {
// TODO implement getUserByName();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Logs user into the system
*
Expand All @@ -186,9 +193,10 @@ public Mono<String> loginUser(
@QueryValue(value="password") @NotNull String password
) {
// TODO implement loginUser();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Logs out current logged in user session
*
Expand All @@ -208,9 +216,10 @@ public Mono<String> loginUser(
@Produces(value = {})
public Mono<Void> logoutUser() {
// TODO implement logoutUser();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}


/**
* Updated user
* This can only be done by the logged in user.
Expand All @@ -237,6 +246,7 @@ public Mono<Void> updateUser(
@Body @NotNull @Valid User user
) {
// TODO implement updateUser();
return Mono.empty();
return Mono.error(new HttpStatusException(HttpStatus.NOT_IMPLEMENTED, null));
}

}

0 comments on commit a575096

Please sign in to comment.