diff --git a/src/main/java/org/opensearch/sdk/NamedWriteableRegistryAPI.java b/src/main/java/org/opensearch/sdk/ExtensionNamedWriteableRegistry.java similarity index 90% rename from src/main/java/org/opensearch/sdk/NamedWriteableRegistryAPI.java rename to src/main/java/org/opensearch/sdk/ExtensionNamedWriteableRegistry.java index fca1e655..2f000ebe 100644 --- a/src/main/java/org/opensearch/sdk/NamedWriteableRegistryAPI.java +++ b/src/main/java/org/opensearch/sdk/ExtensionNamedWriteableRegistry.java @@ -29,25 +29,25 @@ /** * API used to handle named writeable registry requests from OpenSearch */ -public class NamedWriteableRegistryAPI { - private final Logger logger = LogManager.getLogger(NamedWriteableRegistryAPI.class); +public class ExtensionNamedWriteableRegistry { + private final Logger logger = LogManager.getLogger(ExtensionNamedWriteableRegistry.class); private List namedWriteables; private final NamedWriteableRegistry namedWriteableRegistry; /** - * Constructor for NamedWriteableRegistryAPI. Creates a NamedWriteableRegistry for this extension + * Constructor for ExtensionNamedWriteableRegistry. Creates a NamedWriteableRegistry for this extension */ - public NamedWriteableRegistryAPI() { + public ExtensionNamedWriteableRegistry() { this.namedWriteables = getNamedWriteables(); this.namedWriteableRegistry = new NamedWriteableRegistry(namedWriteables); } /** - * Constructor for NamedWriteableRegistryAPI. Creates and populates a NamedWriteableRegistry with the given NamedWriteableRegistry entries for this extension + * Constructor for ExtensionNamedWriteableRegistry. Creates and populates a NamedWriteableRegistry with the given NamedWriteableRegistry entries for this extension * * @param extensionNamedWriteables List of NamedWriteableRegistry.Entry to be registered */ - public NamedWriteableRegistryAPI(List extensionNamedWriteables) { + public ExtensionNamedWriteableRegistry(List extensionNamedWriteables) { this.namedWriteables = extensionNamedWriteables; this.namedWriteableRegistry = new NamedWriteableRegistry(namedWriteables); } diff --git a/src/main/java/org/opensearch/sdk/ExtensionRestRequest.java b/src/main/java/org/opensearch/sdk/ExtensionRestRequest.java index 978c9f49..5f170a59 100644 --- a/src/main/java/org/opensearch/sdk/ExtensionRestRequest.java +++ b/src/main/java/org/opensearch/sdk/ExtensionRestRequest.java @@ -56,7 +56,7 @@ protected ExtensionRestRequest(RestExecuteOnExtensionRequest request) throws Ill /** * Object generated from input stream * @param in Input stream - * @throws IOException + * @throws IOException if there's an error in generating object from input stream */ public ExtensionRestRequest(StreamInput in) throws IOException { super(in); @@ -68,7 +68,7 @@ public ExtensionRestRequest(StreamInput in) throws IOException { /** * Write this object to output stream * @param out the writeable output stream - * @throws IOException + * @throws IOException if there's an error in generating object from output stream */ @Override public void writeTo(StreamOutput out) throws IOException { diff --git a/src/main/java/org/opensearch/sdk/ExtensionsRunner.java b/src/main/java/org/opensearch/sdk/ExtensionsRunner.java index 30b8ea59..6ad1d1e9 100644 --- a/src/main/java/org/opensearch/sdk/ExtensionsRunner.java +++ b/src/main/java/org/opensearch/sdk/ExtensionsRunner.java @@ -15,22 +15,18 @@ import org.opensearch.Version; import org.opensearch.cluster.ClusterModule; import org.opensearch.cluster.node.DiscoveryNode; -import org.opensearch.common.bytes.BytesReference; import org.opensearch.common.io.stream.NamedWriteableRegistry; import org.opensearch.common.io.stream.NamedWriteableRegistryParseRequest; import org.opensearch.extensions.OpenSearchRequest; import org.opensearch.extensions.rest.RegisterRestActionsRequest; import org.opensearch.extensions.rest.RestExecuteOnExtensionRequest; -import org.opensearch.extensions.rest.RestExecuteOnExtensionResponse; import org.opensearch.extensions.settings.RegisterCustomSettingsRequest; import org.opensearch.common.network.NetworkModule; import org.opensearch.common.network.NetworkService; import org.opensearch.common.settings.Setting; import org.opensearch.common.settings.Settings; import org.opensearch.common.util.PageCacheRecycler; -import org.opensearch.extensions.ExtensionBooleanResponse; import org.opensearch.discovery.InitializeExtensionsRequest; -import org.opensearch.discovery.InitializeExtensionsResponse; import org.opensearch.extensions.ExtensionActionListenerOnFailureRequest; import org.opensearch.extensions.DiscoveryExtension; import org.opensearch.extensions.EnvironmentSettingsRequest; @@ -39,13 +35,10 @@ import org.opensearch.extensions.ExtensionRequest; import org.opensearch.extensions.ExtensionsOrchestrator; import org.opensearch.index.IndicesModuleRequest; -import org.opensearch.index.IndicesModuleResponse; import org.opensearch.indices.IndicesModule; import org.opensearch.indices.breaker.CircuitBreakerService; import org.opensearch.indices.breaker.NoneCircuitBreakerService; -import org.opensearch.rest.RestStatus; import org.opensearch.rest.RestHandler.Route; -import org.opensearch.rest.RestResponse; import org.opensearch.transport.netty4.Netty4Transport; import org.opensearch.transport.SharedGroupFactory; import org.opensearch.sdk.handlers.ActionListenerOnFailureResponseHandler; @@ -53,9 +46,14 @@ import org.opensearch.sdk.handlers.ClusterStateResponseHandler; import org.opensearch.sdk.handlers.EnvironmentSettingsResponseHandler; import org.opensearch.sdk.handlers.ExtensionBooleanResponseHandler; +import org.opensearch.sdk.handlers.ExtensionsIndicesModuleNameRequestHandler; +import org.opensearch.sdk.handlers.ExtensionsIndicesModuleRequestHandler; +import org.opensearch.sdk.handlers.ExtensionsInitRequestHandler; +import org.opensearch.sdk.handlers.ExtensionsRestRequestHandler; import org.opensearch.sdk.handlers.LocalNodeResponseHandler; import org.opensearch.sdk.handlers.UpdateSettingsRequestHandler; import org.opensearch.sdk.handlers.ExtensionStringResponseHandler; +import org.opensearch.sdk.handlers.OpensearchRequestHandler; import org.opensearch.search.SearchModule; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.ClusterConnectionManager; @@ -63,7 +61,6 @@ import org.opensearch.transport.TransportInterceptor; import org.opensearch.transport.TransportService; import org.opensearch.transport.TransportSettings; -import org.opensearch.transport.TransportResponse; import java.io.File; import java.io.IOException; @@ -91,23 +88,46 @@ public class ExtensionsRunner { private static final String NODE_NAME_SETTING = "node.name"; private String uniqueId; - private DiscoveryNode opensearchNode; + /** + * This field is initialized by a call from {@link ExtensionsInitRequestHandler}. + */ + public DiscoveryNode opensearchNode; private DiscoveryExtension extensionNode; - private TransportService extensionTransportService = null; + /** + * This field is initialized by a call from {@link ExtensionsInitRequestHandler}. + */ + public TransportService extensionTransportService = null; // The routes and classes which handle the REST requests private final ExtensionRestPathRegistry extensionRestPathRegistry = new ExtensionRestPathRegistry(); // Custom settings from the extension's getSettings + /** + * This field is initialized by a call from {@link ExtensionsInitRequestHandler}. + */ private final List> customSettings; // Node name, host, and port - private final Settings settings; + /** + * This field is initialized by a call from {@link ExtensionsInitRequestHandler}. + */ + public final Settings settings; private final TransportInterceptor NOOP_TRANSPORT_INTERCEPTOR = new TransportInterceptor() { }; - private NamedWriteableRegistryAPI namedWriteableRegistryApi = new NamedWriteableRegistryAPI(); + private ExtensionNamedWriteableRegistry namedWriteableRegistryApi = new ExtensionNamedWriteableRegistry(); + private ExtensionsInitRequestHandler extensionsInitRequestHandler = new ExtensionsInitRequestHandler(); + private OpensearchRequestHandler opensearchRequestHandler = new OpensearchRequestHandler(); + private ExtensionsIndicesModuleRequestHandler extensionsIndicesModuleRequestHandler = new ExtensionsIndicesModuleRequestHandler(); + private ExtensionsIndicesModuleNameRequestHandler extensionsIndicesModuleNameRequestHandler = + new ExtensionsIndicesModuleNameRequestHandler(); + private ExtensionsRestRequestHandler extensionsRestRequestHandler = new ExtensionsRestRequestHandler(); + /* * TODO: expose an interface for extension to register actions * https://github.com/opensearch-project/opensearch-sdk-java/issues/119 */ - private TransportActions transportActions = new TransportActions(new HashMap<>()); + /** + * Instantiates a new transportActions + */ + public TransportActions transportActions = new TransportActions(new HashMap<>()); + /** * Instantiates a new update settings request handler */ @@ -161,11 +181,19 @@ private static ExtensionSettings readExtensionSettings() throws IOException { return objectMapper.readValue(file, ExtensionSettings.class); } + /** + * This method is call from {@link ExtensionsInitRequestHandler}. + * @param extensionTransportService assign value for extensionTransportService + */ void setExtensionTransportService(TransportService extensionTransportService) { this.extensionTransportService = extensionTransportService; } - private void setUniqueId(String id) { + /** + * Sets the Unique ID, used in REST requests to uniquely identify this extension + * @param id assign value for id + */ + public void setUniqueId(String id) { this.uniqueId = id; } @@ -173,11 +201,11 @@ String getUniqueId() { return uniqueId; } - private void setOpensearchNode(DiscoveryNode opensearchNode) { + public void setOpensearchNode(DiscoveryNode opensearchNode) { this.opensearchNode = opensearchNode; } - private void setExtensionNode(DiscoveryExtension extensionNode) { + public void setExtensionNode(DiscoveryExtension extensionNode) { this.extensionNode = extensionNode; } @@ -185,107 +213,6 @@ DiscoveryNode getOpensearchNode() { return opensearchNode; } - /** - * Handles a extension request from OpenSearch. This is the first request for the transport communication and will initialize the extension and will be a part of OpenSearch bootstrap. - * - * @param extensionInitRequest The request to handle. - * @return A response to OpenSearch validating that this is an extension. - */ - InitializeExtensionsResponse handleExtensionInitRequest(InitializeExtensionsRequest extensionInitRequest) { - logger.info("Registering Extension Request received from OpenSearch"); - opensearchNode = extensionInitRequest.getSourceNode(); - setUniqueId(extensionInitRequest.getExtension().getId()); - // Successfully initialized. Send the response. - try { - return new InitializeExtensionsResponse(settings.get(NODE_NAME_SETTING)); - } finally { - // After sending successful response to initialization, send the REST API and Settings - setOpensearchNode(opensearchNode); - setExtensionNode(extensionInitRequest.getExtension()); - extensionTransportService.connectToNode(opensearchNode); - sendRegisterRestActionsRequest(extensionTransportService); - sendRegisterCustomSettingsRequest(extensionTransportService); - transportActions.sendRegisterTransportActionsRequest(extensionTransportService, opensearchNode); - } - } - - /** - * Handles a request from OpenSearch and invokes the extension point API corresponding with the request type - * - * @param request The request to handle. - * @return A response to OpenSearch for the corresponding API - * @throws Exception if the corresponding handler for the request is not present - */ - TransportResponse handleOpenSearchRequest(OpenSearchRequest request) throws Exception { - // Read enum - switch (request.getRequestType()) { - case REQUEST_OPENSEARCH_NAMED_WRITEABLE_REGISTRY: - return namedWriteableRegistryApi.handleNamedWriteableRegistryRequest(request); - // Add additional request handlers here - default: - throw new Exception("Handler not present for the provided request"); - } - } - - /** - * Handles a request for extension point indices from OpenSearch. The {@link #handleExtensionInitRequest(InitializeExtensionsRequest)} method must have been called first to initialize the extension. - * - * @param indicesModuleRequest The request to handle. - * @param transportService The transport service communicating with OpenSearch. - * @return A response to OpenSearch with this extension's index and search listeners. - */ - IndicesModuleResponse handleIndicesModuleRequest(IndicesModuleRequest indicesModuleRequest, TransportService transportService) { - logger.info("Registering Indices Module Request received from OpenSearch"); - IndicesModuleResponse indicesModuleResponse = new IndicesModuleResponse(true, true, true); - return indicesModuleResponse; - } - - /** - * Handles a request for extension name from OpenSearch. The {@link #handleExtensionInitRequest(InitializeExtensionsRequest)} method must have been called first to initialize the extension. - * - * @param indicesModuleRequest The request to handle. - * @return A response acknowledging the request. - */ - ExtensionBooleanResponse handleIndicesModuleNameRequest(IndicesModuleRequest indicesModuleRequest) { - // Works as beforeIndexRemoved - logger.info("Registering Indices Module Name Request received from OpenSearch"); - ExtensionBooleanResponse indicesModuleNameResponse = new ExtensionBooleanResponse(true); - return indicesModuleNameResponse; - } - - /** - * Handles a request from OpenSearch to execute a REST request on the extension. - * - * @param request The REST request to execute. - * @return A response acknowledging the request. - */ - RestExecuteOnExtensionResponse handleRestExecuteOnExtensionRequest(RestExecuteOnExtensionRequest request) { - - ExtensionRestHandler restHandler = extensionRestPathRegistry.getHandler(request.getMethod(), request.getUri()); - if (restHandler == null) { - return new RestExecuteOnExtensionResponse( - RestStatus.NOT_FOUND, - "No handler for " + ExtensionRestPathRegistry.restPathToString(request.getMethod(), request.getUri()) - ); - } - // ExtensionRestRequest restRequest = new ExtensionRestRequest(request); - ExtensionRestRequest restRequest = new ExtensionRestRequest( - request.getMethod(), - request.getUri(), - request.getRequestIssuerIdentity() - ); - - // Get response from extension - RestResponse response = restHandler.handleRequest(restRequest); - logger.info("Sending extension response to OpenSearch: " + response.status()); - return new RestExecuteOnExtensionResponse( - response.status(), - response.contentType(), - BytesReference.toBytes(response.content()), - response.getHeaders() - ); - } - /** * Initializes a Netty4Transport object. This object will be wrapped in a {@link TransportService} object. * @@ -381,7 +308,7 @@ public void startTransportService(TransportService transportService) { false, false, InitializeExtensionsRequest::new, - (request, channel, task) -> channel.sendResponse(handleExtensionInitRequest(request)) + (request, channel, task) -> channel.sendResponse(extensionsInitRequestHandler.handleExtensionInitRequest(request, this)) ); transportService.registerRequestHandler( @@ -390,7 +317,7 @@ public void startTransportService(TransportService transportService) { false, false, OpenSearchRequest::new, - (request, channel, task) -> channel.sendResponse(handleOpenSearchRequest(request)) + (request, channel, task) -> channel.sendResponse(opensearchRequestHandler.handleOpenSearchRequest(request)) ); transportService.registerRequestHandler( @@ -408,7 +335,9 @@ public void startTransportService(TransportService transportService) { false, false, IndicesModuleRequest::new, - ((request, channel, task) -> channel.sendResponse(handleIndicesModuleRequest(request, transportService))) + ((request, channel, task) -> channel.sendResponse( + extensionsIndicesModuleRequestHandler.handleIndicesModuleRequest(request, transportService) + )) ); @@ -418,7 +347,9 @@ public void startTransportService(TransportService transportService) { false, false, IndicesModuleRequest::new, - ((request, channel, task) -> channel.sendResponse(handleIndicesModuleNameRequest(request))) + ((request, channel, task) -> channel.sendResponse( + extensionsIndicesModuleNameRequestHandler.handleIndicesModuleNameRequest(request) + )) ); transportService.registerRequestHandler( @@ -427,7 +358,7 @@ public void startTransportService(TransportService transportService) { false, false, RestExecuteOnExtensionRequest::new, - ((request, channel, task) -> channel.sendResponse(handleRestExecuteOnExtensionRequest(request))) + ((request, channel, task) -> channel.sendResponse(extensionsRestRequestHandler.handleRestExecuteOnExtensionRequest(request))) ); transportService.registerRequestHandler( diff --git a/src/main/java/org/opensearch/sdk/handlers/ExtensionsIndicesModuleNameRequestHandler.java b/src/main/java/org/opensearch/sdk/handlers/ExtensionsIndicesModuleNameRequestHandler.java new file mode 100644 index 00000000..c929ba71 --- /dev/null +++ b/src/main/java/org/opensearch/sdk/handlers/ExtensionsIndicesModuleNameRequestHandler.java @@ -0,0 +1,36 @@ +/* + * 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.sdk.handlers; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.extensions.ExtensionBooleanResponse; +import org.opensearch.sdk.ExtensionsRunner; +import org.opensearch.index.IndicesModuleRequest; + +/** + * This class handles the request from OpenSearch to a {@link ExtensionsRunner#startTransportService(TransportService transportService)} call. + */ + +public class ExtensionsIndicesModuleNameRequestHandler { + private static final Logger logger = LogManager.getLogger(ExtensionsIndicesModuleNameRequestHandler.class); + + /** + * Handles a request for extension name from OpenSearch. The {@link ExtensionsInitRequestHandler} method must have been called first to initialize the extension. + * + * @param indicesModuleRequest The request to handle. + * @return A response acknowledging the request. + */ + public ExtensionBooleanResponse handleIndicesModuleNameRequest(IndicesModuleRequest indicesModuleRequest) { + // Works as beforeIndexRemoved + logger.info("Registering Indices Module Name Request received from OpenSearch"); + ExtensionBooleanResponse indicesModuleNameResponse = new ExtensionBooleanResponse(true); + return indicesModuleNameResponse; + } + +} diff --git a/src/main/java/org/opensearch/sdk/handlers/ExtensionsIndicesModuleRequestHandler.java b/src/main/java/org/opensearch/sdk/handlers/ExtensionsIndicesModuleRequestHandler.java new file mode 100644 index 00000000..a923b25f --- /dev/null +++ b/src/main/java/org/opensearch/sdk/handlers/ExtensionsIndicesModuleRequestHandler.java @@ -0,0 +1,37 @@ +/* + * 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.sdk.handlers; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.index.IndicesModuleRequest; +import org.opensearch.index.IndicesModuleResponse; +import org.opensearch.sdk.ExtensionsRunner; +import org.opensearch.transport.TransportService; + +/** + * This class handles the request from OpenSearch to a {@link ExtensionsRunner#startTransportService(TransportService transportService)} call. + */ + +public class ExtensionsIndicesModuleRequestHandler { + private static final Logger logger = LogManager.getLogger(ExtensionsIndicesModuleRequestHandler.class); + + /** + * Handles a request for extension point indices from OpenSearch. The {@link ExtensionsInitRequestHandler} class must have been called first to initialize the extension. + * + * @param indicesModuleRequest The request to handle. + * @param transportService The transport service communicating with OpenSearch. + * @return A response to OpenSearch with this extension's index and search listeners. + */ + public IndicesModuleResponse handleIndicesModuleRequest(IndicesModuleRequest indicesModuleRequest, TransportService transportService) { + logger.info("Registering Indices Module Request received from OpenSearch"); + IndicesModuleResponse indicesModuleResponse = new IndicesModuleResponse(true, true, true); + return indicesModuleResponse; + } + +} diff --git a/src/main/java/org/opensearch/sdk/handlers/ExtensionsInitRequestHandler.java b/src/main/java/org/opensearch/sdk/handlers/ExtensionsInitRequestHandler.java new file mode 100644 index 00000000..bd7f7c90 --- /dev/null +++ b/src/main/java/org/opensearch/sdk/handlers/ExtensionsInitRequestHandler.java @@ -0,0 +1,55 @@ +/* + * 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.sdk.handlers; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.discovery.InitializeExtensionsRequest; +import org.opensearch.discovery.InitializeExtensionsResponse; +import org.opensearch.sdk.ExtensionsRunner; +import org.opensearch.transport.TransportService; + +/** + * This class handles the request from OpenSearch to a {@link ExtensionsRunner#startTransportService(TransportService transportService)} call. + */ + +public class ExtensionsInitRequestHandler { + private static final Logger logger = LogManager.getLogger(ExtensionsInitRequestHandler.class); + private static final String NODE_NAME_SETTING = "node.name"; + + /** + * Handles a extension request from OpenSearch. This is the first request for the transport communication and will initialize the extension and will be a part of OpenSearch bootstrap. + * + * @param extensionInitRequest The request to handle. + * @param extensionsRunner The method call from handler. + * @return A response to OpenSearch validating that this is an extension. + */ + public InitializeExtensionsResponse handleExtensionInitRequest( + InitializeExtensionsRequest extensionInitRequest, + ExtensionsRunner extensionsRunner + ) { + logger.info("Registering Extension Request received from OpenSearch"); + extensionsRunner.opensearchNode = extensionInitRequest.getSourceNode(); + extensionsRunner.setUniqueId(extensionInitRequest.getExtension().getId()); + // Successfully initialized. Send the response. + try { + return new InitializeExtensionsResponse(extensionsRunner.settings.get(NODE_NAME_SETTING)); + } finally { + // After sending successful response to initialization, send the REST API and Settings + extensionsRunner.setOpensearchNode(extensionsRunner.opensearchNode); + extensionsRunner.setExtensionNode(extensionInitRequest.getExtension()); + extensionsRunner.extensionTransportService.connectToNode(extensionsRunner.opensearchNode); + extensionsRunner.sendRegisterRestActionsRequest(extensionsRunner.extensionTransportService); + extensionsRunner.sendRegisterCustomSettingsRequest(extensionsRunner.extensionTransportService); + extensionsRunner.transportActions.sendRegisterTransportActionsRequest( + extensionsRunner.extensionTransportService, + extensionsRunner.opensearchNode + ); + } + } +} diff --git a/src/main/java/org/opensearch/sdk/handlers/ExtensionsRestRequestHandler.java b/src/main/java/org/opensearch/sdk/handlers/ExtensionsRestRequestHandler.java new file mode 100644 index 00000000..5dbe0792 --- /dev/null +++ b/src/main/java/org/opensearch/sdk/handlers/ExtensionsRestRequestHandler.java @@ -0,0 +1,63 @@ +/* + * 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.sdk.handlers; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.common.bytes.BytesReference; +import org.opensearch.extensions.rest.RestExecuteOnExtensionRequest; +import org.opensearch.extensions.rest.RestExecuteOnExtensionResponse; +import org.opensearch.rest.RestStatus; +import org.opensearch.sdk.ExtensionRestHandler; +import org.opensearch.sdk.ExtensionsRunner; +import org.opensearch.sdk.ExtensionRestPathRegistry; +import org.opensearch.sdk.ExtensionRestRequest; +import org.opensearch.sdk.ExtensionRestResponse; + +/** + * This class handles the request from OpenSearch to a {@link ExtensionsRunner#startTransportService(TransportService transportService)} call. + */ + +public class ExtensionsRestRequestHandler { + private static final Logger logger = LogManager.getLogger(ExtensionsRestRequestHandler.class); + private ExtensionRestPathRegistry extensionRestPathRegistry = new ExtensionRestPathRegistry(); + + /** + * Handles a request from OpenSearch to execute a REST request on the extension. + * + * @param request The REST request to execute. + * @return A response acknowledging the request. + */ + public RestExecuteOnExtensionResponse handleRestExecuteOnExtensionRequest(RestExecuteOnExtensionRequest request) { + + ExtensionRestHandler restHandler = extensionRestPathRegistry.getHandler(request.getMethod(), request.getUri()); + if (restHandler == null) { + return new RestExecuteOnExtensionResponse( + RestStatus.NOT_FOUND, + "No handler for " + ExtensionRestPathRegistry.restPathToString(request.getMethod(), request.getUri()) + ); + } + // ExtensionRestRequest restRequest = new ExtensionRestRequest(request); + ExtensionRestRequest restRequest = new ExtensionRestRequest( + request.getMethod(), + request.getUri(), + request.getRequestIssuerIdentity() + ); + + // Get response from extension + ExtensionRestResponse response = restHandler.handleRequest(restRequest); + logger.info("Sending extension response to OpenSearch: " + response.status()); + return new RestExecuteOnExtensionResponse( + response.status(), + response.contentType(), + BytesReference.toBytes(response.content()), + response.getHeaders() + ); + } + +} diff --git a/src/main/java/org/opensearch/sdk/handlers/OpensearchRequestHandler.java b/src/main/java/org/opensearch/sdk/handlers/OpensearchRequestHandler.java new file mode 100644 index 00000000..49cec0b4 --- /dev/null +++ b/src/main/java/org/opensearch/sdk/handlers/OpensearchRequestHandler.java @@ -0,0 +1,40 @@ +/* + * 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.sdk.handlers; + +import org.opensearch.extensions.OpenSearchRequest; +import org.opensearch.sdk.ExtensionNamedWriteableRegistry; +import org.opensearch.sdk.ExtensionsRunner; +import org.opensearch.transport.TransportResponse; + +/** + * This class handles the request from OpenSearch to a {@link ExtensionsRunner#startTransportService(TransportService transportService)} call. + */ + +public class OpensearchRequestHandler { + private ExtensionNamedWriteableRegistry namedWriteableRegistryApi = new ExtensionNamedWriteableRegistry(); + + /** + * Handles a request from OpenSearch and invokes the extension point API corresponding with the request type + * + * @param request The request to handle. + * @return A response to OpenSearch for the corresponding API + * @throws Exception if the corresponding handler for the request is not present + */ + public TransportResponse handleOpenSearchRequest(OpenSearchRequest request) throws Exception { + // Read enum + switch (request.getRequestType()) { + case REQUEST_OPENSEARCH_NAMED_WRITEABLE_REGISTRY: + return namedWriteableRegistryApi.handleNamedWriteableRegistryRequest(request); + // Add additional request handlers here + default: + throw new IllegalArgumentException("Handler not present for the provided request"); + } + } + +} diff --git a/src/test/java/org/opensearch/sdk/TestExtensionsRunner.java b/src/test/java/org/opensearch/sdk/TestExtensionsRunner.java index 66e3a7ea..54688a88 100644 --- a/src/test/java/org/opensearch/sdk/TestExtensionsRunner.java +++ b/src/test/java/org/opensearch/sdk/TestExtensionsRunner.java @@ -57,8 +57,11 @@ import org.opensearch.sdk.handlers.ClusterSettingsResponseHandler; import org.opensearch.sdk.handlers.ClusterStateResponseHandler; import org.opensearch.sdk.handlers.EnvironmentSettingsResponseHandler; +import org.opensearch.sdk.handlers.ExtensionsInitRequestHandler; +import org.opensearch.sdk.handlers.ExtensionsRestRequestHandler; import org.opensearch.sdk.handlers.LocalNodeResponseHandler; import org.opensearch.sdk.handlers.ExtensionStringResponseHandler; +import org.opensearch.sdk.handlers.OpensearchRequestHandler; import org.opensearch.test.OpenSearchTestCase; import org.opensearch.transport.Transport; import org.opensearch.transport.TransportService; @@ -67,6 +70,9 @@ public class TestExtensionsRunner extends OpenSearchTestCase { private static final String EXTENSION_NAME = "sample-extension"; + private ExtensionsInitRequestHandler extensionsInitRequestHandler = new ExtensionsInitRequestHandler(); + private OpensearchRequestHandler opensearchRequestHandler = new OpensearchRequestHandler(); + private ExtensionsRestRequestHandler extensionsRestRequestHandler = new ExtensionsRestRequestHandler(); private ExtensionsRunner extensionsRunner; private TransportService transportService; @@ -141,7 +147,10 @@ public void testHandleExtensionInitRequest() throws UnknownHostException { InitializeExtensionsRequest extensionInitRequest = new InitializeExtensionsRequest(sourceNode, extension); - InitializeExtensionsResponse response = extensionsRunner.handleExtensionInitRequest(extensionInitRequest); + InitializeExtensionsResponse response = extensionsInitRequestHandler.handleExtensionInitRequest( + extensionInitRequest, + extensionsRunner + ); // Test if name and unique ID are set assertEquals(EXTENSION_NAME, response.getName()); assertEquals("opensearch-sdk-1", extensionsRunner.getUniqueId()); @@ -153,7 +162,7 @@ public void testHandleExtensionInitRequest() throws UnknownHostException { public void testHandleOpenSearchRequest() throws Exception { OpenSearchRequest request = new OpenSearchRequest(OpenSearchRequestType.REQUEST_OPENSEARCH_NAMED_WRITEABLE_REGISTRY); - assertEquals(NamedWriteableRegistryResponse.class, extensionsRunner.handleOpenSearchRequest(request).getClass()); + assertEquals(NamedWriteableRegistryResponse.class, opensearchRequestHandler.handleOpenSearchRequest(request).getClass()); // Add additional OpenSearch request handler tests here for each default extension point } @@ -164,7 +173,7 @@ public void testHandleRestExecuteOnExtensionRequest() throws Exception { ExtensionTokenProcessor ext = new ExtensionTokenProcessor(EXTENSION_NAME); Principal userPrincipal = () -> "user1"; RestExecuteOnExtensionRequest request = new RestExecuteOnExtensionRequest(Method.GET, "/foo", ext.generateToken(userPrincipal)); - RestExecuteOnExtensionResponse response = extensionsRunner.handleRestExecuteOnExtensionRequest(request); + RestExecuteOnExtensionResponse response = extensionsRestRequestHandler.handleRestExecuteOnExtensionRequest(request); // this will fail in test environment with no registered actions assertEquals(RestStatus.NOT_FOUND, response.getStatus()); assertEquals(BytesRestResponse.TEXT_CONTENT_TYPE, response.getContentType()); diff --git a/src/test/java/org/opensearch/sdk/TestNamedWriteableRegistryAPI.java b/src/test/java/org/opensearch/sdk/TestNamedWriteableRegistryAPI.java index 5a322d15..b29211bf 100644 --- a/src/test/java/org/opensearch/sdk/TestNamedWriteableRegistryAPI.java +++ b/src/test/java/org/opensearch/sdk/TestNamedWriteableRegistryAPI.java @@ -38,7 +38,7 @@ public class TestNamedWriteableRegistryAPI extends OpenSearchTestCase { private List namedWriteables; - private NamedWriteableRegistryAPI namedWriteableRegistryAPI; + private ExtensionNamedWriteableRegistry extensionNamedWriteableRegistry; private static class Example implements NamedWriteable { public static final String INVALID_NAME = "invalid_name"; @@ -77,18 +77,18 @@ public int hashCode() { @BeforeEach public void setUp() throws Exception { this.namedWriteables = Collections.singletonList(new NamedWriteableRegistry.Entry(Example.class, Example.NAME, Example::new)); - this.namedWriteableRegistryAPI = new NamedWriteableRegistryAPI(namedWriteables); + this.extensionNamedWriteableRegistry = new ExtensionNamedWriteableRegistry(namedWriteables); } @Test public void testNamedWriteableRegistryCreation() { - assert (namedWriteableRegistryAPI.getRegistry() instanceof NamedWriteableRegistry); + assert (extensionNamedWriteableRegistry.getRegistry() instanceof NamedWriteableRegistry); } @Test public void testNamedWriteableRegistryRequest() throws UnknownHostException { OpenSearchRequest request = new OpenSearchRequest(OpenSearchRequestType.REQUEST_OPENSEARCH_NAMED_WRITEABLE_REGISTRY); - NamedWriteableRegistryResponse response = namedWriteableRegistryAPI.handleNamedWriteableRegistryRequest(request); + NamedWriteableRegistryResponse response = extensionNamedWriteableRegistry.handleNamedWriteableRegistryRequest(request); // Verify that the api processes named writeable registry entries successfully within the response assertEquals(response.getRegistry().size(), 1); @@ -112,7 +112,7 @@ public void testNamedWriteableRegistryParseRequest() throws UnknownHostException InputStream input = new ByteArrayInputStream(context); StreamInput in = new InputStreamStreamInput(input); NamedWriteableRegistryParseRequest request = new NamedWriteableRegistryParseRequest(Example.class, in); - ExtensionBooleanResponse response = namedWriteableRegistryAPI.handleNamedWriteableRegistryParseRequest(request); + ExtensionBooleanResponse response = extensionNamedWriteableRegistry.handleNamedWriteableRegistryParseRequest(request); // verify that byte array deserialization was successful assertEquals(response.getStatus(), true); @@ -136,7 +136,10 @@ public void testInvalidCategoryClass() throws UnknownHostException, IOException // Category Class ExtensionRunner is not registered NamedWriteableRegistryParseRequest request = new NamedWriteableRegistryParseRequest(ExtensionsRunner.class, in); - Exception e = expectThrows(Exception.class, () -> namedWriteableRegistryAPI.handleNamedWriteableRegistryParseRequest(request)); + Exception e = expectThrows( + Exception.class, + () -> extensionNamedWriteableRegistry.handleNamedWriteableRegistryParseRequest(request) + ); assertEquals(e.getMessage(), "Unknown NamedWriteable category [" + ExtensionsRunner.class.getName() + "]"); } @@ -157,7 +160,10 @@ public void testInvalidWriteableName() throws UnknownHostException, IOException InputStream input = new ByteArrayInputStream(context); StreamInput in = new InputStreamStreamInput(input); NamedWriteableRegistryParseRequest request = new NamedWriteableRegistryParseRequest(Example.class, in); - Exception e = expectThrows(Exception.class, () -> namedWriteableRegistryAPI.handleNamedWriteableRegistryParseRequest(request)); + Exception e = expectThrows( + Exception.class, + () -> extensionNamedWriteableRegistry.handleNamedWriteableRegistryParseRequest(request) + ); assertEquals(e.getMessage(), "Unknown NamedWriteable [" + Example.class.getName() + "][" + Example.INVALID_NAME + "]"); } }