From ef612816ea0596930125558195737ec86a088cab Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Tue, 27 Aug 2024 09:16:30 +1200 Subject: [PATCH] Generate the ml namespace (#1158) * Generate ml.register_model_group Signed-off-by: Thomas Farr * Start neural search sample Signed-off-by: Thomas Farr * Re-generate ShardStatistics Signed-off-by: Thomas Farr * Re-generate ShardFailure Signed-off-by: Thomas Farr * Re-generate Result Signed-off-by: Thomas Farr * Re-generate WriteResponseBase Signed-off-by: Thomas Farr * Generate ml.delete_model_group Signed-off-by: Thomas Farr * Generate ml.register_model Signed-off-by: Thomas Farr * Exclude legacy license from ml namespace Signed-off-by: Thomas Farr * Generate ml.get_task Signed-off-by: Thomas Farr * Generate ml.delete_task Signed-off-by: Thomas Farr * Generate ml.delete_model Signed-off-by: Thomas Farr * Generate ml.deploy_model Signed-off-by: Thomas Farr * Generate ml.undeploy_model Signed-off-by: Thomas Farr * Complete neural search sample Signed-off-by: Thomas Farr * Generate ml.get_model Signed-off-by: Thomas Farr * Add changelog entry Signed-off-by: Thomas Farr * note Signed-off-by: Thomas Farr * Fix tests Signed-off-by: Thomas Farr --------- Signed-off-by: Thomas Farr (cherry picked from commit c6e61e1b559cc7e26b1e65765440c02192e44180) --- java-codegen/build.gradle.kts | 3 + java-codegen/opensearch-openapi.yaml | 43 ++++++++++--- .../client/codegen/CodeGenerator.java | 10 ++- .../client/codegen/model/Deprecation.java | 7 ++- .../client/codegen/model/Namespace.java | 7 ++- .../client/codegen/model/OperationGroup.java | 59 ------------------ .../codegen/model/OperationGroupMatcher.java | 61 +++++++++++++++++++ .../client/codegen/model/RequestShape.java | 6 ++ .../client/codegen/model/Shape.java | 4 ++ .../client/codegen/model/SpecTransformer.java | 35 ++++++++--- .../codegen/openapi/OpenApiOperation.java | 6 +- .../codegen/openapi/OpenApiParameter.java | 6 +- .../client/codegen/openapi/OpenApiSchema.java | 14 +++++ .../client/codegen/utils/Strings.java | 12 ++++ .../client/codegen/utils/Versions.java | 25 ++++++++ .../templates/Partials/ClassHeader.mustache | 2 + 16 files changed, 213 insertions(+), 87 deletions(-) create mode 100644 java-codegen/src/main/java/org/opensearch/client/codegen/model/OperationGroupMatcher.java create mode 100644 java-codegen/src/main/java/org/opensearch/client/codegen/utils/Versions.java diff --git a/java-codegen/build.gradle.kts b/java-codegen/build.gradle.kts index c5f1933713..49aa5ec3f5 100644 --- a/java-codegen/build.gradle.kts +++ b/java-codegen/build.gradle.kts @@ -167,6 +167,9 @@ dependencies { implementation("org.apache.maven.resolver", "maven-resolver-api", "1.9.20") implementation("org.apache.maven.resolver", "maven-resolver-supplier", "1.9.20") + // MIT + implementation("org.semver4j", "semver4j", "5.3.0") + // EPL-2.0 testImplementation(platform("org.junit:junit-bom:5.10.3")) testImplementation("org.junit.jupiter", "junit-jupiter") diff --git a/java-codegen/opensearch-openapi.yaml b/java-codegen/opensearch-openapi.yaml index fc23f29fe3..889bedbbdf 100644 --- a/java-codegen/opensearch-openapi.yaml +++ b/java-codegen/opensearch-openapi.yaml @@ -3887,6 +3887,20 @@ paths: '200': $ref: '#/components/responses/ml.undeploy_model@200' /_plugins/_ml/tasks/{task_id}: + delete: + operationId: ml.delete_task.0 + x-operation-group: ml.delete_task + description: Deletes a task. + parameters: + - $ref: '#/components/parameters/ml.delete_task::path.task_id' + - $ref: '#/components/parameters/_global::query.pretty' + - $ref: '#/components/parameters/_global::query.human' + - $ref: '#/components/parameters/_global::query.error_trace' + - $ref: '#/components/parameters/_global::query.source' + - $ref: '#/components/parameters/_global::query.filter_path' + responses: + '200': + $ref: '#/components/responses/ml.delete_task@200' get: operationId: ml.get_task.0 x-operation-group: ml.get_task @@ -20036,6 +20050,12 @@ components: required: true schema: type: string + ml.delete_task::path.task_id: + name: task_id + in: path + required: true + schema: + type: string ml.deploy_model::path.model_id: name: model_id in: path @@ -26139,6 +26159,11 @@ components: application/json: schema: $ref: '#/components/schemas/_common:WriteResponseBase' + ml.delete_task@200: + content: + application/json: + schema: + $ref: '#/components/schemas/_common:WriteResponseBase' ml.deploy_model@200: content: application/json: @@ -29286,6 +29311,7 @@ components: - version_map_memory_in_bytes _common:SequenceNumber: type: number + format: int64 _common:ShardFailure: type: object properties: @@ -29602,6 +29628,7 @@ components: type: string _common:VersionNumber: type: number + format: int64 _common:VersionString: type: string _common:VersionType: @@ -29671,6 +29698,7 @@ components: $ref: '#/components/schemas/_common:IndexName' _primary_term: type: number + format: int64 result: $ref: '#/components/schemas/_common:Result' _seq_no: @@ -46333,18 +46361,19 @@ components: type: string required: - state - ml._common:UndeployModelResponse: - type: object - additionalProperties: - $ref: '#/components/schemas/ml._common:UndeployModelResponseModels' - ml._common:UndeployModelResponseModels: + ml._common:UndeployModelNode: type: object properties: stats: - $ref: '#/components/schemas/ml._common:UndeployModelResponseStats' - ml._common:UndeployModelResponseStats: + $ref: '#/components/schemas/ml._common:UndeployModelNodeStats' + ml._common:UndeployModelNodeStats: type: object additionalProperties: true + ml._common:UndeployModelResponse: + type: object + additionalProperties: + title: nodes + $ref: '#/components/schemas/ml._common:UndeployModelNode' nodes._common:AdaptiveSelection: type: object properties: diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/CodeGenerator.java b/java-codegen/src/main/java/org/opensearch/client/codegen/CodeGenerator.java index 3c629d41e9..45e034136b 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/CodeGenerator.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/CodeGenerator.java @@ -8,6 +8,8 @@ package org.opensearch.client.codegen; +import static org.opensearch.client.codegen.model.OperationGroupMatcher.*; + import java.io.File; import java.io.IOException; import java.io.PrintWriter; @@ -26,14 +28,18 @@ import org.opensearch.client.codegen.exceptions.ApiSpecificationParseException; import org.opensearch.client.codegen.exceptions.RenderException; import org.opensearch.client.codegen.model.Namespace; -import org.opensearch.client.codegen.model.OperationGroup; +import org.opensearch.client.codegen.model.OperationGroupMatcher; import org.opensearch.client.codegen.model.ShapeRenderingContext; import org.opensearch.client.codegen.model.SpecTransformer; import org.opensearch.client.codegen.openapi.OpenApiSpecification; public class CodeGenerator { private static final Logger LOGGER = LogManager.getLogger(); - private static final OperationGroup.Matcher OPERATION_MATCHER = OperationGroup.matcher(); + private static final OperationGroupMatcher OPERATION_MATCHER = none(); +// private static final OperationGroupMatcher OPERATION_MATCHER = or( +// and(namespace(""), named("info")), +// and(namespace("ml"), not(named("search_models"))) // TODO: search_models is complex and ideally should re-use the search structures +// ); public static void main(String[] args) { var inputOpt = Option.builder("i") diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/model/Deprecation.java b/java-codegen/src/main/java/org/opensearch/client/codegen/model/Deprecation.java index 9b1818a852..8f965bb14f 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/model/Deprecation.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/model/Deprecation.java @@ -11,14 +11,15 @@ import java.util.Optional; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.semver4j.Semver; public class Deprecation { @Nullable private final String description; @Nullable - private final String version; + private final Semver version; - public Deprecation(@Nullable String description, @Nullable String version) { + public Deprecation(@Nullable String description, @Nullable Semver version) { this.description = description; this.version = version; } @@ -29,7 +30,7 @@ public Optional getDescription() { } @Nonnull - public Optional getVersion() { + public Optional getVersion() { return Optional.ofNullable(version); } } diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/model/Namespace.java b/java-codegen/src/main/java/org/opensearch/client/codegen/model/Namespace.java index 1f455426a3..e0f52eb63d 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/model/Namespace.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/model/Namespace.java @@ -47,10 +47,11 @@ public void addShape(Shape shape) { } public String getPackageName() { - return parent != null ? parent.getPackageName() + "." + getPackageNamePart() : "org.opensearch.client.opensearch"; + return parent != null ? parent.getPackageName() + "." + getName() : "org.opensearch.client.opensearch"; } - private String getPackageNamePart() { + @Nonnull + public String getName() { return name; } @@ -70,7 +71,7 @@ public Namespace child(@Nullable String name) { public void render(ShapeRenderingContext ctx) throws RenderException { for (Namespace child : children.values()) { - child.render(ctx.forSubDir(child.getPackageNamePart())); + child.render(ctx.forSubDir(child.getName())); } for (Shape shape : shapes) { diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/model/OperationGroup.java b/java-codegen/src/main/java/org/opensearch/client/codegen/model/OperationGroup.java index 818a4acd40..0d8dd650d9 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/model/OperationGroup.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/model/OperationGroup.java @@ -8,12 +8,7 @@ package org.opensearch.client.codegen.model; -import java.util.Collection; -import java.util.HashSet; -import java.util.Objects; import java.util.Optional; -import java.util.Set; -import java.util.regex.Pattern; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.apache.commons.lang3.builder.EqualsBuilder; @@ -76,58 +71,4 @@ public boolean equals(Object o) { public int hashCode() { return new HashCodeBuilder(17, 37).append(namespace).append(name).toHashCode(); } - - @Nonnull - public static Matcher matcher() { - return new Matcher(); - } - - public static class Matcher { - private final Set namespaces = new HashSet<>(); - private final Set operations = new HashSet<>(); - private final Collection patterns = new HashSet<>(); - - private Matcher() {} - - @Nonnull - public Matcher add(@Nullable String namespace, @Nullable String... operations) { - if (operations == null || operations.length == 0) { - namespaces.add(Strings.requireNonBlank(namespace, "namespace must not be blank")); - } else { - for (String operation : operations) { - add(new OperationGroup(namespace, operation)); - } - } - return this; - } - - @Nonnull - public Matcher add(@Nonnull OperationGroup operation) { - operations.add(Objects.requireNonNull(operation, "operation must not be null")); - return this; - } - - @Nonnull - public Matcher add(@Nonnull Pattern pattern) { - patterns.add(Objects.requireNonNull(pattern, "pattern must not be null")); - return this; - } - - public boolean matches(@Nonnull OperationGroup operation) { - Objects.requireNonNull(operation, "operation must not be null"); - if (operation.getNamespace().map(namespaces::contains).orElse(false)) { - return true; - } - if (operations.contains(operation)) { - return true; - } - var str = operation.toString(); - for (Pattern pattern : patterns) { - if (pattern.matcher(str).matches()) { - return true; - } - } - return false; - } - } } diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/model/OperationGroupMatcher.java b/java-codegen/src/main/java/org/opensearch/client/codegen/model/OperationGroupMatcher.java new file mode 100644 index 0000000000..6a33bf3f81 --- /dev/null +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/model/OperationGroupMatcher.java @@ -0,0 +1,61 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.client.codegen.model; + +import java.util.Arrays; +import java.util.HashSet; +import javax.annotation.Nonnull; + +@FunctionalInterface +public interface OperationGroupMatcher { + boolean matches(OperationGroup group); + + static OperationGroupMatcher all() { + return group -> true; + } + + static OperationGroupMatcher none() { + return group -> false; + } + + static OperationGroupMatcher not(OperationGroupMatcher matcher) { + return group -> !matcher.matches(group); + } + + static OperationGroupMatcher or(OperationGroupMatcher... matchers) { + return group -> { + for (OperationGroupMatcher matcher : matchers) { + if (matcher.matches(group)) { + return true; + } + } + return false; + }; + } + + static OperationGroupMatcher and(OperationGroupMatcher... matchers) { + return group -> { + for (OperationGroupMatcher matcher : matchers) { + if (!matcher.matches(group)) { + return false; + } + } + return true; + }; + } + + static OperationGroupMatcher named(String... names) { + var set = new HashSet<>(Arrays.asList(names)); + return group -> set.contains(group.getName()); + } + + static OperationGroupMatcher namespace(@Nonnull String namespace) { + return group -> namespace.equals(group.getNamespace().orElse("")); + } +} diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/model/RequestShape.java b/java-codegen/src/main/java/org/opensearch/client/codegen/model/RequestShape.java index 3e332ca8b8..53972b826c 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/model/RequestShape.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/model/RequestShape.java @@ -136,6 +136,12 @@ public Collection getPathParams() { return pathParams.values(); } + @Override + public void addBodyField(Field field) { + super.addBodyField(field); + addField(field); + } + private void addField(Field field) { fields.put(field.getName(), field); } diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/model/Shape.java b/java-codegen/src/main/java/org/opensearch/client/codegen/model/Shape.java index 73d728a1db..bb59217c11 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/model/Shape.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/model/Shape.java @@ -94,4 +94,8 @@ public Set getImports() { } return imports; } + + public boolean needsLegacyLicense() { + return !"ml".equals(parent.getName()); + } } diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/model/SpecTransformer.java b/java-codegen/src/main/java/org/opensearch/client/codegen/model/SpecTransformer.java index 55e6a45609..72527200ff 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/model/SpecTransformer.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/model/SpecTransformer.java @@ -41,11 +41,12 @@ 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 { private static final Logger LOGGER = LogManager.getLogger(); @Nonnull - private final OperationGroup.Matcher matcher; + private final OperationGroupMatcher matcher; @Nonnull private final Namespace root = new Namespace(); @Nonnull @@ -53,7 +54,7 @@ public class SpecTransformer { @Nonnull private final Map schemaToType = new ConcurrentHashMap<>(); - public SpecTransformer(@Nonnull OperationGroup.Matcher matcher) { + public SpecTransformer(@Nonnull OperationGroupMatcher matcher) { this.matcher = Objects.requireNonNull(matcher, "matcher must not be null"); } @@ -285,14 +286,14 @@ private void visitInto(OpenApiSchema schema, ObjectShape shape) { final var required = collectObjectProperties(schema, properties, additionalProperties); properties.forEach( - (k, v) -> { shape.addBodyField(new Field(k, mapType(v), required.contains(k), v.getDescription().orElse(null), null)); } + (k, v) -> shape.addBodyField(new Field(k, mapType(v), required.contains(k), v.getDescription().orElse(null), null)) ); if (!additionalProperties.isEmpty()) { var valueSchema = additionalProperties.size() == 1 ? additionalProperties.get(0) : OpenApiSchema.ANONYMOUS_UNTYPED; shape.setAdditionalPropertiesField( new Field( - valueSchema.getTitle().orElseThrow(), + valueSchema.getTitle().orElse("metadata"), Types.Java.Util.Map(Types.Java.Lang.String, mapType(valueSchema)), false, valueSchema.getDescription().orElse(null), @@ -333,17 +334,28 @@ private Set collectObjectProperties( return required; } - schema.getProperties().ifPresent(props -> props.forEach((k, v) -> { - var existing = properties.get(k); + schema.getProperties().ifPresent(props -> props.forEach((propName, propSchema) -> { + var resolvedPropSchema = propSchema.resolve(); + var isRemoved = propSchema.getVersionRemoved() + .or(resolvedPropSchema::getVersionRemoved) + .map(ver -> ver.isLowerThanOrEqualTo(Versions.V2_0_0)) + .orElse(false); + + if (isRemoved) { + return; + } + + var existing = properties.get(propName); if (existing != null) { var existingType = existing.determineSingleType().orElse(null); - var newType = v.determineSingleType().orElse(null); + var newType = propSchema.determineSingleType().orElse(null); if (existingType != null && (existingType == OpenApiSchemaType.Object || existingType == OpenApiSchemaType.Array || existingType != newType)) { - v = OpenApiSchema.ANONYMOUS_UNTYPED; + propSchema = OpenApiSchema.ANONYMOUS_UNTYPED; } } - properties.put(k, v); + + properties.put(propName, propSchema); })); schema.getAdditionalProperties().ifPresent(additionalProperties::add); @@ -472,6 +484,11 @@ private boolean shouldKeepRef(OpenApiSchema schema) { if (schema.isString() && schema.getEnums().isEmpty()) { return false; } + 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()); } diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/openapi/OpenApiOperation.java b/java-codegen/src/main/java/org/opensearch/client/codegen/openapi/OpenApiOperation.java index 34b2f4be9b..0489c44bd4 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/openapi/OpenApiOperation.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/openapi/OpenApiOperation.java @@ -20,6 +20,8 @@ import javax.annotation.Nullable; import org.opensearch.client.codegen.model.Deprecation; import org.opensearch.client.codegen.model.OperationGroup; +import org.opensearch.client.codegen.utils.Versions; +import org.semver4j.Semver; public class OpenApiOperation extends OpenApiElement { @Nonnull @@ -43,7 +45,7 @@ public class OpenApiOperation extends OpenApiElement { @Nullable private final String versionAdded; @Nullable - private final String versionDeprecated; + private final Semver versionDeprecated; @Nullable private final String deprecationMessage; @@ -61,7 +63,7 @@ protected OpenApiOperation(@Nonnull OpenApiPath parent, @Nonnull JsonPointer poi this.requestBody = child("requestBody", operation.getRequestBody(), OpenApiRequestBody::new); this.responses = child("responses", operation.getResponses(), OpenApiResponses::new); this.versionAdded = ifNonnull(extensions.get("x-version-added"), String::valueOf); - this.versionDeprecated = ifNonnull(extensions.get("x-version-deprecated"), String::valueOf); + this.versionDeprecated = ifNonnull(extensions.get("x-version-deprecated"), v -> Versions.coerce((String) v)); this.deprecationMessage = ifNonnull(extensions.get("x-deprecation-message"), String::valueOf); } diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/openapi/OpenApiParameter.java b/java-codegen/src/main/java/org/opensearch/client/codegen/openapi/OpenApiParameter.java index 442873eab7..45e0178b46 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/openapi/OpenApiParameter.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/openapi/OpenApiParameter.java @@ -16,6 +16,8 @@ import javax.annotation.Nullable; import org.opensearch.client.codegen.model.Deprecation; import org.opensearch.client.codegen.utils.Maps; +import org.opensearch.client.codegen.utils.Versions; +import org.semver4j.Semver; public class OpenApiParameter extends OpenApiRefElement { @Nullable @@ -31,7 +33,7 @@ public class OpenApiParameter extends OpenApiRefElement { @Nullable private final Boolean isDeprecated; @Nullable - private final String versionDeprecated; + private final Semver versionDeprecated; @Nullable private final String deprecationMessage; @Nullable @@ -46,7 +48,7 @@ protected OpenApiParameter(@Nullable OpenApiElement parent, @Nonnull JsonPoin this.schema = child("schema", parameter.getSchema(), OpenApiSchema::new); this.isDeprecated = parameter.getDeprecated(); var extensions = parameter.getExtensions(); - this.versionDeprecated = Maps.tryGet(extensions, "x-version-deprecated").map(String::valueOf).orElse(null); + this.versionDeprecated = Maps.tryGet(extensions, "x-version-deprecated").map(v -> Versions.coerce((String) v)).orElse(null); this.deprecationMessage = Maps.tryGet(extensions, "x-deprecation-message").map(String::valueOf).orElse(null); this.isGlobal = (Boolean) Maps.tryGet(extensions, "x-global").orElse(null); } diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/openapi/OpenApiSchema.java b/java-codegen/src/main/java/org/opensearch/client/codegen/openapi/OpenApiSchema.java index 5928c63fce..d48d1140e7 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/openapi/OpenApiSchema.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/openapi/OpenApiSchema.java @@ -24,6 +24,8 @@ import org.opensearch.client.codegen.utils.Lists; import org.opensearch.client.codegen.utils.Maps; import org.opensearch.client.codegen.utils.Sets; +import org.opensearch.client.codegen.utils.Versions; +import org.semver4j.Semver; public class OpenApiSchema extends OpenApiRefElement { private static final JsonPointer ANONYMOUS = JsonPointer.of(""); @@ -65,6 +67,8 @@ public class OpenApiSchema extends OpenApiRefElement { private final String title; @Nullable private final String pattern; + @Nullable + private final Semver versionRemoved; private OpenApiSchema(@Nonnull Builder builder) { super(builder.parent, Objects.requireNonNull(builder.pointer, "pointer must not be null"), builder.$ref, OpenApiSchema.class); @@ -84,6 +88,7 @@ private OpenApiSchema(@Nonnull Builder builder) { required = builder.required; title = builder.title; pattern = builder.pattern; + versionRemoved = builder.versionRemoved; } protected OpenApiSchema(@Nullable OpenApiElement parent, @Nonnull JsonPointer pointer, @Nonnull Schema schema) { @@ -135,6 +140,8 @@ protected OpenApiSchema(@Nullable OpenApiElement parent, @Nonnull JsonPointer // noinspection unchecked deprecatedEnums = Maps.tryGet(extensions, "x-deprecated-enums").map(e -> (Collection) e).map(HashSet::new).orElse(null); + + versionRemoved = Maps.tryGet(extensions, "x-version-removed").map(v -> Versions.coerce((String) v)).orElse(null); } @Nonnull @@ -258,6 +265,11 @@ public Optional getPattern() { return Optional.ofNullable(pattern); } + @Nonnull + public Optional getVersionRemoved() { + return Optional.ofNullable(versionRemoved); + } + public static Set determineTypes(List schemas) { return schemas.stream().map(OpenApiSchema::determineTypes).flatMap(Set::stream).collect(Collectors.toSet()); } @@ -338,6 +350,8 @@ public static class Builder { private String title; @Nullable private String pattern; + @Nullable + private Semver versionRemoved; @Nonnull public Builder withPointer(@Nonnull JsonPointer pointer) { diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/utils/Strings.java b/java-codegen/src/main/java/org/opensearch/client/codegen/utils/Strings.java index a8afed9249..d6a751a84f 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/utils/Strings.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/utils/Strings.java @@ -8,7 +8,9 @@ package org.opensearch.client.codegen.utils; +import java.util.HashMap; import java.util.Locale; +import java.util.Map; import java.util.Objects; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -35,12 +37,22 @@ public static String requireNonBlank(@Nullable String str, @Nullable String mess return str; } + private static final Map SPECIAL_CASE_SNAKE_CASE_CONVERSION = new HashMap<>() { + { + put("noop", "no_op"); + } + }; + @Nonnull public static String toSnakeCase(@Nonnull String str) { Objects.requireNonNull(str, "str must not be null"); if (str.isEmpty()) { return str; } + + var specialCase = SPECIAL_CASE_SNAKE_CASE_CONVERSION.get(str); + if (specialCase != null) return specialCase; + return str.replaceAll("([A-Z]+)([A-Z][a-z])", "$1_$2") .replaceAll("([a-z\\d])([A-Z])", "$1_$2") .replaceAll("(\\s|[-:.])", "_") diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/utils/Versions.java b/java-codegen/src/main/java/org/opensearch/client/codegen/utils/Versions.java new file mode 100644 index 0000000000..288c1bac88 --- /dev/null +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/utils/Versions.java @@ -0,0 +1,25 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.client.codegen.utils; + +import javax.annotation.Nonnull; +import org.semver4j.Semver; + +public final class Versions { + private Versions() {} + + public static final Semver V2_0_0 = Semver.of(2, 0, 0); + + @Nonnull + public static Semver coerce(String str) { + var version = Semver.coerce(str); + if (version == null) throw new IllegalArgumentException("Unable to coerce `" + str + "` to semver"); + return version; + } +} diff --git a/java-codegen/src/main/resources/org/opensearch/client/codegen/templates/Partials/ClassHeader.mustache b/java-codegen/src/main/resources/org/opensearch/client/codegen/templates/Partials/ClassHeader.mustache index b04007b760..04f604493e 100644 --- a/java-codegen/src/main/resources/org/opensearch/client/codegen/templates/Partials/ClassHeader.mustache +++ b/java-codegen/src/main/resources/org/opensearch/client/codegen/templates/Partials/ClassHeader.mustache @@ -5,6 +5,7 @@ * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ +{{#needsLegacyLicense}} /* * Licensed to Elasticsearch B.V. under one or more contributor @@ -29,6 +30,7 @@ * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. */ +{{/needsLegacyLicense}} //---------------------------------------------------- // THIS CODE IS GENERATED. MANUAL EDITS WILL BE LOST.