OpenAPITools / OpenAPITools/openapi-generator
[BUG][Java][Client] Multiple oneOf => Multiple same discriminator
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator (example)?
- What's the version of OpenAPI Generator used?
- Have you search for related issues/PRs?
- What's the actual output vs expected output?
- [Optional] Bounty to sponsor the fix (example)
Description
When generating java feign client from yaml where there is same object in multiple oneOf, the generator produce duplicated discriminator attributes.
openapi-generator version
OpenApi Generator version : 4.3.0 with OpenAPI V3 file
OpenAPI declaration file content or url
gist : https://gist.github.com/LeComptoirDesPharmacies/f28c0a189cf6a1312b8c1d5d7b59c0f7
Command line used for generation
java -cp openapi-generator-cli-4.3.0.jar org.openapitools.codegen.OpenAPIGenerator generate -g java -i example.yaml -o output --library feign
Steps to reproduce
Launch the command. You will see that ModelB is generated like the following with multiple distributionType fields :
/**
* ModeB
*/
@JsonPropertyOrder({
ModeB.JSON_PROPERTY_ANY_PROP_C,
ModeB.JSON_PROPERTY_DISTRIBUTION_TYPE,
ModeB.JSON_PROPERTY_DISTRIBUTION_TYPE
})
@javax.annotation.Generated(value = "fr.lcdp.codegen.JavaPlayFeignClientCodegen", date = "2020-04-07T22:25:50.963278800+02:00[Europe/Paris]")
public class ModeB extends Mode implements AnyIdentifiedMode, AnyMode {
public static final String JSON_PROPERTY_ANY_PROP_C = "anyPropC";
private String anyPropC;
public static final String JSON_PROPERTY_DISTRIBUTION_TYPE = "distributionType";
private String distributionType;
public static final String JSON_PROPERTY_DISTRIBUTION_TYPE = "distributionType";
private String distributionType;
Expected value should be :
/**
* ModeB
*/
@JsonPropertyOrder({
ModeB.JSON_PROPERTY_ANY_PROP_C,
ModeB.JSON_PROPERTY_DISTRIBUTION_TYPE
})
@javax.annotation.Generated(value = "fr.lcdp.codegen.JavaPlayFeignClientCodegen", date = "2020-04-07T22:25:50.963278800+02:00[Europe/Paris]")
public class ModeB extends Mode implements AnyIdentifiedMode, AnyMode {
public static final String JSON_PROPERTY_ANY_PROP_C = "anyPropC";
private String anyPropC;
public static final String JSON_PROPERTY_DISTRIBUTION_TYPE = "distributionType";
private String distributionType;
Suggest a fix
I think that it can came from this new lines which manage oneOf aspect of OpenAPI v3. Generator add to current models properties from implemented interfaces (oneOf) event if they are already in additionalProps.
https://github.com/OpenAPITools/openapi-generator/pull/4785/files#diff-df91e7fc730a53c408e0e3b2f22ab86eR961
Temporary workaroung
We created a wrapping generator of JavaClientCodegen with the following method to clean the vars after postProcess :
public static <T> Predicate<T> distinctByKey(
Function<? super T, ?> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
@Override
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
objs = super.postProcessAllModels(objs);
if (this.useOneOfInterfaces) {
for (Map.Entry modelsEntry : objs.entrySet()) {
Map<String, Object> modelsAttrs = (Map<String, Object>) modelsEntry.getValue();
List<Object> models = (List<Object>) modelsAttrs.get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
if (cm.getVendorExtensions().containsKey("implements"))
{
if (cm.vars.size() > 0) {
// Filter duplicate
cm.vars = cm.vars.stream()
.filter(distinctByKey(codegenProperty -> codegenProperty.baseName))
.collect(Collectors.toList());
// Re-compute hasMore flag
CodegenProperty last = cm.vars.remove(cm.vars.size() - 1);
last.hasMore = false;
cm.vars.stream().map(codegenProperty -> codegenProperty.hasMore=true);
cm.vars.add(last);
cm.hasVars = true;
}
}
}
}
}
return objs;
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in the Java client codegen model-processing path, especially postProcessAllModels and the oneOf changes referenced in PR 4785. Reproduce with the linked gist and the Java Feign command, then verify that a model appearing in multiple oneOf interfaces has only one distributionType field and discriminator entry.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, openapi
- Domain
- api, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100