From ce1bf8779895bce7e62ab72ab63378e94d32a610 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Tue, 31 Dec 2024 20:50:28 -0500 Subject: [PATCH 1/8] WIP on creating extension points in core Signed-off-by: Craig Perkins --- .../main/java/org/opensearch/node/Node.java | 10 ++ .../plugins/ResourceAccessControlPlugin.java | 16 ++ .../opensearch/plugins/ResourcePlugin.java | 20 +++ .../opensearch/plugins/resource/Resource.java | 14 ++ .../plugins/resource/ResourceParser.java | 17 ++ .../plugins/resource/ResourceService.java | 60 +++++++ .../resource/ResourceSharingService.java | 17 ++ .../plugins/resource/ResourceType.java | 30 ++++ .../resource/action/ResourceRequest.java | 45 ++++++ .../action/create/CreateResourceRequest.java | 50 ++++++ .../action/create/CreateResourceResponse.java | 55 +++++++ .../create/CreateResourceTransportAction.java | 90 +++++++++++ .../action/get/GetResourceRequest.java | 38 +++++ .../action/get/GetResourceResponse.java | 56 +++++++ .../get/GetResourceTransportAction.java | 130 +++++++++++++++ .../action/list/ListResourceRequest.java | 33 ++++ .../action/list/ListResourceResponse.java | 57 +++++++ .../list/ListResourceTransportAction.java | 148 ++++++++++++++++++ .../noop/NoopResourceAccessControlPlugin.java | 21 +++ .../noop/NoopResourceSharingService.java | 32 ++++ 20 files changed, 939 insertions(+) create mode 100644 server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java create mode 100644 server/src/main/java/org/opensearch/plugins/ResourcePlugin.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/Resource.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/ResourceParser.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/ResourceService.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/ResourceType.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/ResourceRequest.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceRequest.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceResponse.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceTransportAction.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceRequest.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceResponse.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceTransportAction.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceRequest.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceResponse.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceTransportAction.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceSharingService.java diff --git a/server/src/main/java/org/opensearch/node/Node.java b/server/src/main/java/org/opensearch/node/Node.java index c78ee6711dcda..8028f64d5a98e 100644 --- a/server/src/main/java/org/opensearch/node/Node.java +++ b/server/src/main/java/org/opensearch/node/Node.java @@ -214,6 +214,8 @@ import org.opensearch.plugins.Plugin; import org.opensearch.plugins.PluginsService; import org.opensearch.plugins.RepositoryPlugin; +import org.opensearch.plugins.ResourceAccessControlPlugin; +import org.opensearch.plugins.ResourcePlugin; import org.opensearch.plugins.ScriptPlugin; import org.opensearch.plugins.SearchPipelinePlugin; import org.opensearch.plugins.SearchPlugin; @@ -222,6 +224,7 @@ import org.opensearch.plugins.TaskManagerClientPlugin; import org.opensearch.plugins.TelemetryAwarePlugin; import org.opensearch.plugins.TelemetryPlugin; +import org.opensearch.plugins.resource.ResourceService; import org.opensearch.ratelimitting.admissioncontrol.AdmissionControlService; import org.opensearch.ratelimitting.admissioncontrol.transport.AdmissionControlTransportInterceptor; import org.opensearch.repositories.RepositoriesModule; @@ -590,6 +593,13 @@ protected Node( final IdentityService identityService = new IdentityService(settings, threadPool, identityPlugins); + final List resourceAccessControlPlugins = pluginsService.filterPlugins( + ResourceAccessControlPlugin.class + ); + final List resourcePlugins = pluginsService.filterPlugins(ResourcePlugin.class); + ResourceService resourceService = new ResourceService(resourceAccessControlPlugins); + resourceService.initializeResourcePlugins(resourcePlugins); + if (FeatureFlags.isEnabled(FeatureFlags.EXTENSIONS)) { final List extensionAwarePlugins = pluginsService.filterPlugins(ExtensionAwarePlugin.class); Set> additionalSettings = new HashSet<>(); diff --git a/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java b/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java new file mode 100644 index 0000000000000..f7c0c1edae07a --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java @@ -0,0 +1,16 @@ +/* + * 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.plugins; + +import org.opensearch.plugins.resource.ResourceSharingService; +import org.opensearch.plugins.resource.ResourceType; + +public interface ResourceAccessControlPlugin { + ResourceSharingService getResourceSharingService(ResourceType resourceType); +} diff --git a/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java b/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java new file mode 100644 index 0000000000000..7a787652672e6 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java @@ -0,0 +1,20 @@ +/* + * 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.plugins; + +import org.opensearch.plugins.resource.ResourceSharingService; +import org.opensearch.plugins.resource.ResourceType; + +import java.util.List; + +public interface ResourcePlugin { + List getResourceTypes(); + + void assignResourceService(List resourceService); +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/Resource.java b/server/src/main/java/org/opensearch/plugins/resource/Resource.java new file mode 100644 index 0000000000000..7c9ad6dd4c8b6 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/Resource.java @@ -0,0 +1,14 @@ +/* + * 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.plugins.resource; + +import org.opensearch.core.common.io.stream.NamedWriteable; +import org.opensearch.core.xcontent.ToXContentObject; + +public interface Resource extends NamedWriteable, ToXContentObject {} diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceParser.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceParser.java new file mode 100644 index 0000000000000..13213ee367596 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceParser.java @@ -0,0 +1,17 @@ +/* + * 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.plugins.resource; + +import org.opensearch.core.xcontent.XContentParser; + +import java.io.IOException; + +public interface ResourceParser { + T parse(XContentParser xContentParser, String id) throws IOException; +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceService.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceService.java new file mode 100644 index 0000000000000..88339c18aae05 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceService.java @@ -0,0 +1,60 @@ +/* + * 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.plugins.resource; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.OpenSearchException; +import org.opensearch.plugins.ResourceAccessControlPlugin; +import org.opensearch.plugins.ResourcePlugin; +import org.opensearch.plugins.resource.noop.NoopResourceAccessControlPlugin; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Service to get the current ResourcePlugin to perform authorization. + * + * @opensearch.experimental + */ +public class ResourceService { + private static final Logger log = LogManager.getLogger(ResourceService.class); + + private final ResourceAccessControlPlugin resourceAccessControlPlugin; + + public ResourceService(final List resourceACPlugins) { + + if (resourceACPlugins.isEmpty()) { + log.info("Security plugin disabled: Using DefaultResourceAccessControlPlugin"); + resourceAccessControlPlugin = new NoopResourceAccessControlPlugin(); + } else if (resourceACPlugins.size() == 1) { + log.info("Security plugin enabled: Using OpenSearchSecurityPlugin"); + resourceAccessControlPlugin = resourceACPlugins.get(0); + } else { + throw new OpenSearchException( + "Multiple resource access control plugins are not supported, found: " + + resourceACPlugins.stream().map(Object::getClass).map(Class::getName).collect(Collectors.joining(",")) + ); + } + } + + public void initializeResourcePlugins(final List resourcePlugins) { + if (resourcePlugins != null) { + for (ResourcePlugin plugin : resourcePlugins) { + List sharingServices = new ArrayList<>(); + List pluginResourceTypes = plugin.getResourceTypes(); + for (ResourceType resourceType : pluginResourceTypes) { + sharingServices.add(resourceAccessControlPlugin.getResourceSharingService(resourceType)); + } + plugin.assignResourceService(sharingServices); + } + } + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java new file mode 100644 index 0000000000000..a8379bc9424c0 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java @@ -0,0 +1,17 @@ +/* + * 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.plugins.resource; + +import org.opensearch.core.action.ActionListener; + +public interface ResourceSharingService { + ResourceType getResourceType(); + + void isSharedWithCurrentRequester(String resourceId, ActionListener shareListener); +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java new file mode 100644 index 0000000000000..10658e7852a42 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java @@ -0,0 +1,30 @@ +/* + * 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.plugins.resource; + +public interface ResourceType { + /** + * Type of the resource + * @return a string containing the type of the resource + */ + String getResourceType(); + + /** + * The index where resource meta-data is stored + * @return the name of the parent index where resource meta-data is stored + */ + String getResourceIndex(); + + /** + * @return returns a parser for this resource + */ + default ResourceParser getResourceParser() { + return null; + }; +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/ResourceRequest.java b/server/src/main/java/org/opensearch/plugins/resource/action/ResourceRequest.java new file mode 100644 index 0000000000000..de359fb2b7870 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/ResourceRequest.java @@ -0,0 +1,45 @@ +/* + * 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.plugins.resource.action; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; + +import java.io.IOException; + +public class ResourceRequest extends ActionRequest { + protected final String resourceIndex; + + /** + * Default constructor + */ + public ResourceRequest(String resourceIndex) { + this.resourceIndex = resourceIndex; + } + + public ResourceRequest(StreamInput in) throws IOException { + this.resourceIndex = in.readString(); + } + + @Override + public void writeTo(final StreamOutput out) throws IOException { + out.writeString(resourceIndex); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + public String getResourceIndex() { + return this.resourceIndex; + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceRequest.java b/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceRequest.java new file mode 100644 index 0000000000000..4f992a83bd4fe --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceRequest.java @@ -0,0 +1,50 @@ +/* + * 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.plugins.resource.action.create; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.plugins.resource.Resource; + +import java.io.IOException; + +/** + * Request object for CreateSampleResource transport action + */ +public class CreateResourceRequest extends ActionRequest { + + private final T resource; + + /** + * Default constructor + */ + public CreateResourceRequest(T resource) { + this.resource = resource; + } + + public CreateResourceRequest(StreamInput in, Reader resourceReader) throws IOException { + this.resource = resourceReader.read(in); + } + + @Override + public void writeTo(final StreamOutput out) throws IOException { + resource.writeTo(out); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + public Resource getResource() { + return this.resource; + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceResponse.java b/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceResponse.java new file mode 100644 index 0000000000000..85e3be95421d9 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceResponse.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.plugins.resource.action.create; + +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; + +import java.io.IOException; + +/** + * Response to a CreateSampleResourceRequest + */ +public class CreateResourceResponse extends ActionResponse implements ToXContentObject { + private final String resourceId; + + /** + * Default constructor + * + * @param resourceId The resourceId + */ + public CreateResourceResponse(String resourceId) { + this.resourceId = resourceId; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(resourceId); + } + + /** + * Constructor with StreamInput + * + * @param in the stream input + */ + public CreateResourceResponse(final StreamInput in) throws IOException { + resourceId = in.readString(); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("resourceId", resourceId); + builder.endObject(); + return builder; + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceTransportAction.java b/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceTransportAction.java new file mode 100644 index 0000000000000..0474954efcc49 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceTransportAction.java @@ -0,0 +1,90 @@ +/* + * 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.plugins.resource.action.create; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.action.admin.indices.create.CreateIndexRequest; +import org.opensearch.action.admin.indices.create.CreateIndexResponse; +import org.opensearch.action.index.IndexRequest; +import org.opensearch.action.index.IndexResponse; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.action.support.WriteRequest; +import org.opensearch.client.Client; +import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.common.io.stream.Writeable; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.security.spi.Resource; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +import java.io.IOException; + +import static org.opensearch.common.xcontent.XContentFactory.jsonBuilder; + +/** + * Transport action for CreateSampleResource. + */ +public class CreateResourceTransportAction extends HandledTransportAction< + CreateResourceRequest, + CreateResourceResponse> { + private static final Logger log = LogManager.getLogger(CreateResourceTransportAction.class); + + private final TransportService transportService; + private final Client nodeClient; + private final String resourceIndex; + + public CreateResourceTransportAction( + TransportService transportService, + ActionFilters actionFilters, + Client nodeClient, + String actionName, + String resourceIndex, + Writeable.Reader resourceReader + ) { + super(actionName, transportService, actionFilters, (in) -> new CreateResourceRequest(in, resourceReader)); + this.transportService = transportService; + this.nodeClient = nodeClient; + this.resourceIndex = resourceIndex; + } + + @Override + protected void doExecute(Task task, CreateResourceRequest request, ActionListener listener) { + try (ThreadContext.StoredContext ignore = transportService.getThreadPool().getThreadContext().stashContext()) { + CreateIndexRequest cir = new CreateIndexRequest(resourceIndex); + ActionListener cirListener = ActionListener.wrap( + response -> { createResource(request, listener); }, + (failResponse) -> { + /* Index already exists, ignore and continue */ + createResource(request, listener); + } + ); + nodeClient.admin().indices().create(cir, cirListener); + } + } + + private void createResource(CreateResourceRequest request, ActionListener listener) { + Resource sample = request.getResource(); + try { + IndexRequest ir = nodeClient.prepareIndex(resourceIndex) + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .setSource(sample.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS)) + .request(); + + ActionListener irListener = ActionListener.wrap(idxResponse -> { + listener.onResponse(new CreateResourceResponse(idxResponse.getId())); + }, listener::onFailure); + nodeClient.index(ir, irListener); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceRequest.java b/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceRequest.java new file mode 100644 index 0000000000000..dc14694eab011 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceRequest.java @@ -0,0 +1,38 @@ +/* + * 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.plugins.resource.action.get; + +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.plugins.resource.action.ResourceRequest; + +import java.io.IOException; + +/** + * Request object for GetResource transport action + */ +public class GetResourceRequest extends ResourceRequest { + private final String resourceId; + + /** + * Default constructor + */ + public GetResourceRequest(String resourceId, String resourceIndex) { + super(resourceIndex); + this.resourceId = resourceId; + } + + public GetResourceRequest(StreamInput in) throws IOException { + super(in); + this.resourceId = in.readString(); + } + + public String getResourceId() { + return this.resourceId; + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceResponse.java b/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceResponse.java new file mode 100644 index 0000000000000..232afaf8b709a --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceResponse.java @@ -0,0 +1,56 @@ +/* + * 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.plugins.resource.action.get; + +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.plugins.resource.Resource; + +import java.io.IOException; + +/** + * Response to a GetResourceRequest + */ +public class GetResourceResponse extends ActionResponse implements ToXContentObject { + private final T resource; + + /** + * Default constructor + * + * @param resource The resource + */ + public GetResourceResponse(T resource) { + this.resource = resource; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + resource.writeTo(out); + } + + /** + * Constructor with StreamInput + * + * @param in the stream input + */ + public GetResourceResponse(final StreamInput in, Reader resourceReader) throws IOException { + resource = resourceReader.read(in); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("resource", resource); + builder.endObject(); + return builder; + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceTransportAction.java b/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceTransportAction.java new file mode 100644 index 0000000000000..899ebc6d4c4e3 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceTransportAction.java @@ -0,0 +1,130 @@ +/* + * 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.plugins.resource.action.get; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.OpenSearchException; +import org.opensearch.action.get.GetRequest; +import org.opensearch.action.get.GetResponse; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.client.Client; +import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.common.xcontent.LoggingDeprecationHandler; +import org.opensearch.common.xcontent.XContentHelper; +import org.opensearch.common.xcontent.XContentType; +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.xcontent.NamedXContentRegistry; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.plugins.resource.Resource; +import org.opensearch.plugins.resource.ResourceParser; +import org.opensearch.plugins.resource.ResourceSharingService; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +import java.io.IOException; +import java.util.Objects; + +/** + * Transport action for GetResource. + */ +public class GetResourceTransportAction extends HandledTransportAction> { + private static final Logger log = LogManager.getLogger(GetResourceTransportAction.class); + + private final ResourceSharingService resourceSharingService; + + private final ResourceParser resourceParser; + + private final String resourceIndex; + + private final Client client; + + private final NamedXContentRegistry xContentRegistry; + + public GetResourceTransportAction( + TransportService transportService, + ActionFilters actionFilters, + String actionName, + String resourceIndex, + ResourceSharingService resourceSharingService, + ResourceParser resourceParser, + Client client, + NamedXContentRegistry xContentRegistry + ) { + super(actionName, transportService, actionFilters, GetResourceRequest::new); + this.resourceSharingService = resourceSharingService; + Objects.requireNonNull(resourceParser); + this.resourceParser = resourceParser; + this.resourceIndex = resourceIndex; + this.client = client; + this.xContentRegistry = xContentRegistry; + } + + @Override + protected void doExecute(Task task, GetResourceRequest request, ActionListener> actionListener) { + getResource(request, actionListener); + } + + private void getResource(GetResourceRequest request, ActionListener> listener) { + ActionListener getResourceListener = ActionListener.wrap(resource -> { + System.out.println("resource: " + resource); + listener.onResponse(new GetResourceResponse(resource)); + }, listener::onFailure); + + try (ThreadContext.StoredContext ignore = client.threadPool().getThreadContext().stashContext()) { + GetRequest gr = new GetRequest(resourceIndex); + gr.id(request.getResourceId()); + ActionListener getListener = new ActionListener<>() { + @Override + public void onResponse(GetResponse getResponse) { + try { + XContentParser parser = XContentHelper.createParser( + xContentRegistry, + LoggingDeprecationHandler.INSTANCE, + getResponse.getSourceAsBytesRef(), + XContentType.JSON + ); + T resource = resourceParser.parse(parser, getResponse.getId()); + ActionListener shareListener = new ActionListener<>() { + @Override + public void onResponse(Boolean isShared) { + if (isShared) { + getResourceListener.onResponse(resource); + } else { + getResourceListener.onFailure( + new OpenSearchException("User is not authorized to access this resource") + ); + } + } + + @Override + public void onFailure(Exception e) { + getResourceListener.onFailure( + new OpenSearchException("Failed to check sharing status: " + e.getMessage(), e) + ); + } + }; + + resourceSharingService.isSharedWithCurrentRequester(request.getResourceId(), shareListener); + } catch (IOException e) { + throw new OpenSearchException("Caught exception while loading resources: " + e.getMessage()); + } + } + + @Override + public void onFailure(Exception e) { + throw new OpenSearchException("Caught exception while loading resources: " + e.getMessage()); + } + }; + client.get(gr, getListener); + } + // resourceSharingService.getResource(request.getResourceId(), getResourceListener); + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceRequest.java b/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceRequest.java new file mode 100644 index 0000000000000..85351f0ddc365 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceRequest.java @@ -0,0 +1,33 @@ +/* + * 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.plugins.resource.action.list; + +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.plugins.resource.action.ResourceRequest; + +import java.io.IOException; + +/** + * Request object for ListResource transport action + */ +public class ListResourceRequest extends ResourceRequest { + + // TODO Change this into Search instead of List + + /** + * Default constructor + */ + public ListResourceRequest(String resourceIndex) { + super(resourceIndex); + } + + public ListResourceRequest(StreamInput in) throws IOException { + super(in); + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceResponse.java b/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceResponse.java new file mode 100644 index 0000000000000..54fc78ed27537 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceResponse.java @@ -0,0 +1,57 @@ +/* + * 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.plugins.resource.action.list; + +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.plugins.resource.Resource; + +import java.io.IOException; +import java.util.List; + +/** + * Response to a ListResourceRequest + */ +public class ListResourceResponse extends ActionResponse implements ToXContentObject { + private final List resources; + + /** + * Default constructor + * + * @param resources The resources + */ + public ListResourceResponse(List resources) { + this.resources = resources; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeList(resources); + } + + /** + * Constructor with StreamInput + * + * @param in the stream input + */ + public ListResourceResponse(final StreamInput in, Reader resourceReader) throws IOException { + resources = in.readList(resourceReader); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("resources", resources); + builder.endObject(); + return builder; + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceTransportAction.java b/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceTransportAction.java new file mode 100644 index 0000000000000..57a4c11b1c95b --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceTransportAction.java @@ -0,0 +1,148 @@ +/* + * 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.plugins.resource.action.list; + +import org.opensearch.OpenSearchException; +import org.opensearch.action.search.SearchRequest; +import org.opensearch.action.search.SearchResponse; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.client.Client; +import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.common.xcontent.LoggingDeprecationHandler; +import org.opensearch.common.xcontent.XContentHelper; +import org.opensearch.common.xcontent.XContentType; +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.xcontent.NamedXContentRegistry; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.index.query.MatchAllQueryBuilder; +import org.opensearch.plugins.resource.Resource; +import org.opensearch.plugins.resource.ResourceParser; +import org.opensearch.plugins.resource.ResourceSharingService; +import org.opensearch.search.SearchHit; +import org.opensearch.search.builder.SearchSourceBuilder; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Transport action for ListResource. + */ +public class ListResourceTransportAction extends HandledTransportAction> { + private final ResourceSharingService resourceSharingService; + + private final ResourceParser resourceParser; + + private final Client client; + + private final String resourceIndex; + + private final NamedXContentRegistry xContentRegistry; + + public ListResourceTransportAction( + TransportService transportService, + ActionFilters actionFilters, + String actionName, + String resourceIndex, + ResourceSharingService resourceSharingService, + ResourceParser resourceParser, + Client client, + NamedXContentRegistry xContentRegistry + ) { + super(actionName, transportService, actionFilters, ListResourceRequest::new); + this.client = client; + this.resourceSharingService = resourceSharingService; + this.resourceIndex = resourceIndex; + this.xContentRegistry = xContentRegistry; + Objects.requireNonNull(resourceParser); + this.resourceParser = resourceParser; + } + + @Override + protected void doExecute(Task task, ListResourceRequest request, ActionListener> listener) { + ActionListener> listResourceListener = ActionListener.wrap(resourcesList -> { + System.out.println("resourcesList: " + resourcesList); + listener.onResponse(new ListResourceResponse<>(resourcesList)); + }, listener::onFailure); + try (ThreadContext.StoredContext ignore = client.threadPool().getThreadContext().stashContext()) { + SearchRequest sr = new SearchRequest(resourceIndex); + SearchSourceBuilder matchAllQuery = new SearchSourceBuilder(); + matchAllQuery.query(new MatchAllQueryBuilder()); + sr.source(matchAllQuery); + ActionListener searchListener = new ActionListener<>() { + @Override + public void onResponse(SearchResponse searchResponse) { + List resources = new ArrayList<>(); + + SearchHit[] hits = searchResponse.getHits().getHits(); + + if (hits.length == 0) { + listResourceListener.onResponse(resources); + return; + } + + AtomicInteger remainingChecks = new AtomicInteger(hits.length); + + for (SearchHit hit : hits) { + try { + XContentParser parser = XContentHelper.createParser( + xContentRegistry, + LoggingDeprecationHandler.INSTANCE, + hit.getSourceRef(), + XContentType.JSON + ); + T resource = resourceParser.parse(parser, hit.getId()); + + ActionListener shareListener = new ActionListener<>() { + @Override + public void onResponse(Boolean isShared) { + if (isShared) { + synchronized (resources) { + resources.add(resource); + } + } + if (remainingChecks.decrementAndGet() == 0) { + listResourceListener.onResponse(resources); + } + } + + @Override + public void onFailure(Exception e) { + listResourceListener.onFailure( + new OpenSearchException("Failed to check sharing status: " + e.getMessage(), e) + ); + } + }; + + resourceSharingService.isSharedWithCurrentRequester(hit.getId(), shareListener); + + } catch (IOException e) { + listResourceListener.onFailure( + new OpenSearchException("Caught exception while loading resources: " + e.getMessage(), e) + ); + return; + } + } + listResourceListener.onResponse(resources); + } + + @Override + public void onFailure(Exception e) { + throw new OpenSearchException("Caught exception while loading resources: " + e.getMessage()); + } + }; + client.search(sr, searchListener); + } + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java new file mode 100644 index 0000000000000..d62a26ecb4fd0 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java @@ -0,0 +1,21 @@ +/* + * 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.plugins.resource.noop; + +import org.opensearch.plugins.ResourceAccessControlPlugin; +import org.opensearch.plugins.resource.ResourceSharingService; +import org.opensearch.plugins.resource.ResourceType; + +public class NoopResourceAccessControlPlugin implements ResourceAccessControlPlugin { + + @Override + public ResourceSharingService getResourceSharingService(ResourceType resourceType) { + return new NoopResourceSharingService(resourceType); + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceSharingService.java b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceSharingService.java new file mode 100644 index 0000000000000..1e3b652ee9407 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceSharingService.java @@ -0,0 +1,32 @@ +/* + * 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.plugins.resource.noop; + +import org.opensearch.core.action.ActionListener; +import org.opensearch.plugins.resource.ResourceSharingService; +import org.opensearch.plugins.resource.ResourceType; + +public class NoopResourceSharingService implements ResourceSharingService { + + private final ResourceType resourceType; + + public NoopResourceSharingService(ResourceType resourceType) { + this.resourceType = resourceType; + } + + @Override + public void isSharedWithCurrentRequester(String resourceId, ActionListener shareListener) { + shareListener.onResponse(Boolean.TRUE); + } + + @Override + public ResourceType getResourceType() { + return resourceType; + } +} From d7ffded3d38423a8a3a6d80ec7f1ecfb63e5792a Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Tue, 31 Dec 2024 21:44:57 -0500 Subject: [PATCH 2/8] Add javadoc Signed-off-by: Craig Perkins --- .../resource => }/action/ResourceRequest.java | 7 ++++--- .../plugins/ResourceAccessControlPlugin.java | 5 +++++ .../java/org/opensearch/plugins/ResourcePlugin.java | 4 ++++ .../org/opensearch/plugins/resource/Resource.java | 4 ++++ .../opensearch/plugins/resource/ResourceParser.java | 5 +++++ .../plugins/resource/ResourceSharingService.java | 3 +++ .../opensearch/plugins/resource/ResourceType.java | 3 +++ .../action/create/CreateResourceTransportAction.java | 2 +- .../plugins/resource/action/create/package-info.java | 12 ++++++++++++ .../resource/action/get/GetResourceRequest.java | 2 +- .../plugins/resource/action/get/package-info.java | 12 ++++++++++++ .../resource/action/list/ListResourceRequest.java | 2 +- .../plugins/resource/action/list/package-info.java | 12 ++++++++++++ .../plugins/resource/action/package-info.java | 12 ++++++++++++ .../noop/NoopResourceAccessControlPlugin.java | 3 +++ .../resource/noop/NoopResourceSharingService.java | 3 +++ .../plugins/resource/noop/package-info.java | 12 ++++++++++++ .../opensearch/plugins/resource/package-info.java | 12 ++++++++++++ 18 files changed, 109 insertions(+), 6 deletions(-) rename server/src/main/java/org/opensearch/{plugins/resource => }/action/ResourceRequest.java (86%) create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/create/package-info.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/get/package-info.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/list/package-info.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/package-info.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/noop/package-info.java create mode 100644 server/src/main/java/org/opensearch/plugins/resource/package-info.java diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/ResourceRequest.java b/server/src/main/java/org/opensearch/action/ResourceRequest.java similarity index 86% rename from server/src/main/java/org/opensearch/plugins/resource/action/ResourceRequest.java rename to server/src/main/java/org/opensearch/action/ResourceRequest.java index de359fb2b7870..bc56a814d0eff 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/action/ResourceRequest.java +++ b/server/src/main/java/org/opensearch/action/ResourceRequest.java @@ -6,15 +6,16 @@ * compatible open source license. */ -package org.opensearch.plugins.resource.action; +package org.opensearch.action; -import org.opensearch.action.ActionRequest; -import org.opensearch.action.ActionRequestValidationException; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; import java.io.IOException; +/** + * Base class for all resource requests + */ public class ResourceRequest extends ActionRequest { protected final String resourceIndex; diff --git a/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java b/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java index f7c0c1edae07a..ec07e53e86f93 100644 --- a/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java +++ b/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java @@ -11,6 +11,11 @@ import org.opensearch.plugins.resource.ResourceSharingService; import org.opensearch.plugins.resource.ResourceType; +/** + * A ResourceAccessControlPlugin is responsible for assigned a resource sharing service for each + * {@link ResourceType} that is registered by a {@link ResourcePlugin}. There can only be a single + * ResourceAccessControlPlugin installed. + */ public interface ResourceAccessControlPlugin { ResourceSharingService getResourceSharingService(ResourceType resourceType); } diff --git a/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java b/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java index 7a787652672e6..3d510102c0fb8 100644 --- a/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java +++ b/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java @@ -13,6 +13,10 @@ import java.util.List; +/** + * A ResourcePlugin registers a list of {@link ResourceType}. These are resources created by the plugin + * and typically stored in a system index. Resources are provided protection by the {@link ResourceAccessControlPlugin}. + */ public interface ResourcePlugin { List getResourceTypes(); diff --git a/server/src/main/java/org/opensearch/plugins/resource/Resource.java b/server/src/main/java/org/opensearch/plugins/resource/Resource.java index 7c9ad6dd4c8b6..ad294a8e8f4a1 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/Resource.java +++ b/server/src/main/java/org/opensearch/plugins/resource/Resource.java @@ -11,4 +11,8 @@ import org.opensearch.core.common.io.stream.NamedWriteable; import org.opensearch.core.xcontent.ToXContentObject; +/** + * Interface for a generic Resource. Resources are entities created by plugins that are typically + * stored in system indices. Access Control is provided by the ResourceAccessControlPlugin. + */ public interface Resource extends NamedWriteable, ToXContentObject {} diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceParser.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceParser.java index 13213ee367596..afb82fee41975 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/ResourceParser.java +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceParser.java @@ -12,6 +12,11 @@ import java.io.IOException; +/** + * Parser for Resource + * + * @param Returns instance of a Resource + */ public interface ResourceParser { T parse(XContentParser xContentParser, String id) throws IOException; } diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java index a8379bc9424c0..bde29783bd471 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java @@ -10,6 +10,9 @@ import org.opensearch.core.action.ActionListener; +/** + * Interface for Resource Sharing Service + */ public interface ResourceSharingService { ResourceType getResourceType(); diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java index 10658e7852a42..663fe97cfdaa0 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java @@ -8,6 +8,9 @@ package org.opensearch.plugins.resource; +/** + * Interface for a resource type + */ public interface ResourceType { /** * Type of the resource diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceTransportAction.java b/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceTransportAction.java index 0474954efcc49..52778cb4bbbb9 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceTransportAction.java +++ b/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceTransportAction.java @@ -22,7 +22,7 @@ import org.opensearch.core.action.ActionListener; import org.opensearch.core.common.io.stream.Writeable; import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.security.spi.Resource; +import org.opensearch.plugins.resource.Resource; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/create/package-info.java b/server/src/main/java/org/opensearch/plugins/resource/action/create/package-info.java new file mode 100644 index 0000000000000..b7470d3317205 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/create/package-info.java @@ -0,0 +1,12 @@ +/* + * 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. + */ + +/** + * Contains generic re-usable action for creating generic resource + */ +package org.opensearch.plugins.resource.action.create; diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceRequest.java b/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceRequest.java index dc14694eab011..d2bcdd0afc2d7 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceRequest.java +++ b/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceRequest.java @@ -8,8 +8,8 @@ package org.opensearch.plugins.resource.action.get; +import org.opensearch.action.ResourceRequest; import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.plugins.resource.action.ResourceRequest; import java.io.IOException; diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/get/package-info.java b/server/src/main/java/org/opensearch/plugins/resource/action/get/package-info.java new file mode 100644 index 0000000000000..6ebad757638b6 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/get/package-info.java @@ -0,0 +1,12 @@ +/* + * 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. + */ + +/** + * Contains generic re-usable action for getting single plugin resource + */ +package org.opensearch.plugins.resource.action.get; diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceRequest.java b/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceRequest.java index 85351f0ddc365..1491e5afc49fd 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceRequest.java +++ b/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceRequest.java @@ -8,8 +8,8 @@ package org.opensearch.plugins.resource.action.list; +import org.opensearch.action.ResourceRequest; import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.plugins.resource.action.ResourceRequest; import java.io.IOException; diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/list/package-info.java b/server/src/main/java/org/opensearch/plugins/resource/action/list/package-info.java new file mode 100644 index 0000000000000..6a027854192a2 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/list/package-info.java @@ -0,0 +1,12 @@ +/* + * 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. + */ + +/** + * Contains generic re-usable action for listing plugin resources + */ +package org.opensearch.plugins.resource.action.list; diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/package-info.java b/server/src/main/java/org/opensearch/plugins/resource/action/package-info.java new file mode 100644 index 0000000000000..5e0824cca69d2 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/action/package-info.java @@ -0,0 +1,12 @@ +/* + * 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. + */ + +/** + * Contains generic re-usable actions for common operations related to plugin resources + */ +package org.opensearch.plugins.resource.action; diff --git a/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java index d62a26ecb4fd0..281e6c82a52df 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java +++ b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java @@ -12,6 +12,9 @@ import org.opensearch.plugins.resource.ResourceSharingService; import org.opensearch.plugins.resource.ResourceType; +/** + * Noop implementation of Resource Access Control Plugin + */ public class NoopResourceAccessControlPlugin implements ResourceAccessControlPlugin { @Override diff --git a/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceSharingService.java b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceSharingService.java index 1e3b652ee9407..96e2ec17ad934 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceSharingService.java +++ b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceSharingService.java @@ -12,6 +12,9 @@ import org.opensearch.plugins.resource.ResourceSharingService; import org.opensearch.plugins.resource.ResourceType; +/** + * Noop implementation of Resource Sharing Service + */ public class NoopResourceSharingService implements ResourceSharingService { private final ResourceType resourceType; diff --git a/server/src/main/java/org/opensearch/plugins/resource/noop/package-info.java b/server/src/main/java/org/opensearch/plugins/resource/noop/package-info.java new file mode 100644 index 0000000000000..26d8bf80d5ce9 --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/noop/package-info.java @@ -0,0 +1,12 @@ +/* + * 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. + */ + +/** + * Contains noop implementation of interfaces related to plugin resources + */ +package org.opensearch.plugins.resource.noop; diff --git a/server/src/main/java/org/opensearch/plugins/resource/package-info.java b/server/src/main/java/org/opensearch/plugins/resource/package-info.java new file mode 100644 index 0000000000000..25cad10e5021e --- /dev/null +++ b/server/src/main/java/org/opensearch/plugins/resource/package-info.java @@ -0,0 +1,12 @@ +/* + * 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. + */ + +/** + * Contains classes related to plugin resources + */ +package org.opensearch.plugins.resource; From 60585c3d34a43c9dc11c82533d34fedb1df2d85e Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Wed, 1 Jan 2025 10:10:58 -0500 Subject: [PATCH 3/8] Assign on the resource type level Signed-off-by: Craig Perkins --- .../opensearch/plugins/ResourceAccessControlPlugin.java | 3 +-- .../main/java/org/opensearch/plugins/ResourcePlugin.java | 3 --- .../org/opensearch/plugins/resource/ResourceService.java | 5 +---- .../plugins/resource/ResourceSharingService.java | 2 +- .../java/org/opensearch/plugins/resource/ResourceType.java | 6 ++++++ .../resource/noop/NoopResourceAccessControlPlugin.java | 5 ++--- .../plugins/resource/noop/NoopResourceSharingService.java | 7 +++---- 7 files changed, 14 insertions(+), 17 deletions(-) diff --git a/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java b/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java index ec07e53e86f93..b6b6b6301baeb 100644 --- a/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java +++ b/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java @@ -8,7 +8,6 @@ package org.opensearch.plugins; -import org.opensearch.plugins.resource.ResourceSharingService; import org.opensearch.plugins.resource.ResourceType; /** @@ -17,5 +16,5 @@ * ResourceAccessControlPlugin installed. */ public interface ResourceAccessControlPlugin { - ResourceSharingService getResourceSharingService(ResourceType resourceType); + void assignResourceSharingService(ResourceType resourceType); } diff --git a/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java b/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java index 3d510102c0fb8..6290576cc1108 100644 --- a/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java +++ b/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java @@ -8,7 +8,6 @@ package org.opensearch.plugins; -import org.opensearch.plugins.resource.ResourceSharingService; import org.opensearch.plugins.resource.ResourceType; import java.util.List; @@ -19,6 +18,4 @@ */ public interface ResourcePlugin { List getResourceTypes(); - - void assignResourceService(List resourceService); } diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceService.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceService.java index 88339c18aae05..02205422d9e5c 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/ResourceService.java +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceService.java @@ -15,7 +15,6 @@ import org.opensearch.plugins.ResourcePlugin; import org.opensearch.plugins.resource.noop.NoopResourceAccessControlPlugin; -import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -48,12 +47,10 @@ public ResourceService(final List resourceACPlugins public void initializeResourcePlugins(final List resourcePlugins) { if (resourcePlugins != null) { for (ResourcePlugin plugin : resourcePlugins) { - List sharingServices = new ArrayList<>(); List pluginResourceTypes = plugin.getResourceTypes(); for (ResourceType resourceType : pluginResourceTypes) { - sharingServices.add(resourceAccessControlPlugin.getResourceSharingService(resourceType)); + resourceAccessControlPlugin.assignResourceSharingService(resourceType); } - plugin.assignResourceService(sharingServices); } } } diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java index bde29783bd471..c7b58ca65faef 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java @@ -14,7 +14,7 @@ * Interface for Resource Sharing Service */ public interface ResourceSharingService { - ResourceType getResourceType(); + String getResourceType(); void isSharedWithCurrentRequester(String resourceId, ActionListener shareListener); } diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java index 663fe97cfdaa0..bfa22c3d91bd0 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java @@ -24,6 +24,12 @@ public interface ResourceType { */ String getResourceIndex(); + /** + * This method is called when initializing ResourcePlugins to assign an instance + * of {@link ResourceSharingService} to the resource type. + */ + void assignResourceSharingService(ResourceSharingService resourceSharingService); + /** * @return returns a parser for this resource */ diff --git a/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java index 281e6c82a52df..8eb1e2c792fc6 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java +++ b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java @@ -9,7 +9,6 @@ package org.opensearch.plugins.resource.noop; import org.opensearch.plugins.ResourceAccessControlPlugin; -import org.opensearch.plugins.resource.ResourceSharingService; import org.opensearch.plugins.resource.ResourceType; /** @@ -18,7 +17,7 @@ public class NoopResourceAccessControlPlugin implements ResourceAccessControlPlugin { @Override - public ResourceSharingService getResourceSharingService(ResourceType resourceType) { - return new NoopResourceSharingService(resourceType); + public void assignResourceSharingService(ResourceType resourceType) { + resourceType.assignResourceSharingService(new NoopResourceSharingService(resourceType.getResourceType())); } } diff --git a/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceSharingService.java b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceSharingService.java index 96e2ec17ad934..a933257b4ef07 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceSharingService.java +++ b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceSharingService.java @@ -10,16 +10,15 @@ import org.opensearch.core.action.ActionListener; import org.opensearch.plugins.resource.ResourceSharingService; -import org.opensearch.plugins.resource.ResourceType; /** * Noop implementation of Resource Sharing Service */ public class NoopResourceSharingService implements ResourceSharingService { - private final ResourceType resourceType; + private final String resourceType; - public NoopResourceSharingService(ResourceType resourceType) { + public NoopResourceSharingService(String resourceType) { this.resourceType = resourceType; } @@ -29,7 +28,7 @@ public void isSharedWithCurrentRequester(String resourceId, ActionListener Date: Wed, 1 Jan 2025 13:40:51 -0500 Subject: [PATCH 4/8] Move initialization down Signed-off-by: Craig Perkins --- server/src/main/java/org/opensearch/node/Node.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/server/src/main/java/org/opensearch/node/Node.java b/server/src/main/java/org/opensearch/node/Node.java index 8028f64d5a98e..f9a6460861b12 100644 --- a/server/src/main/java/org/opensearch/node/Node.java +++ b/server/src/main/java/org/opensearch/node/Node.java @@ -593,13 +593,6 @@ protected Node( final IdentityService identityService = new IdentityService(settings, threadPool, identityPlugins); - final List resourceAccessControlPlugins = pluginsService.filterPlugins( - ResourceAccessControlPlugin.class - ); - final List resourcePlugins = pluginsService.filterPlugins(ResourcePlugin.class); - ResourceService resourceService = new ResourceService(resourceAccessControlPlugins); - resourceService.initializeResourcePlugins(resourcePlugins); - if (FeatureFlags.isEnabled(FeatureFlags.EXTENSIONS)) { final List extensionAwarePlugins = pluginsService.filterPlugins(ExtensionAwarePlugin.class); Set> additionalSettings = new HashSet<>(); @@ -1056,6 +1049,13 @@ protected Node( List identityAwarePlugins = pluginsService.filterPlugins(IdentityAwarePlugin.class); identityService.initializeIdentityAwarePlugins(identityAwarePlugins); + final List resourceAccessControlPlugins = pluginsService.filterPlugins( + ResourceAccessControlPlugin.class + ); + final List resourcePlugins = pluginsService.filterPlugins(ResourcePlugin.class); + ResourceService resourceService = new ResourceService(resourceAccessControlPlugins); + resourceService.initializeResourcePlugins(resourcePlugins); + final QueryGroupResourceUsageTrackerService queryGroupResourceUsageTrackerService = new QueryGroupResourceUsageTrackerService( taskResourceTrackingService ); From 05a2e2eda9d9f2c643203b7a805f139841075916 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 2 Jan 2025 10:18:25 -0500 Subject: [PATCH 5/8] Only keep generic request for GET for demonstration of noop impl Signed-off-by: Craig Perkins --- .../action/create/CreateResourceRequest.java | 50 ------ .../action/create/CreateResourceResponse.java | 55 ------- .../create/CreateResourceTransportAction.java | 90 ----------- .../resource/action/create/package-info.java | 12 -- .../{ => generic}/get/GetResourceRequest.java | 2 +- .../get/GetResourceResponse.java | 2 +- .../get/GetResourceTransportAction.java | 2 +- .../{ => generic}/get/package-info.java | 2 +- .../action/list/ListResourceRequest.java | 33 ---- .../action/list/ListResourceResponse.java | 57 ------- .../list/ListResourceTransportAction.java | 148 ------------------ .../resource/action/list/package-info.java | 12 -- 12 files changed, 4 insertions(+), 461 deletions(-) delete mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceRequest.java delete mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceResponse.java delete mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceTransportAction.java delete mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/create/package-info.java rename server/src/main/java/org/opensearch/plugins/resource/action/{ => generic}/get/GetResourceRequest.java (93%) rename server/src/main/java/org/opensearch/plugins/resource/action/{ => generic}/get/GetResourceResponse.java (96%) rename server/src/main/java/org/opensearch/plugins/resource/action/{ => generic}/get/GetResourceTransportAction.java (98%) rename server/src/main/java/org/opensearch/plugins/resource/action/{ => generic}/get/package-info.java (82%) delete mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceRequest.java delete mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceResponse.java delete mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceTransportAction.java delete mode 100644 server/src/main/java/org/opensearch/plugins/resource/action/list/package-info.java diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceRequest.java b/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceRequest.java deleted file mode 100644 index 4f992a83bd4fe..0000000000000 --- a/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceRequest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.plugins.resource.action.create; - -import org.opensearch.action.ActionRequest; -import org.opensearch.action.ActionRequestValidationException; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.plugins.resource.Resource; - -import java.io.IOException; - -/** - * Request object for CreateSampleResource transport action - */ -public class CreateResourceRequest extends ActionRequest { - - private final T resource; - - /** - * Default constructor - */ - public CreateResourceRequest(T resource) { - this.resource = resource; - } - - public CreateResourceRequest(StreamInput in, Reader resourceReader) throws IOException { - this.resource = resourceReader.read(in); - } - - @Override - public void writeTo(final StreamOutput out) throws IOException { - resource.writeTo(out); - } - - @Override - public ActionRequestValidationException validate() { - return null; - } - - public Resource getResource() { - return this.resource; - } -} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceResponse.java b/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceResponse.java deleted file mode 100644 index 85e3be95421d9..0000000000000 --- a/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceResponse.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.plugins.resource.action.create; - -import org.opensearch.core.action.ActionResponse; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.xcontent.ToXContentObject; -import org.opensearch.core.xcontent.XContentBuilder; - -import java.io.IOException; - -/** - * Response to a CreateSampleResourceRequest - */ -public class CreateResourceResponse extends ActionResponse implements ToXContentObject { - private final String resourceId; - - /** - * Default constructor - * - * @param resourceId The resourceId - */ - public CreateResourceResponse(String resourceId) { - this.resourceId = resourceId; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(resourceId); - } - - /** - * Constructor with StreamInput - * - * @param in the stream input - */ - public CreateResourceResponse(final StreamInput in) throws IOException { - resourceId = in.readString(); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - builder.field("resourceId", resourceId); - builder.endObject(); - return builder; - } -} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceTransportAction.java b/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceTransportAction.java deleted file mode 100644 index 52778cb4bbbb9..0000000000000 --- a/server/src/main/java/org/opensearch/plugins/resource/action/create/CreateResourceTransportAction.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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.plugins.resource.action.create; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.opensearch.action.admin.indices.create.CreateIndexRequest; -import org.opensearch.action.admin.indices.create.CreateIndexResponse; -import org.opensearch.action.index.IndexRequest; -import org.opensearch.action.index.IndexResponse; -import org.opensearch.action.support.ActionFilters; -import org.opensearch.action.support.HandledTransportAction; -import org.opensearch.action.support.WriteRequest; -import org.opensearch.client.Client; -import org.opensearch.common.util.concurrent.ThreadContext; -import org.opensearch.core.action.ActionListener; -import org.opensearch.core.common.io.stream.Writeable; -import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.plugins.resource.Resource; -import org.opensearch.tasks.Task; -import org.opensearch.transport.TransportService; - -import java.io.IOException; - -import static org.opensearch.common.xcontent.XContentFactory.jsonBuilder; - -/** - * Transport action for CreateSampleResource. - */ -public class CreateResourceTransportAction extends HandledTransportAction< - CreateResourceRequest, - CreateResourceResponse> { - private static final Logger log = LogManager.getLogger(CreateResourceTransportAction.class); - - private final TransportService transportService; - private final Client nodeClient; - private final String resourceIndex; - - public CreateResourceTransportAction( - TransportService transportService, - ActionFilters actionFilters, - Client nodeClient, - String actionName, - String resourceIndex, - Writeable.Reader resourceReader - ) { - super(actionName, transportService, actionFilters, (in) -> new CreateResourceRequest(in, resourceReader)); - this.transportService = transportService; - this.nodeClient = nodeClient; - this.resourceIndex = resourceIndex; - } - - @Override - protected void doExecute(Task task, CreateResourceRequest request, ActionListener listener) { - try (ThreadContext.StoredContext ignore = transportService.getThreadPool().getThreadContext().stashContext()) { - CreateIndexRequest cir = new CreateIndexRequest(resourceIndex); - ActionListener cirListener = ActionListener.wrap( - response -> { createResource(request, listener); }, - (failResponse) -> { - /* Index already exists, ignore and continue */ - createResource(request, listener); - } - ); - nodeClient.admin().indices().create(cir, cirListener); - } - } - - private void createResource(CreateResourceRequest request, ActionListener listener) { - Resource sample = request.getResource(); - try { - IndexRequest ir = nodeClient.prepareIndex(resourceIndex) - .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) - .setSource(sample.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS)) - .request(); - - ActionListener irListener = ActionListener.wrap(idxResponse -> { - listener.onResponse(new CreateResourceResponse(idxResponse.getId())); - }, listener::onFailure); - nodeClient.index(ir, irListener); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/create/package-info.java b/server/src/main/java/org/opensearch/plugins/resource/action/create/package-info.java deleted file mode 100644 index b7470d3317205..0000000000000 --- a/server/src/main/java/org/opensearch/plugins/resource/action/create/package-info.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * 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. - */ - -/** - * Contains generic re-usable action for creating generic resource - */ -package org.opensearch.plugins.resource.action.create; diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceRequest.java b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceRequest.java similarity index 93% rename from server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceRequest.java rename to server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceRequest.java index d2bcdd0afc2d7..b76705f9e9d56 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceRequest.java +++ b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugins.resource.action.get; +package org.opensearch.plugins.resource.action.generic.get; import org.opensearch.action.ResourceRequest; import org.opensearch.core.common.io.stream.StreamInput; diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceResponse.java b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceResponse.java similarity index 96% rename from server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceResponse.java rename to server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceResponse.java index 232afaf8b709a..8bf790d4ce3fe 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceResponse.java +++ b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugins.resource.action.get; +package org.opensearch.plugins.resource.action.generic.get; import org.opensearch.core.action.ActionResponse; import org.opensearch.core.common.io.stream.StreamInput; diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceTransportAction.java b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceTransportAction.java similarity index 98% rename from server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceTransportAction.java rename to server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceTransportAction.java index 899ebc6d4c4e3..bc16f046f0330 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/action/get/GetResourceTransportAction.java +++ b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceTransportAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.plugins.resource.action.get; +package org.opensearch.plugins.resource.action.generic.get; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/get/package-info.java b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/package-info.java similarity index 82% rename from server/src/main/java/org/opensearch/plugins/resource/action/get/package-info.java rename to server/src/main/java/org/opensearch/plugins/resource/action/generic/get/package-info.java index 6ebad757638b6..833171061020d 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/action/get/package-info.java +++ b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/package-info.java @@ -9,4 +9,4 @@ /** * Contains generic re-usable action for getting single plugin resource */ -package org.opensearch.plugins.resource.action.get; +package org.opensearch.plugins.resource.action.generic.get; diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceRequest.java b/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceRequest.java deleted file mode 100644 index 1491e5afc49fd..0000000000000 --- a/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceRequest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.plugins.resource.action.list; - -import org.opensearch.action.ResourceRequest; -import org.opensearch.core.common.io.stream.StreamInput; - -import java.io.IOException; - -/** - * Request object for ListResource transport action - */ -public class ListResourceRequest extends ResourceRequest { - - // TODO Change this into Search instead of List - - /** - * Default constructor - */ - public ListResourceRequest(String resourceIndex) { - super(resourceIndex); - } - - public ListResourceRequest(StreamInput in) throws IOException { - super(in); - } -} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceResponse.java b/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceResponse.java deleted file mode 100644 index 54fc78ed27537..0000000000000 --- a/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceResponse.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.plugins.resource.action.list; - -import org.opensearch.core.action.ActionResponse; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.xcontent.ToXContentObject; -import org.opensearch.core.xcontent.XContentBuilder; -import org.opensearch.plugins.resource.Resource; - -import java.io.IOException; -import java.util.List; - -/** - * Response to a ListResourceRequest - */ -public class ListResourceResponse extends ActionResponse implements ToXContentObject { - private final List resources; - - /** - * Default constructor - * - * @param resources The resources - */ - public ListResourceResponse(List resources) { - this.resources = resources; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeList(resources); - } - - /** - * Constructor with StreamInput - * - * @param in the stream input - */ - public ListResourceResponse(final StreamInput in, Reader resourceReader) throws IOException { - resources = in.readList(resourceReader); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - builder.field("resources", resources); - builder.endObject(); - return builder; - } -} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceTransportAction.java b/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceTransportAction.java deleted file mode 100644 index 57a4c11b1c95b..0000000000000 --- a/server/src/main/java/org/opensearch/plugins/resource/action/list/ListResourceTransportAction.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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.plugins.resource.action.list; - -import org.opensearch.OpenSearchException; -import org.opensearch.action.search.SearchRequest; -import org.opensearch.action.search.SearchResponse; -import org.opensearch.action.support.ActionFilters; -import org.opensearch.action.support.HandledTransportAction; -import org.opensearch.client.Client; -import org.opensearch.common.util.concurrent.ThreadContext; -import org.opensearch.common.xcontent.LoggingDeprecationHandler; -import org.opensearch.common.xcontent.XContentHelper; -import org.opensearch.common.xcontent.XContentType; -import org.opensearch.core.action.ActionListener; -import org.opensearch.core.xcontent.NamedXContentRegistry; -import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.index.query.MatchAllQueryBuilder; -import org.opensearch.plugins.resource.Resource; -import org.opensearch.plugins.resource.ResourceParser; -import org.opensearch.plugins.resource.ResourceSharingService; -import org.opensearch.search.SearchHit; -import org.opensearch.search.builder.SearchSourceBuilder; -import org.opensearch.tasks.Task; -import org.opensearch.transport.TransportService; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Transport action for ListResource. - */ -public class ListResourceTransportAction extends HandledTransportAction> { - private final ResourceSharingService resourceSharingService; - - private final ResourceParser resourceParser; - - private final Client client; - - private final String resourceIndex; - - private final NamedXContentRegistry xContentRegistry; - - public ListResourceTransportAction( - TransportService transportService, - ActionFilters actionFilters, - String actionName, - String resourceIndex, - ResourceSharingService resourceSharingService, - ResourceParser resourceParser, - Client client, - NamedXContentRegistry xContentRegistry - ) { - super(actionName, transportService, actionFilters, ListResourceRequest::new); - this.client = client; - this.resourceSharingService = resourceSharingService; - this.resourceIndex = resourceIndex; - this.xContentRegistry = xContentRegistry; - Objects.requireNonNull(resourceParser); - this.resourceParser = resourceParser; - } - - @Override - protected void doExecute(Task task, ListResourceRequest request, ActionListener> listener) { - ActionListener> listResourceListener = ActionListener.wrap(resourcesList -> { - System.out.println("resourcesList: " + resourcesList); - listener.onResponse(new ListResourceResponse<>(resourcesList)); - }, listener::onFailure); - try (ThreadContext.StoredContext ignore = client.threadPool().getThreadContext().stashContext()) { - SearchRequest sr = new SearchRequest(resourceIndex); - SearchSourceBuilder matchAllQuery = new SearchSourceBuilder(); - matchAllQuery.query(new MatchAllQueryBuilder()); - sr.source(matchAllQuery); - ActionListener searchListener = new ActionListener<>() { - @Override - public void onResponse(SearchResponse searchResponse) { - List resources = new ArrayList<>(); - - SearchHit[] hits = searchResponse.getHits().getHits(); - - if (hits.length == 0) { - listResourceListener.onResponse(resources); - return; - } - - AtomicInteger remainingChecks = new AtomicInteger(hits.length); - - for (SearchHit hit : hits) { - try { - XContentParser parser = XContentHelper.createParser( - xContentRegistry, - LoggingDeprecationHandler.INSTANCE, - hit.getSourceRef(), - XContentType.JSON - ); - T resource = resourceParser.parse(parser, hit.getId()); - - ActionListener shareListener = new ActionListener<>() { - @Override - public void onResponse(Boolean isShared) { - if (isShared) { - synchronized (resources) { - resources.add(resource); - } - } - if (remainingChecks.decrementAndGet() == 0) { - listResourceListener.onResponse(resources); - } - } - - @Override - public void onFailure(Exception e) { - listResourceListener.onFailure( - new OpenSearchException("Failed to check sharing status: " + e.getMessage(), e) - ); - } - }; - - resourceSharingService.isSharedWithCurrentRequester(hit.getId(), shareListener); - - } catch (IOException e) { - listResourceListener.onFailure( - new OpenSearchException("Caught exception while loading resources: " + e.getMessage(), e) - ); - return; - } - } - listResourceListener.onResponse(resources); - } - - @Override - public void onFailure(Exception e) { - throw new OpenSearchException("Caught exception while loading resources: " + e.getMessage()); - } - }; - client.search(sr, searchListener); - } - } -} diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/list/package-info.java b/server/src/main/java/org/opensearch/plugins/resource/action/list/package-info.java deleted file mode 100644 index 6a027854192a2..0000000000000 --- a/server/src/main/java/org/opensearch/plugins/resource/action/list/package-info.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * 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. - */ - -/** - * Contains generic re-usable action for listing plugin resources - */ -package org.opensearch.plugins.resource.action.list; From 3b51cfcbdb4756dd86e0b176ff44009f4afb52e4 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 2 Jan 2025 10:55:14 -0500 Subject: [PATCH 6/8] Rename to SharableResource Signed-off-by: Craig Perkins --- .../plugins/ResourceAccessControlPlugin.java | 6 ++--- .../opensearch/plugins/ResourcePlugin.java | 6 ++--- .../plugins/resource/ResourceParser.java | 2 +- .../plugins/resource/ResourceService.java | 24 +++++++++---------- .../{Resource.java => SharableResource.java} | 17 +++++++++++-- ...rceType.java => SharableResourceType.java} | 6 ++--- .../generic/get/GetResourceResponse.java | 4 ++-- .../get/GetResourceTransportAction.java | 7 +++--- .../noop/NoopResourceAccessControlPlugin.java | 6 ++--- 9 files changed, 46 insertions(+), 32 deletions(-) rename server/src/main/java/org/opensearch/plugins/resource/{Resource.java => SharableResource.java} (55%) rename server/src/main/java/org/opensearch/plugins/resource/{ResourceType.java => SharableResourceType.java} (81%) diff --git a/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java b/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java index b6b6b6301baeb..edaa935417922 100644 --- a/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java +++ b/server/src/main/java/org/opensearch/plugins/ResourceAccessControlPlugin.java @@ -8,13 +8,13 @@ package org.opensearch.plugins; -import org.opensearch.plugins.resource.ResourceType; +import org.opensearch.plugins.resource.SharableResourceType; /** * A ResourceAccessControlPlugin is responsible for assigned a resource sharing service for each - * {@link ResourceType} that is registered by a {@link ResourcePlugin}. There can only be a single + * {@link SharableResourceType} that is registered by a {@link ResourcePlugin}. There can only be a single * ResourceAccessControlPlugin installed. */ public interface ResourceAccessControlPlugin { - void assignResourceSharingService(ResourceType resourceType); + void assignResourceSharingService(SharableResourceType resourceType); } diff --git a/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java b/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java index 6290576cc1108..ae427087e5f59 100644 --- a/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java +++ b/server/src/main/java/org/opensearch/plugins/ResourcePlugin.java @@ -8,14 +8,14 @@ package org.opensearch.plugins; -import org.opensearch.plugins.resource.ResourceType; +import org.opensearch.plugins.resource.SharableResourceType; import java.util.List; /** - * A ResourcePlugin registers a list of {@link ResourceType}. These are resources created by the plugin + * A ResourcePlugin registers a list of {@link SharableResourceType}. These are resources created by the plugin * and typically stored in a system index. Resources are provided protection by the {@link ResourceAccessControlPlugin}. */ public interface ResourcePlugin { - List getResourceTypes(); + List getResourceTypes(); } diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceParser.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceParser.java index afb82fee41975..f9fc9a6ad32ac 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/ResourceParser.java +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceParser.java @@ -17,6 +17,6 @@ * * @param Returns instance of a Resource */ -public interface ResourceParser { +public interface ResourceParser { T parse(XContentParser xContentParser, String id) throws IOException; } diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceService.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceService.java index 02205422d9e5c..5bbf61c028c84 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/ResourceService.java +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceService.java @@ -26,20 +26,20 @@ public class ResourceService { private static final Logger log = LogManager.getLogger(ResourceService.class); - private final ResourceAccessControlPlugin resourceAccessControlPlugin; + private final ResourceAccessControlPlugin controlPlugin; - public ResourceService(final List resourceACPlugins) { + public ResourceService(final List plugins) { - if (resourceACPlugins.isEmpty()) { - log.info("Security plugin disabled: Using DefaultResourceAccessControlPlugin"); - resourceAccessControlPlugin = new NoopResourceAccessControlPlugin(); - } else if (resourceACPlugins.size() == 1) { - log.info("Security plugin enabled: Using OpenSearchSecurityPlugin"); - resourceAccessControlPlugin = resourceACPlugins.get(0); + if (plugins.isEmpty()) { + log.debug("resource access control plugins size is 0. Using noop."); + controlPlugin = new NoopResourceAccessControlPlugin(); + } else if (plugins.size() == 1) { + log.debug("resource access control plugin installed."); + controlPlugin = plugins.get(0); } else { throw new OpenSearchException( "Multiple resource access control plugins are not supported, found: " - + resourceACPlugins.stream().map(Object::getClass).map(Class::getName).collect(Collectors.joining(",")) + + plugins.stream().map(Object::getClass).map(Class::getName).collect(Collectors.joining(",")) ); } } @@ -47,9 +47,9 @@ public ResourceService(final List resourceACPlugins public void initializeResourcePlugins(final List resourcePlugins) { if (resourcePlugins != null) { for (ResourcePlugin plugin : resourcePlugins) { - List pluginResourceTypes = plugin.getResourceTypes(); - for (ResourceType resourceType : pluginResourceTypes) { - resourceAccessControlPlugin.assignResourceSharingService(resourceType); + List pluginSharableResourceTypes = plugin.getResourceTypes(); + for (SharableResourceType resourceType : pluginSharableResourceTypes) { + controlPlugin.assignResourceSharingService(resourceType); } } } diff --git a/server/src/main/java/org/opensearch/plugins/resource/Resource.java b/server/src/main/java/org/opensearch/plugins/resource/SharableResource.java similarity index 55% rename from server/src/main/java/org/opensearch/plugins/resource/Resource.java rename to server/src/main/java/org/opensearch/plugins/resource/SharableResource.java index ad294a8e8f4a1..3fa63273cac65 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/Resource.java +++ b/server/src/main/java/org/opensearch/plugins/resource/SharableResource.java @@ -11,8 +11,21 @@ import org.opensearch.core.common.io.stream.NamedWriteable; import org.opensearch.core.xcontent.ToXContentObject; +import java.time.Instant; + /** - * Interface for a generic Resource. Resources are entities created by plugins that are typically + * Interface for a generic Sharable Resource. Resources are entities created by plugins that are typically * stored in system indices. Access Control is provided by the ResourceAccessControlPlugin. */ -public interface Resource extends NamedWriteable, ToXContentObject {} +public interface SharableResource extends NamedWriteable, ToXContentObject { + + /** + * @return resource name. + */ + String getName(); + + /** + * @return resource last update time. + */ + Instant getLastUpdateTime(); +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java b/server/src/main/java/org/opensearch/plugins/resource/SharableResourceType.java similarity index 81% rename from server/src/main/java/org/opensearch/plugins/resource/ResourceType.java rename to server/src/main/java/org/opensearch/plugins/resource/SharableResourceType.java index bfa22c3d91bd0..c0fc5d1955a96 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/ResourceType.java +++ b/server/src/main/java/org/opensearch/plugins/resource/SharableResourceType.java @@ -11,9 +11,9 @@ /** * Interface for a resource type */ -public interface ResourceType { +public interface SharableResourceType { /** - * Type of the resource + * Type of the resource. This must be unique across all registered resource types. * @return a string containing the type of the resource */ String getResourceType(); @@ -33,7 +33,7 @@ public interface ResourceType { /** * @return returns a parser for this resource */ - default ResourceParser getResourceParser() { + default ResourceParser getResourceParser() { return null; }; } diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceResponse.java b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceResponse.java index 8bf790d4ce3fe..31c78d76930ca 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceResponse.java +++ b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceResponse.java @@ -13,14 +13,14 @@ import org.opensearch.core.common.io.stream.StreamOutput; import org.opensearch.core.xcontent.ToXContentObject; import org.opensearch.core.xcontent.XContentBuilder; -import org.opensearch.plugins.resource.Resource; +import org.opensearch.plugins.resource.SharableResource; import java.io.IOException; /** * Response to a GetResourceRequest */ -public class GetResourceResponse extends ActionResponse implements ToXContentObject { +public class GetResourceResponse extends ActionResponse implements ToXContentObject { private final T resource; /** diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceTransportAction.java b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceTransportAction.java index bc16f046f0330..b68c7a6ff4497 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceTransportAction.java +++ b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceTransportAction.java @@ -23,9 +23,9 @@ import org.opensearch.core.action.ActionListener; import org.opensearch.core.xcontent.NamedXContentRegistry; import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.plugins.resource.Resource; import org.opensearch.plugins.resource.ResourceParser; import org.opensearch.plugins.resource.ResourceSharingService; +import org.opensearch.plugins.resource.SharableResource; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; @@ -35,7 +35,9 @@ /** * Transport action for GetResource. */ -public class GetResourceTransportAction extends HandledTransportAction> { +public class GetResourceTransportAction extends HandledTransportAction< + GetResourceRequest, + GetResourceResponse> { private static final Logger log = LogManager.getLogger(GetResourceTransportAction.class); private final ResourceSharingService resourceSharingService; @@ -74,7 +76,6 @@ protected void doExecute(Task task, GetResourceRequest request, ActionListener> listener) { ActionListener getResourceListener = ActionListener.wrap(resource -> { - System.out.println("resource: " + resource); listener.onResponse(new GetResourceResponse(resource)); }, listener::onFailure); diff --git a/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java index 8eb1e2c792fc6..b5eb0143610df 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java +++ b/server/src/main/java/org/opensearch/plugins/resource/noop/NoopResourceAccessControlPlugin.java @@ -9,7 +9,7 @@ package org.opensearch.plugins.resource.noop; import org.opensearch.plugins.ResourceAccessControlPlugin; -import org.opensearch.plugins.resource.ResourceType; +import org.opensearch.plugins.resource.SharableResourceType; /** * Noop implementation of Resource Access Control Plugin @@ -17,7 +17,7 @@ public class NoopResourceAccessControlPlugin implements ResourceAccessControlPlugin { @Override - public void assignResourceSharingService(ResourceType resourceType) { - resourceType.assignResourceSharingService(new NoopResourceSharingService(resourceType.getResourceType())); + public void assignResourceSharingService(SharableResourceType sharableResourceType) { + sharableResourceType.assignResourceSharingService(new NoopResourceSharingService(sharableResourceType.getResourceType())); } } From 1474d19f8dfe0dbc981dc66e4628b81dd501e06e Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 2 Jan 2025 11:12:34 -0500 Subject: [PATCH 7/8] Update javadoc Signed-off-by: Craig Perkins --- .../plugins/resource/ResourceSharingService.java | 13 +++++++++++++ .../generic/get/GetResourceTransportAction.java | 8 ++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java b/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java index c7b58ca65faef..a92624f65af99 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java +++ b/server/src/main/java/org/opensearch/plugins/resource/ResourceSharingService.java @@ -14,7 +14,20 @@ * Interface for Resource Sharing Service */ public interface ResourceSharingService { + + /** + * Returns the resource type this service is responsible for. + * + * @return The resource type. Will match {@link SharableResourceType#getResourceType()} for the respective + * sharable resource type + */ String getResourceType(); + /** + * Checks if the resource is shared with the current requester. + * + * @param resourceId The resource id + * @param shareListener The listener to be called when the check is complete + */ void isSharedWithCurrentRequester(String resourceId, ActionListener shareListener); } diff --git a/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceTransportAction.java b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceTransportAction.java index b68c7a6ff4497..45e744d761f90 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceTransportAction.java +++ b/server/src/main/java/org/opensearch/plugins/resource/action/generic/get/GetResourceTransportAction.java @@ -75,9 +75,10 @@ protected void doExecute(Task task, GetResourceRequest request, ActionListener> listener) { - ActionListener getResourceListener = ActionListener.wrap(resource -> { - listener.onResponse(new GetResourceResponse(resource)); - }, listener::onFailure); + ActionListener getResourceListener = ActionListener.wrap( + resource -> { listener.onResponse(new GetResourceResponse(resource)); }, + listener::onFailure + ); try (ThreadContext.StoredContext ignore = client.threadPool().getThreadContext().stashContext()) { GetRequest gr = new GetRequest(resourceIndex); @@ -126,6 +127,5 @@ public void onFailure(Exception e) { }; client.get(gr, getListener); } - // resourceSharingService.getResource(request.getResourceId(), getResourceListener); } } From 6a5238b3fb1ce926d96b4361983256262b9d0469 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 2 Jan 2025 16:31:57 -0500 Subject: [PATCH 8/8] WIP on SampleResourcePluginIT Signed-off-by: Craig Perkins --- .../resource/SampleResourcePluginIT.java | 11 +++ .../resource/sample/SampleResource.java | 68 ++++++++++++++ .../resource/sample/SampleResourceParser.java | 52 +++++++++++ .../resource/sample/SampleResourcePlugin.java | 74 +++++++++++++++ .../resource/sample/SampleResourceType.java | 45 ++++++++++ .../create/CreateSampleResourceAction.java | 29 ++++++ .../create/CreateSampleResourceRequest.java | 51 +++++++++++ .../create/CreateSampleResourceResponse.java | 55 ++++++++++++ .../CreateSampleResourceRestAction.java | 56 ++++++++++++ .../CreateSampleResourceTransportAction.java | 89 +++++++++++++++++++ .../action/get/GetSampleResourceAction.java | 31 +++++++ .../get/GetSampleResourceRestAction.java | 50 +++++++++++ .../get/GetSampleResourceTransportAction.java | 49 ++++++++++ .../resource/SharableResourceType.java | 4 +- 14 files changed, 662 insertions(+), 2 deletions(-) create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/SampleResourcePluginIT.java create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResource.java create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResourceParser.java create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResourcePlugin.java create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResourceType.java create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceAction.java create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceRequest.java create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceResponse.java create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceRestAction.java create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceTransportAction.java create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/get/GetSampleResourceAction.java create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/get/GetSampleResourceRestAction.java create mode 100644 server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/get/GetSampleResourceTransportAction.java diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/SampleResourcePluginIT.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/SampleResourcePluginIT.java new file mode 100644 index 0000000000000..2eb30b2d3d2cd --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/SampleResourcePluginIT.java @@ -0,0 +1,11 @@ +/* + * 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.plugins.resource; + +public class SampleResourcePluginIT {} diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResource.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResource.java new file mode 100644 index 0000000000000..25c03fd1c1878 --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResource.java @@ -0,0 +1,68 @@ +/* + * 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.plugins.resource.sample; + +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.plugins.resource.SharableResource; + +import java.io.IOException; +import java.time.Instant; + +public class SampleResource implements SharableResource { + + private String name; + private Instant lastUpdateTime; + + public SampleResource() { + Instant now = Instant.now(); + this.lastUpdateTime = now; + } + + public SampleResource(StreamInput in) throws IOException { + this.name = in.readString(); + this.lastUpdateTime = in.readInstant(); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + return builder.startObject().field("name", name).endObject(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(name); + out.writeInstant(lastUpdateTime); + + } + + @Override + public String getWriteableName() { + return "sample_resource"; + } + + @Override + public String getName() { + return name; + } + + @Override + public Instant getLastUpdateTime() { + return lastUpdateTime; + } + + public void setName(String name) { + this.name = name; + } + + public void setLastUpdateTime(Instant lastUpdateTime) { + this.lastUpdateTime = lastUpdateTime; + } +} diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResourceParser.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResourceParser.java new file mode 100644 index 0000000000000..d674aacd97103 --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResourceParser.java @@ -0,0 +1,52 @@ +/* + * 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.plugins.resource.sample; + +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.core.xcontent.XContentParserUtils; +import org.opensearch.plugins.resource.ResourceParser; + +import java.io.IOException; +import java.time.Instant; + +public class SampleResourceParser implements ResourceParser { + + @Override + public SampleResource parse(XContentParser parser, String id) throws IOException { + SampleResource resource = new SampleResource(); + XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser); + + while (!parser.nextToken().equals(XContentParser.Token.END_OBJECT)) { + String fieldName = parser.currentName(); + parser.nextToken(); + switch (fieldName) { + case "name": + resource.setName(parser.text()); + break; + case "last_update_time": + resource.setLastUpdateTime(parseInstantValue(parser)); + break; + default: + XContentParserUtils.throwUnknownToken(parser.currentToken(), parser.getTokenLocation()); + } + } + return resource; + } + + private Instant parseInstantValue(XContentParser parser) throws IOException { + if (XContentParser.Token.VALUE_NULL.equals(parser.currentToken())) { + return null; + } + if (parser.currentToken().isValue()) { + return Instant.ofEpochMilli(parser.longValue()); + } + XContentParserUtils.throwUnknownToken(parser.currentToken(), parser.getTokenLocation()); + return null; + } +} diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResourcePlugin.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResourcePlugin.java new file mode 100644 index 0000000000000..1f7cb3b183e35 --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResourcePlugin.java @@ -0,0 +1,74 @@ +/* + * 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.plugins.resource.sample; + +import org.opensearch.action.ActionRequest; +import org.opensearch.cluster.metadata.IndexNameExpressionResolver; +import org.opensearch.cluster.node.DiscoveryNodes; +import org.opensearch.common.settings.ClusterSettings; +import org.opensearch.common.settings.IndexScopedSettings; +import org.opensearch.common.settings.Settings; +import org.opensearch.common.settings.SettingsFilter; +import org.opensearch.core.action.ActionResponse; +import org.opensearch.indices.SystemIndexDescriptor; +import org.opensearch.plugins.ActionPlugin; +import org.opensearch.plugins.Plugin; +import org.opensearch.plugins.ResourcePlugin; +import org.opensearch.plugins.SystemIndexPlugin; +import org.opensearch.plugins.resource.SharableResourceType; +import org.opensearch.plugins.resource.sample.action.create.CreateSampleResourceAction; +import org.opensearch.plugins.resource.sample.action.create.CreateSampleResourceRestAction; +import org.opensearch.plugins.resource.sample.action.create.CreateSampleResourceTransportAction; +import org.opensearch.plugins.resource.sample.action.get.GetSampleResourceAction; +import org.opensearch.plugins.resource.sample.action.get.GetSampleResourceRestAction; +import org.opensearch.plugins.resource.sample.action.get.GetSampleResourceTransportAction; +import org.opensearch.rest.RestController; +import org.opensearch.rest.RestHandler; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.function.Supplier; + +public class SampleResourcePlugin extends Plugin implements ResourcePlugin, SystemIndexPlugin, ActionPlugin { + + public static final String RESOURCE_INDEX_NAME = ".sample_resources"; + + @Override + public List getRestHandlers( + Settings settings, + RestController restController, + ClusterSettings clusterSettings, + IndexScopedSettings indexScopedSettings, + SettingsFilter settingsFilter, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier nodesInCluster + ) { + return List.of(new CreateSampleResourceRestAction(), new GetSampleResourceRestAction()); + } + + @Override + public List> getActions() { + return List.of( + new ActionHandler<>(CreateSampleResourceAction.INSTANCE, CreateSampleResourceTransportAction.class), + new ActionHandler<>(GetSampleResourceAction.INSTANCE, GetSampleResourceTransportAction.class) + ); + } + + @Override + public Collection getSystemIndexDescriptors(Settings settings) { + final SystemIndexDescriptor systemIndexDescriptor = new SystemIndexDescriptor(RESOURCE_INDEX_NAME, "Example index with resources"); + return Collections.singletonList(systemIndexDescriptor); + } + + @Override + public List getResourceTypes() { + return List.of(SampleResourceType.getInstance()); + } +} diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResourceType.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResourceType.java new file mode 100644 index 0000000000000..d67dd825974d1 --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/SampleResourceType.java @@ -0,0 +1,45 @@ +/* + * 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.plugins.resource.sample; + +import org.opensearch.plugins.resource.ResourceSharingService; +import org.opensearch.plugins.resource.SharableResourceType; + +import static org.opensearch.plugins.resource.sample.SampleResourcePlugin.RESOURCE_INDEX_NAME; + +public class SampleResourceType implements SharableResourceType { + private volatile ResourceSharingService resourceSharingService; + + private static final SampleResourceType INSTANCE = new SampleResourceType(); + + private SampleResourceType() {} + + public static SampleResourceType getInstance() { + return INSTANCE; + } + + @Override + public String getResourceType() { + return "sample_resource"; + } + + @Override + public String getResourceIndex() { + return RESOURCE_INDEX_NAME; + } + + @Override + public void assignResourceSharingService(ResourceSharingService resourceSharingService) { + this.resourceSharingService = resourceSharingService; + } + + public ResourceSharingService getResourceSharingService() { + return this.resourceSharingService; + } +} diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceAction.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceAction.java new file mode 100644 index 0000000000000..2384719bee159 --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceAction.java @@ -0,0 +1,29 @@ +/* + * 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.plugins.resource.sample.action.create; + +import org.opensearch.action.ActionType; + +/** + * Action to create a sample resource + */ +public class CreateSampleResourceAction extends ActionType { + /** + * Create sample resource action instance + */ + public static final CreateSampleResourceAction INSTANCE = new CreateSampleResourceAction(); + /** + * Create sample resource action name + */ + public static final String NAME = "cluster:admin/sampleresource/create"; + + private CreateSampleResourceAction() { + super(NAME, CreateSampleResourceResponse::new); + } +} diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceRequest.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceRequest.java new file mode 100644 index 0000000000000..33390a973eebc --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceRequest.java @@ -0,0 +1,51 @@ +/* + * 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.plugins.resource.sample.action.create; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.plugins.resource.SharableResource; +import org.opensearch.plugins.resource.sample.SampleResource; + +import java.io.IOException; + +/** + * Request object for CreateSampleResource transport action + */ +public class CreateSampleResourceRequest extends ActionRequest { + + private final SampleResource resource; + + /** + * Default constructor + */ + public CreateSampleResourceRequest(SampleResource resource) { + this.resource = resource; + } + + public CreateSampleResourceRequest(StreamInput in, Reader resourceReader) throws IOException { + this.resource = resourceReader.read(in); + } + + @Override + public void writeTo(final StreamOutput out) throws IOException { + resource.writeTo(out); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + public SharableResource getResource() { + return this.resource; + } +} diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceResponse.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceResponse.java new file mode 100644 index 0000000000000..ffc6d0e4dd73b --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceResponse.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.plugins.resource.sample.action.create; + +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; + +import java.io.IOException; + +/** + * Response to a CreateSampleResourceRequest + */ +public class CreateSampleResourceResponse extends ActionResponse implements ToXContentObject { + private final String resourceId; + + /** + * Default constructor + * + * @param resourceId The resourceId + */ + public CreateSampleResourceResponse(String resourceId) { + this.resourceId = resourceId; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(resourceId); + } + + /** + * Constructor with StreamInput + * + * @param in the stream input + */ + public CreateSampleResourceResponse(final StreamInput in) throws IOException { + resourceId = in.readString(); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("resourceId", resourceId); + builder.endObject(); + return builder; + } +} diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceRestAction.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceRestAction.java new file mode 100644 index 0000000000000..b0242e8eaf459 --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceRestAction.java @@ -0,0 +1,56 @@ +/* + * 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.plugins.resource.sample.action.create; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.plugins.resource.sample.SampleResource; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.action.RestToXContentListener; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import static java.util.Collections.singletonList; +import static org.opensearch.rest.RestRequest.Method.POST; + +public class CreateSampleResourceRestAction extends BaseRestHandler { + + public CreateSampleResourceRestAction() {} + + @Override + public List routes() { + return singletonList(new Route(POST, "/_plugins/resource_sharing_example/resource")); + } + + @Override + public String getName() { + return "create_sample_resource"; + } + + @Override + public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + Map source; + try (XContentParser parser = request.contentParser()) { + source = parser.map(); + } + + String name = (String) source.get("name"); + SampleResource resource = new SampleResource(); + resource.setName(name); + final CreateSampleResourceRequest createSampleResourceRequest = new CreateSampleResourceRequest<>(resource); + return channel -> client.executeLocally( + CreateSampleResourceAction.INSTANCE, + createSampleResourceRequest, + new RestToXContentListener<>(channel) + ); + } +} diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceTransportAction.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceTransportAction.java new file mode 100644 index 0000000000000..634ac087b826e --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/create/CreateSampleResourceTransportAction.java @@ -0,0 +1,89 @@ +/* + * 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.plugins.resource.sample.action.create; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.action.admin.indices.create.CreateIndexRequest; +import org.opensearch.action.admin.indices.create.CreateIndexResponse; +import org.opensearch.action.index.IndexRequest; +import org.opensearch.action.index.IndexResponse; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.action.support.WriteRequest; +import org.opensearch.client.Client; +import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.common.io.stream.Writeable; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.plugins.resource.SharableResource; +import org.opensearch.plugins.resource.sample.SampleResource; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +import java.io.IOException; + +import static org.opensearch.common.xcontent.XContentFactory.jsonBuilder; + +/** + * Transport action for CreateSampleResource. + */ +public class CreateSampleResourceTransportAction extends HandledTransportAction { + private static final Logger log = LogManager.getLogger(CreateSampleResourceTransportAction.class); + + private final TransportService transportService; + private final Client nodeClient; + private final String resourceIndex; + + public CreateSampleResourceTransportAction( + TransportService transportService, + ActionFilters actionFilters, + Client nodeClient, + String actionName, + String resourceIndex, + Writeable.Reader resourceReader + ) { + super(actionName, transportService, actionFilters, (in) -> new CreateSampleResourceRequest(in, resourceReader)); + this.transportService = transportService; + this.nodeClient = nodeClient; + this.resourceIndex = resourceIndex; + } + + @Override + protected void doExecute(Task task, CreateSampleResourceRequest request, ActionListener listener) { + try (ThreadContext.StoredContext ignore = transportService.getThreadPool().getThreadContext().stashContext()) { + CreateIndexRequest cir = new CreateIndexRequest(resourceIndex); + ActionListener cirListener = ActionListener.wrap( + response -> { createResource(request, listener); }, + (failResponse) -> { + /* Index already exists, ignore and continue */ + createResource(request, listener); + } + ); + nodeClient.admin().indices().create(cir, cirListener); + } + } + + private void createResource(CreateSampleResourceRequest request, ActionListener listener) { + SharableResource sample = request.getResource(); + try { + IndexRequest ir = nodeClient.prepareIndex(resourceIndex) + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .setSource(sample.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS)) + .request(); + + ActionListener irListener = ActionListener.wrap(idxResponse -> { + listener.onResponse(new CreateSampleResourceResponse(idxResponse.getId())); + }, listener::onFailure); + nodeClient.index(ir, irListener); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/get/GetSampleResourceAction.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/get/GetSampleResourceAction.java new file mode 100644 index 0000000000000..082e6c18f6c54 --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/get/GetSampleResourceAction.java @@ -0,0 +1,31 @@ +/* + * 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.plugins.resource.sample.action.get; + +import org.opensearch.action.ActionType; +import org.opensearch.plugins.resource.action.generic.get.GetResourceResponse; +import org.opensearch.plugins.resource.sample.SampleResource; + +/** + * Action to get a sample resource + */ +public class GetSampleResourceAction extends ActionType> { + /** + * Get sample resource action instance + */ + public static final GetSampleResourceAction INSTANCE = new GetSampleResourceAction(); + /** + * Get sample resource action name + */ + public static final String NAME = "cluster:admin/sampleresource/get"; + + private GetSampleResourceAction() { + super(NAME, in -> new GetResourceResponse<>(in, SampleResource::new)); + } +} diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/get/GetSampleResourceRestAction.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/get/GetSampleResourceRestAction.java new file mode 100644 index 0000000000000..714f65453e325 --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/get/GetSampleResourceRestAction.java @@ -0,0 +1,50 @@ +/* + * 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.plugins.resource.sample.action.get; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.plugins.resource.action.generic.get.GetResourceRequest; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.action.RestToXContentListener; + +import java.io.IOException; +import java.util.List; + +import static java.util.Collections.singletonList; +import static org.opensearch.plugins.resource.sample.SampleResourcePlugin.RESOURCE_INDEX_NAME; +import static org.opensearch.rest.RestRequest.Method.GET; + +public class GetSampleResourceRestAction extends BaseRestHandler { + + public GetSampleResourceRestAction() {} + + @Override + public List routes() { + return singletonList(new Route(GET, "/_plugins/resource_sharing_example/resource/{id}")); + } + + @Override + public String getName() { + return "get_sample_resource"; + } + + @SuppressWarnings("unchecked") + @Override + public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + String resourceId = request.param("id"); + + final GetResourceRequest getSampleResourceRequest = new GetResourceRequest(resourceId, RESOURCE_INDEX_NAME); + return channel -> client.executeLocally( + GetSampleResourceAction.INSTANCE, + getSampleResourceRequest, + new RestToXContentListener<>(channel) + ); + } +} diff --git a/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/get/GetSampleResourceTransportAction.java b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/get/GetSampleResourceTransportAction.java new file mode 100644 index 0000000000000..0fee37c044b05 --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/plugins/resource/sample/action/get/GetSampleResourceTransportAction.java @@ -0,0 +1,49 @@ +/* + * 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.plugins.resource.sample.action.get; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.client.Client; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.xcontent.NamedXContentRegistry; +import org.opensearch.plugins.resource.action.generic.get.GetResourceTransportAction; +import org.opensearch.plugins.resource.sample.SampleResource; +import org.opensearch.plugins.resource.sample.SampleResourceParser; +import org.opensearch.plugins.resource.sample.SampleResourceType; +import org.opensearch.transport.TransportService; + +import static org.opensearch.plugins.resource.sample.SampleResourcePlugin.RESOURCE_INDEX_NAME; + +/** + * Transport action for GetSampleResource. + */ +public class GetSampleResourceTransportAction extends GetResourceTransportAction { + private static final Logger log = LogManager.getLogger(GetSampleResourceTransportAction.class); + + @Inject + public GetSampleResourceTransportAction( + TransportService transportService, + ActionFilters actionFilters, + Client client, + NamedXContentRegistry xContentRegistry + ) { + super( + transportService, + actionFilters, + GetSampleResourceAction.NAME, + RESOURCE_INDEX_NAME, + SampleResourceType.getInstance().getResourceSharingService(), + new SampleResourceParser(), + client, + xContentRegistry + ); + } +} diff --git a/server/src/main/java/org/opensearch/plugins/resource/SharableResourceType.java b/server/src/main/java/org/opensearch/plugins/resource/SharableResourceType.java index c0fc5d1955a96..bd024983761b0 100644 --- a/server/src/main/java/org/opensearch/plugins/resource/SharableResourceType.java +++ b/server/src/main/java/org/opensearch/plugins/resource/SharableResourceType.java @@ -19,8 +19,8 @@ public interface SharableResourceType { String getResourceType(); /** - * The index where resource meta-data is stored - * @return the name of the parent index where resource meta-data is stored + * The index where resource metadata is stored + * @return the name of the index where resource metadata is stored */ String getResourceIndex();