From c2d90049c37b53d866a37f0cc59aeba9cdb9b4f7 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Wed, 26 Jun 2024 16:45:37 +1200 Subject: [PATCH 1/4] Tweak client generation to extend from existing classes Signed-off-by: Thomas Farr --- .../client/codegen/model/Namespace.java | 62 ++++++++++++++++--- .../client/codegen/model/OperationGroup.java | 7 ++- .../client/codegen/model/RequestShape.java | 10 +-- .../client/codegen/model/SpecTransformer.java | 2 +- .../opensearch/client/codegen/model/Type.java | 4 ++ .../client/codegen/templates/Client.mustache | 23 ++++++- 6 files changed, 89 insertions(+), 19 deletions(-) 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 7ca9322130..3398b98583 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 @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -75,40 +76,83 @@ public void render(ShapeRenderingContext ctx) throws RenderException { shape.render(ctx); } + var operations = getOperationsForClient(); + if (operations.isEmpty()) return; - // TODO: Render clients when won't be partial and conflict with non-generated code - // new Client(this, false).render(outputDir, formatter); - // new Client(this, true).render(outputDir, formatter); + new Client(this, false, operations).render(ctx); + new Client(this, true, operations).render(ctx); + } + + private Collection getOperationsForClient() { + if ("core".equals(name)) return Collections.emptyList(); + return ("".equals(name) ? child("core") : this).operations.values(); + } + + private String getClientClassName(boolean async, boolean base) { + return "OpenSearch" + Strings.toPascalCase(name) + (async ? "Async" : "") + "Client" + (base ? "Base" : ""); + } + + private Type getClientType(boolean async, boolean base) { + var type = Type.builder().pkg(getPackageName()).name(getClientClassName(async, base)); + if (base) { + type.genericArgs(getClientType(async, false)); + } + return type.build(); } private static class Client extends Shape { private final boolean async; + private final Collection operations; - private Client(Namespace parent, boolean async) { - super(parent, "OpenSearch" + Strings.toPascalCase(parent.name) + (async ? "Async" : "") + "Client", null, null); + private Client(Namespace parent, boolean async, Collection operations) { + super(parent, parent.getClientClassName(async, false), null, null); this.async = async; + this.operations = operations; } @Override public Type getExtendsType() { - return Types.Client.ApiClient(Types.Client.Transport.OpenSearchTransport, getType()); + switch (parent.name) { + case "": + return parent.getClientType(async, true); + default: + return Types.Client.ApiClient(Types.Client.Transport.OpenSearchTransport, getType()); + } } public String getName() { return parent.name; } - public Collection getChildren() { - return Lists.filterMap(parent.children.values(), n -> !n.operations.isEmpty(), n -> new Client(n, async)); + public Collection getChildren() { + return Lists.filterMap(parent.children.values(), n -> !n.getOperationsForClient().isEmpty(), n -> new ClientRef(n, async)); } public Collection getOperations() { - return parent.operations.values(); + return operations; } public boolean isAsync() { return this.async; } + + private static class ClientRef { + private final Type type; + private final String name; + + public ClientRef(Namespace namespace, boolean async) { + this.type = namespace.getClientType(async, false); + this.name = namespace.name; + } + + public Type getType() { + return type; + } + + public String getName() { + return name; + } + } } } 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 fa158e8e5f..818a4acd40 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 @@ -36,7 +36,7 @@ public static OperationGroup from(@Nonnull String operationGroup) { return new OperationGroup(operationGroup.substring(0, index), operationGroup.substring(index + 1)); } - private OperationGroup(@Nullable String namespace, @Nonnull String name) { + public OperationGroup(@Nullable String namespace, @Nonnull String name) { this.namespace = namespace; this.name = Strings.requireNonBlank(name, "name must not be blank"); } @@ -51,6 +51,11 @@ public String getName() { return name; } + @Nonnull + public String asTypedefPrefix() { + return (namespace == null ? "_global" : namespace) + "." + name; + } + @Override public String toString() { return namespace == null ? name : namespace + "." + name; 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 3d0e25ef7e..b46ef19025 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 @@ -37,7 +37,7 @@ public class RequestShape extends ObjectShape { private final Map fields = new TreeMap<>(); public RequestShape(@Nonnull Namespace parent, @Nonnull OperationGroup operationGroup, @Nullable String description) { - super(parent, requestClassName(operationGroup), operationGroup + ".Request", description); + super(parent, requestClassName(operationGroup), operationGroup.asTypedefPrefix() + ".Request", description); this.operationGroup = operationGroup; } @@ -72,8 +72,8 @@ public void addSupportedHttpMethod(String method) { httpMethods.add(method); } - public String getResponseType() { - return responseClassName(operationGroup); + public Type getResponseType() { + return Type.builder().pkg(getPackageName()).name(responseClassName(operationGroup)).build(); } public boolean canBeSingleton() { @@ -145,13 +145,13 @@ public boolean hasAnyRequiredFields() { } @Nonnull - public static String requestClassName(@Nonnull OperationGroup operationGroup) { + private static String requestClassName(@Nonnull OperationGroup operationGroup) { Objects.requireNonNull(operationGroup, "operationGroup must not be null"); return Strings.toPascalCase(operationGroup.getName()) + "Request"; } @Nonnull - public static String responseClassName(@Nonnull OperationGroup operationGroup) { + private static String responseClassName(@Nonnull OperationGroup operationGroup) { Objects.requireNonNull(operationGroup, "operationGroup must not be null"); return Strings.toPascalCase(operationGroup.getName()) + "Response"; } 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 e228764097..6848dc7b9c 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 @@ -107,7 +107,7 @@ private void visit(@Nonnull OperationGroup group, @Nonnull List{{/async}} {{#camelCase}}{{id}}{{/camelCase}}() throws {{TYPES.Java.Io.IOException}}, {{TYPES.Client.OpenSearch._Types.OpenSearchException}} { + return this.transport.performRequest{{#async}}Async{{/async}}({{type}}._INSTANCE, {{type}}._ENDPOINT, this.transportOptions); + } + {{/canBeSingleton}} + {{^canBeSingleton}} /** * {{description}} */ public {{#async}}{{TYPES.Java.Util.Concurrent.CompletableFuture}}<{{/async}}{{responseType}}{{#async}}>{{/async}} {{#camelCase}}{{id}}{{/camelCase}}({{type}} request) throws {{TYPES.Java.Io.IOException}}, {{TYPES.Client.OpenSearch._Types.OpenSearchException}} { - return this.transport.performRequest{{#async}}Async{{/async}}(request, {{type}}._ENDPOINT, this.transportOptions); + @SuppressWarnings("unchecked") + {{jsonEndpointType}} endpoint = ({{jsonEndpointType}}) {{type.name}}._ENDPOINT; + + return this.transport.performRequest{{#async}}Async{{/async}}(request, endpoint, this.transportOptions); } /** @@ -44,8 +60,9 @@ */ public {{#async}}{{TYPES.Java.Util.Concurrent.CompletableFuture}}<{{/async}}{{responseType}}{{#async}}>{{/async}} {{#camelCase}}{{id}}{{/camelCase}}() throws IOException, OpenSearchException { - return {{#camelCase}}{{id}}{{/camelCase}}(new {{type.builderType}}().build()); + return this.transport.performRequest{{#async}}Async{{/async}}(new {{type.builderType}}().build(), {{type.name}}._ENDPOINT, this.transportOptions); } {{/hasAnyRequiredFields}} + {{/canBeSingleton}} {{/operations}} -} \ No newline at end of file +} From bb5523f4ab5875ee9a19a2a56d0f6c51c6b358f4 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Wed, 26 Jun 2024 16:49:47 +1200 Subject: [PATCH 2/4] Modify existing client classes to be abstract base classes Signed-off-by: Thomas Farr --- ...nt.java => OpenSearchAsyncClientBase.java} | 25 +++---------------- ...hClient.java => OpenSearchClientBase.java} | 25 +++---------------- 2 files changed, 6 insertions(+), 44 deletions(-) rename java-client/src/main/java/org/opensearch/client/opensearch/{OpenSearchAsyncClient.java => OpenSearchAsyncClientBase.java} (98%) rename java-client/src/main/java/org/opensearch/client/opensearch/{OpenSearchClient.java => OpenSearchClientBase.java} (98%) diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClient.java b/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClientBase.java similarity index 98% rename from java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClient.java rename to java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClientBase.java index 5d869c6f59..bb5d52102e 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClient.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClientBase.java @@ -140,21 +140,13 @@ /** * Client for the namespace. */ -public class OpenSearchAsyncClient extends ApiClient { +public abstract class OpenSearchAsyncClientBase> + extends ApiClient { - public OpenSearchAsyncClient(OpenSearchTransport transport) { - super(transport, null); - } - - public OpenSearchAsyncClient(OpenSearchTransport transport, @Nullable TransportOptions transportOptions) { + public OpenSearchAsyncClientBase(OpenSearchTransport transport, @Nullable TransportOptions transportOptions) { super(transport, transportOptions); } - @Override - public OpenSearchAsyncClient withTransportOptions(@Nullable TransportOptions transportOptions) { - return new OpenSearchAsyncClient(this.transport, transportOptions); - } - // ----- Child clients public OpenSearchCatAsyncClient cat() { @@ -897,17 +889,6 @@ public final CompletableFuture index( return index(fn.apply(new IndexRequest.Builder()).build()); } - // ----- Endpoint: info - - /** - * Returns basic information about the cluster. - * - * - */ - public CompletableFuture info() throws IOException, OpenSearchException { - return this.transport.performRequestAsync(InfoRequest._INSTANCE, InfoRequest._ENDPOINT, this.transportOptions); - } - // ----- Endpoint: list_point_in_time /** diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClient.java b/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClientBase.java similarity index 98% rename from java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClient.java rename to java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClientBase.java index ee83bcc20d..ad839f183d 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClient.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClientBase.java @@ -140,21 +140,13 @@ /** * Client for the namespace. */ -public class OpenSearchClient extends ApiClient { +public abstract class OpenSearchClientBase> + extends ApiClient { - public OpenSearchClient(OpenSearchTransport transport) { - super(transport, null); - } - - public OpenSearchClient(OpenSearchTransport transport, @Nullable TransportOptions transportOptions) { + public OpenSearchClientBase(OpenSearchTransport transport, @Nullable TransportOptions transportOptions) { super(transport, transportOptions); } - @Override - public OpenSearchClient withTransportOptions(@Nullable TransportOptions transportOptions) { - return new OpenSearchClient(this.transport, transportOptions); - } - // ----- Child clients public OpenSearchGenericClient generic() { return new OpenSearchGenericClient(this.transport, this.transportOptions); @@ -883,17 +875,6 @@ public final IndexResponse index(Function()).build()); } - // ----- Endpoint: info - - /** - * Returns basic information about the cluster. - * - * - */ - public InfoResponse info() throws IOException, OpenSearchException { - return this.transport.performRequest(InfoRequest._INSTANCE, InfoRequest._ENDPOINT, this.transportOptions); - } - // ----- Endpoint: list_point_in_time /** From 6c3cb7304a847be95379e1f88cd841eced3d22a9 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Wed, 26 Jun 2024 16:51:40 +1200 Subject: [PATCH 3/4] Re-run generator Signed-off-by: Thomas Farr --- .../opensearch/OpenSearchAsyncClient.java | 72 +++++++++++++++++++ .../client/opensearch/OpenSearchClient.java | 71 ++++++++++++++++++ .../client/opensearch/core/InfoRequest.java | 2 +- 3 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 java-client/src/generated/java/org/opensearch/client/opensearch/OpenSearchAsyncClient.java create mode 100644 java-client/src/generated/java/org/opensearch/client/opensearch/OpenSearchClient.java diff --git a/java-client/src/generated/java/org/opensearch/client/opensearch/OpenSearchAsyncClient.java b/java-client/src/generated/java/org/opensearch/client/opensearch/OpenSearchAsyncClient.java new file mode 100644 index 0000000000..77f05da118 --- /dev/null +++ b/java-client/src/generated/java/org/opensearch/client/opensearch/OpenSearchAsyncClient.java @@ -0,0 +1,72 @@ +/* + * 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. + */ + +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +//---------------------------------------------------- +// THIS CODE IS GENERATED. MANUAL EDITS WILL BE LOST. +//---------------------------------------------------- + +package org.opensearch.client.opensearch; + +import java.io.IOException; +import java.util.concurrent.CompletableFuture; +import javax.annotation.Generated; +import javax.annotation.Nullable; +import org.opensearch.client.opensearch._types.OpenSearchException; +import org.opensearch.client.opensearch.core.InfoRequest; +import org.opensearch.client.opensearch.core.InfoResponse; +import org.opensearch.client.transport.OpenSearchTransport; +import org.opensearch.client.transport.TransportOptions; + +@Generated("org.opensearch.client.codegen.CodeGenerator") +public class OpenSearchAsyncClient extends OpenSearchAsyncClientBase { + public OpenSearchAsyncClient(OpenSearchTransport transport) { + super(transport, null); + } + + public OpenSearchAsyncClient(OpenSearchTransport transport, @Nullable TransportOptions transportOptions) { + super(transport, transportOptions); + } + + @Override + public OpenSearchAsyncClient withTransportOptions(@Nullable TransportOptions transportOptions) { + return new OpenSearchAsyncClient(this.transport, transportOptions); + } + + // ----- Endpoint: info + + /** + * Returns basic information about the cluster. + */ + public CompletableFuture info() throws IOException, OpenSearchException { + return this.transport.performRequestAsync(InfoRequest._INSTANCE, InfoRequest._ENDPOINT, this.transportOptions); + } +} diff --git a/java-client/src/generated/java/org/opensearch/client/opensearch/OpenSearchClient.java b/java-client/src/generated/java/org/opensearch/client/opensearch/OpenSearchClient.java new file mode 100644 index 0000000000..87e3cdc45a --- /dev/null +++ b/java-client/src/generated/java/org/opensearch/client/opensearch/OpenSearchClient.java @@ -0,0 +1,71 @@ +/* + * 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. + */ + +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +//---------------------------------------------------- +// THIS CODE IS GENERATED. MANUAL EDITS WILL BE LOST. +//---------------------------------------------------- + +package org.opensearch.client.opensearch; + +import java.io.IOException; +import javax.annotation.Generated; +import javax.annotation.Nullable; +import org.opensearch.client.opensearch._types.OpenSearchException; +import org.opensearch.client.opensearch.core.InfoRequest; +import org.opensearch.client.opensearch.core.InfoResponse; +import org.opensearch.client.transport.OpenSearchTransport; +import org.opensearch.client.transport.TransportOptions; + +@Generated("org.opensearch.client.codegen.CodeGenerator") +public class OpenSearchClient extends OpenSearchClientBase { + public OpenSearchClient(OpenSearchTransport transport) { + super(transport, null); + } + + public OpenSearchClient(OpenSearchTransport transport, @Nullable TransportOptions transportOptions) { + super(transport, transportOptions); + } + + @Override + public OpenSearchClient withTransportOptions(@Nullable TransportOptions transportOptions) { + return new OpenSearchClient(this.transport, transportOptions); + } + + // ----- Endpoint: info + + /** + * Returns basic information about the cluster. + */ + public InfoResponse info() throws IOException, OpenSearchException { + return this.transport.performRequest(InfoRequest._INSTANCE, InfoRequest._ENDPOINT, this.transportOptions); + } +} diff --git a/java-client/src/generated/java/org/opensearch/client/opensearch/core/InfoRequest.java b/java-client/src/generated/java/org/opensearch/client/opensearch/core/InfoRequest.java index ab8265f76e..6c9e5d2202 100644 --- a/java-client/src/generated/java/org/opensearch/client/opensearch/core/InfoRequest.java +++ b/java-client/src/generated/java/org/opensearch/client/opensearch/core/InfoRequest.java @@ -42,7 +42,7 @@ import org.opensearch.client.transport.Endpoint; import org.opensearch.client.transport.endpoints.SimpleEndpoint; -// typedef: info.Request +// typedef: _global.info.Request /** * Returns basic information about the cluster. From a089f12df86b89d4b3a6d38d52177aa4038e2f91 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Wed, 26 Jun 2024 17:37:02 +1200 Subject: [PATCH 4/4] ./gradlew spotlessApply Signed-off-by: Thomas Farr --- .../client/opensearch/OpenSearchAsyncClientBase.java | 5 +---- .../opensearch/client/opensearch/OpenSearchClientBase.java | 5 +---- .../main/java/org/opensearch/client/codegen/model/Type.java | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClientBase.java b/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClientBase.java index bb5d52102e..8250942fd3 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClientBase.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClientBase.java @@ -75,8 +75,6 @@ import org.opensearch.client.opensearch.core.GetSourceResponse; import org.opensearch.client.opensearch.core.IndexRequest; import org.opensearch.client.opensearch.core.IndexResponse; -import org.opensearch.client.opensearch.core.InfoRequest; -import org.opensearch.client.opensearch.core.InfoResponse; import org.opensearch.client.opensearch.core.MgetRequest; import org.opensearch.client.opensearch.core.MgetResponse; import org.opensearch.client.opensearch.core.MsearchRequest; @@ -140,8 +138,7 @@ /** * Client for the namespace. */ -public abstract class OpenSearchAsyncClientBase> - extends ApiClient { +public abstract class OpenSearchAsyncClientBase> extends ApiClient { public OpenSearchAsyncClientBase(OpenSearchTransport transport, @Nullable TransportOptions transportOptions) { super(transport, transportOptions); diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClientBase.java b/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClientBase.java index ad839f183d..d4b2d661cd 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClientBase.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClientBase.java @@ -74,8 +74,6 @@ import org.opensearch.client.opensearch.core.GetSourceResponse; import org.opensearch.client.opensearch.core.IndexRequest; import org.opensearch.client.opensearch.core.IndexResponse; -import org.opensearch.client.opensearch.core.InfoRequest; -import org.opensearch.client.opensearch.core.InfoResponse; import org.opensearch.client.opensearch.core.MgetRequest; import org.opensearch.client.opensearch.core.MgetResponse; import org.opensearch.client.opensearch.core.MsearchRequest; @@ -140,8 +138,7 @@ /** * Client for the namespace. */ -public abstract class OpenSearchClientBase> - extends ApiClient { +public abstract class OpenSearchClientBase> extends ApiClient { public OpenSearchClientBase(OpenSearchTransport transport, @Nullable TransportOptions transportOptions) { super(transport, transportOptions); diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/model/Type.java b/java-codegen/src/main/java/org/opensearch/client/codegen/model/Type.java index c0cb7a31e1..96ef37d344 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/model/Type.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/model/Type.java @@ -69,7 +69,7 @@ public String toString() { } return str; } - + public String getName() { return name; }