Skip to content

Commit

Permalink
Support new mechanism of defining deprecated enum variants in OpenAPI (
Browse files Browse the repository at this point in the history
…opensearch-project#1198)

* Support new mechanism of defining deprecated enum variants in OpenAPI

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Spotless

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

---------

Signed-off-by: Thomas Farr <tsfarr@amazon.com>
(cherry picked from commit 432919c)
  • Loading branch information
Xtansia committed Sep 23, 2024
1 parent 45313b6 commit c68117a
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -42,7 +43,6 @@
import org.opensearch.client.codegen.openapi.OpenApiSchemaFormat;
import org.opensearch.client.codegen.openapi.OpenApiSchemaType;
import org.opensearch.client.codegen.openapi.OpenApiSpecification;
import org.opensearch.client.codegen.utils.Lists;
import org.opensearch.client.codegen.utils.Versions;

public class SpecTransformer {
Expand Down Expand Up @@ -249,25 +249,33 @@ private Shape visit(Namespace parent, String className, String typedefName, Open

var description = schema.getDescription().orElse(null);

var oneOf = schema.getOneOf();

if (schema.isArray()) {
shape = new ArrayShape(parent, className, mapType(schema), typedefName, description);
visitedSchemas.putIfAbsent(schema, shape);
} else if (schema.isString() && schema.hasEnums()) {
var deprecatedEnums = schema.getDeprecatedEnums().orElseGet(Collections::emptySet);
shape = new EnumShape(
parent,
className,
Lists.map(schema.getEnums().orElseThrow(), v -> new EnumShape.Variant(v, deprecatedEnums.contains(v))),
typedefName,
description
);
} else if (schema.isStringEnum() || (oneOf.isPresent() && oneOf.get().stream().allMatch(OpenApiSchema::isStringEnum))) {
var variants = new ArrayList<EnumShape.Variant>();

if (oneOf.isPresent()) {
oneOf.get().forEach(s -> {
var isDeprecated = s.getVersionDeprecated().isPresent();
s.getEnums().orElseThrow().forEach(v -> variants.add(new EnumShape.Variant(v, isDeprecated)));
});
} else {
schema.getEnums().orElseThrow().forEach(v -> variants.add(new EnumShape.Variant(v, false)));
}

variants.sort(Comparator.comparing(EnumShape.Variant::getName));

shape = new EnumShape(parent, className, variants, typedefName, description);
visitedSchemas.putIfAbsent(schema, shape);
} else if (schema.hasOneOf()) {
} else if (oneOf.isPresent()) {
var taggedUnion = new TaggedUnionShape(parent, className, typedefName, description);
shape = taggedUnion;
visitedSchemas.putIfAbsent(schema, shape);

schema.getOneOf().orElseThrow().forEach(s -> {
oneOf.get().forEach(s -> {
var title = s.getTitle()
.orElseThrow(() -> new IllegalStateException("oneOf variant [" + s.getPointer() + "] is missing a `title` tag"));
taggedUnion.addVariant(title, mapType(s));
Expand Down Expand Up @@ -509,16 +517,17 @@ private boolean shouldKeepRef(OpenApiSchema schema) {
if (schema.isInteger() || schema.isNumber() || schema.isArray()) {
return false;
}
if (schema.isString() && schema.getEnums().isEmpty()) {
return false;
if (schema.isString()) {
return schema.hasEnums();
}
if (schema.isObject()
&& schema.getProperties().map(Map::isEmpty).orElse(true)
&& schema.getAdditionalProperties().map(s -> s.getTitle().isEmpty()).orElse(false)) {
return false;
}
if (schema.getOneOf().isPresent()) {
return schema.getOneOf().orElseThrow().stream().allMatch(s -> s.getTitle().isPresent());
var oneOf = schema.getOneOf().orElseThrow();
return oneOf.stream().allMatch(s -> s.getTitle().isPresent()) || oneOf.stream().allMatch(OpenApiSchema::isStringEnum);
}
if (schema.getAllOf().isPresent()) {
return schema.determineSingleType().orElse(null) == OpenApiSchemaType.Object;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
public enum HttpStatusCode {
Ok("200"),
Created("201"),
Accepted("202"),
NoContent("204"),
BadRequest("400"),
Forbidden("403"),
NotFound("404"),
RequestTimeout("408"),
InternalServerError("500"),
NotImplemented("501");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import static org.opensearch.client.codegen.utils.Functional.ifNonnull;

import io.swagger.v3.oas.models.media.Schema;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -55,8 +54,6 @@ public class OpenApiSchema extends OpenApiRefElement<OpenApiSchema> {
@Nullable
private final List<String> enums;
@Nullable
private final Set<String> deprecatedEnums;
@Nullable
private final OpenApiSchema items;
@Nullable
private final OpenApiSchema additionalProperties;
Expand All @@ -70,6 +67,8 @@ public class OpenApiSchema extends OpenApiRefElement<OpenApiSchema> {
private final String pattern;
@Nullable
private final Semver versionRemoved;
@Nullable
private final Semver versionDeprecated;

private OpenApiSchema(@Nonnull Builder builder) {
super(builder.parent, Objects.requireNonNull(builder.pointer, "pointer must not be null"), builder.$ref, OpenApiSchema.class);
Expand All @@ -82,14 +81,14 @@ private OpenApiSchema(@Nonnull Builder builder) {
anyOf = builder.anyOf;
oneOf = builder.oneOf;
enums = builder.enums;
deprecatedEnums = builder.deprecatedEnums;
items = builder.items;
additionalProperties = builder.additionalProperties;
properties = builder.properties;
required = builder.required;
title = builder.title;
pattern = builder.pattern;
versionRemoved = builder.versionRemoved;
versionDeprecated = builder.versionDeprecated;
}

protected OpenApiSchema(@Nullable OpenApiElement<?> parent, @Nonnull JsonPointer pointer, @Nonnull Schema<?> schema) {
Expand Down Expand Up @@ -139,10 +138,8 @@ protected OpenApiSchema(@Nullable OpenApiElement<?> parent, @Nonnull JsonPointer

var extensions = schema.getExtensions();

// noinspection unchecked
deprecatedEnums = Maps.tryGet(extensions, "x-deprecated-enums").map(e -> (Collection<String>) e).map(HashSet::new).orElse(null);

versionRemoved = Maps.tryGet(extensions, "x-version-removed").map(v -> Versions.coerce((String) v)).orElse(null);
versionDeprecated = Maps.tryGet(extensions, "x-version-deprecated").map(v -> Versions.coerce((String) v)).orElse(null);
}

@Nonnull
Expand Down Expand Up @@ -199,6 +196,10 @@ public boolean isString() {
return is(OpenApiSchemaType.String);
}

public boolean isStringEnum() {
return isString() && hasEnums();
}

public boolean hasAllOf() {
return allOf != null && !allOf.isEmpty();
}
Expand Down Expand Up @@ -235,11 +236,6 @@ public Optional<List<String>> getEnums() {
return Lists.unmodifiableOpt(enums);
}

@Nonnull
public Optional<Set<String>> getDeprecatedEnums() {
return Sets.unmodifiableOpt(deprecatedEnums);
}

@Nonnull
public Optional<OpenApiSchema> getItems() {
return Optional.ofNullable(items);
Expand Down Expand Up @@ -275,6 +271,11 @@ public Optional<Semver> getVersionRemoved() {
return Optional.ofNullable(versionRemoved);
}

@Nonnull
public Optional<Semver> getVersionDeprecated() {
return Optional.ofNullable(versionDeprecated);
}

public static Set<OpenApiSchemaType> determineTypes(List<OpenApiSchema> schemas) {
return schemas.stream().map(OpenApiSchema::determineTypes).flatMap(Set::stream).collect(Collectors.toSet());
}
Expand Down Expand Up @@ -342,8 +343,6 @@ public static class Builder extends ObjectBuilderBase<OpenApiSchema, Builder> {
@Nullable
private List<String> enums;
@Nullable
private Set<String> deprecatedEnums;
@Nullable
private OpenApiSchema items;
@Nullable
private OpenApiSchema additionalProperties;
Expand All @@ -357,6 +356,8 @@ public static class Builder extends ObjectBuilderBase<OpenApiSchema, Builder> {
private String pattern;
@Nullable
private Semver versionRemoved;
@Nullable
private Semver versionDeprecated;

private Builder() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,21 @@ public enum OpenApiSchemaFormat {
Double,
Int32,
Int64,
Binary;
Binary,
DateTime("date-time");

private static final Map<String, OpenApiSchemaFormat> VALUES = Maps.createLookupOf(values(), OpenApiSchemaFormat::toString);

private final String format;

OpenApiSchemaFormat(String format) {
this.format = format;
}

OpenApiSchemaFormat() {
this.format = name().toLowerCase();
}

@Nonnull
public static OpenApiSchemaFormat from(@Nonnull String format) {
var value = VALUES.get(Strings.requireNonBlank(format, "format must not be blank"));
Expand All @@ -33,6 +44,6 @@ public static OpenApiSchemaFormat from(@Nonnull String format) {

@Override
public String toString() {
return name().toLowerCase();
return format;
}
}

0 comments on commit c68117a

Please sign in to comment.