micronaut-openapi
micronaut-openapi copied to clipboard
JsonProperty not getting picked up by yaml generation for Enum
Task List
- [ X ] Steps to reproduce provided
- [ N/A] Stacktrace (if present) provided
- [ N/A] Example that reproduces the problem uploaded to Github
- [ X ] Full description of the issue provided (see below)
Steps to Reproduce
- Create Java Enum Class with JsonProperty
import com.fasterxml.jackson.annotation.JsonProperty;
public enum CurrencyPair2 {
@JsonProperty("CAD-USD") CADUSD("CAD", "USD");
private final String baseCurrency;
private final String quoteCurrency;
CurrencyPair2(String baseCurrency, String quoteCurrency) {
this.baseCurrency = baseCurrency;
this.quoteCurrency = quoteCurrency;
}
public String getBaseCurrency() {
return baseCurrency;
}
public String getQuoteCurrency() {
return quoteCurrency;
}
}
- Reference class in response object/request params
- Build OpenApi:
annotationProcessor("io.micronaut.openapi:micronaut-openapi")
...
implementation("io.swagger.core.v3:swagger-annotations:2.1.6")
...
tasks.withType(JavaCompile) { options.fork = true options.forkOptions.jvmArgs << '-Dmicronaut.openapi.views.spec=rapidoc.enabled=true,swagger-ui.enabled=true,swagger-ui.theme=flattop' }
- Check Swagger output
Expected Behaviour
Enum values should be CAD-USD and serialization should convert appropriately
CurrencyPair2:
type: string
enum:
- CAD-USD
Actual Behaviour
Serialization converts on ingress and egress appropriately but enum values are CADUSD in the swagger schema
CurrencyPair2:
type: string
enum:
- CADUSD
Tell us what happens instead
Environment Information
- Operating System: MavOS Mojave version 10.14.6
- Micronaut Version: 1.3.4
- JDK Version:
- OPENAPI_VERSION=2.0.10
Example Application
- TODO: link to github repository with example that reproduces the issue
The problem is here: https://github.com/micronaut-projects/micronaut-openapi/blob/3c24f1268d5893c98efea007abcec5b37ae471b4/openapi/src/main/java/io/micronaut/openapi/visitor/AbstractOpenApiVisitor.java#L1199
OpenApi calls .values()
to get the values of the enum. This calls (for Java) the following in core https://github.com/micronaut-projects/micronaut-core/blob/09d392ab8f788c9e5cd415ea2ae076a0d8e050dc/inject-java/src/main/java/io/micronaut/annotation/processing/visitor/JavaEnumElement.java#L57-L64
The problem is that inside that code (even if we copy it to the openapi module) we don't have access to any bean metadata that Micronaut produces. All the Element
s in the stream are javax elements and not Micronaut. I don't see a way to check if those element have the appropriate annotation to generate the right value instead of the toString()
that it's done at this moment.
@graemerocher any thoughts if there is a way to do this?
@ccorcoran-nydig Hi! I added the ability to view annotations on enum constants - https://github.com/micronaut-projects/micronaut-core/pull/7580. But this feature will appear only in release 3.6.0
. After that, it will be possible to implement this feature
@altro3 Any plans to add support for @JsonValue
annotation?
@daltonconley Hi! I thought about it, but could not come up with a normal solution to support this annotation. Watch how the library works: the analyzer parses the structure of classes and enums, and can read the annotations that are used there.
So, the problem is: in order to support JsonValue, you need to call the method, i.e. run certain logic to understand what value will be the result.
In general, I'm just not sure that such logic is possible in this library. :-(
@daltonconley I have good news for you. I implemented JsonValue annotation support :-). Now wait for the merge of my changes and the new release (see https://github.com/micronaut-projects/micronaut-openapi/pull/791)
@altro3 Was pleased to see the above PR as I have a similar issue with @JsonValue which I expected would be fixed with your latest commit. I've built 4.5.0-SNAPSHOT from your PR and updated the dependency of my minimal recreation project locally and there's some improvement as it seems to obey the @JsonProperty annotation but still doesn't work for me with @JsonValue.
Interestingly I now get the warning:
Note: Generating OpenAPI Documentation
{path omitted}.../swagger-enum-gen/src/main/java/com/example/ResponseEnum.java:8: warning: Can't find enum class com.example.ResponseEnum
when running, but it still outputs the yaml with the Enum names (and one JsonProperty value).
The checked in bug recreation project above is still on the default dependencies rather than on your snapshot version. Please shout if I can be of any assistance. Thanks very much for your efforts!
@dclarke18 Hi! ok, I'll check it on the weekend
@dclarke18 @daltonconley I also tested this functionality. Well, unfortunately this functionality cannot be done in any way. I rolled back my changes because my solution only works at the testing level. The problem lies in the limitations of Java itself. Java, when executing annotation processors, does not load classes from the main classpath and does not provide access to the source codes of these classes. Those. the annotation processor only accesses the structure of the classes, but cannot call methods from these classes or read the method bodies in any way. So the only solution for enums is to put a JsonProperty annotation on each enum value.
Processing JsonValue at the annotation processor level is impossible to do :-(