Skip to content

Commit

Permalink
Add generic create and list into sample resource plugin
Browse files Browse the repository at this point in the history
Signed-off-by: Craig Perkins <[email protected]>
  • Loading branch information
cwperks committed Jan 2, 2025
1 parent 36620fd commit bcc9f8e
Show file tree
Hide file tree
Showing 16 changed files with 461 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@
import org.opensearch.rest.RestController;
import org.opensearch.rest.RestHandler;
import org.opensearch.script.ScriptService;
import org.opensearch.security.sample.actions.create.CreateSampleResourceAction;
import org.opensearch.security.sample.actions.create.CreateSampleResourceRestAction;
import org.opensearch.security.sample.actions.create.CreateSampleResourceTransportAction;
import org.opensearch.security.sample.actions.get.GetSampleResourceAction;
import org.opensearch.security.sample.actions.get.GetSampleResourceRestAction;
import org.opensearch.security.sample.actions.get.GetSampleResourceTransportAction;
import org.opensearch.security.sample.actions.list.ListSampleResourceAction;
import org.opensearch.security.sample.actions.list.ListSampleResourceRestAction;
import org.opensearch.security.sample.actions.list.ListSampleResourceTransportAction;
import org.opensearch.security.sample.actions.impl.create.CreateSampleResourceAction;
import org.opensearch.security.sample.actions.impl.create.CreateSampleResourceRestAction;
import org.opensearch.security.sample.actions.impl.create.CreateSampleResourceTransportAction;
import org.opensearch.security.sample.actions.impl.get.GetSampleResourceAction;
import org.opensearch.security.sample.actions.impl.get.GetSampleResourceRestAction;
import org.opensearch.security.sample.actions.impl.get.GetSampleResourceTransportAction;
import org.opensearch.security.sample.actions.impl.list.ListSampleResourceAction;
import org.opensearch.security.sample.actions.impl.list.ListSampleResourceRestAction;
import org.opensearch.security.sample.actions.impl.list.ListSampleResourceTransportAction;
import org.opensearch.security.sample.actions.update.UpdateSampleResourceAction;
import org.opensearch.security.sample.actions.update.UpdateSampleResourceRestAction;
import org.opensearch.security.sample.actions.update.UpdateSampleResourceTransportAction;
Expand Down
Original file line number Diff line number Diff line change
@@ -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.security.sample.actions.generic.create;

import java.io.IOException;

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;

/**
* Request object for CreateSampleResource transport action
*/
public class CreateResourceRequest<T extends Resource> extends ActionRequest {

private final T resource;

/**
* Default constructor
*/
public CreateResourceRequest(T resource) {
this.resource = resource;
}

public CreateResourceRequest(StreamInput in, Reader<T> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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.security.sample.actions.generic.create;

import java.io.IOException;

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;

/**
* 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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* 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.security.sample.actions.generic.create;

import java.io.IOException;

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 static org.opensearch.common.xcontent.XContentFactory.jsonBuilder;

/**
* Transport action for CreateSampleResource.
*/
public class CreateResourceTransportAction<T extends Resource> extends HandledTransportAction<
CreateResourceRequest<T>,
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<T> resourceReader
) {
super(actionName, transportService, actionFilters, (in) -> new CreateResourceRequest<T>(in, resourceReader));
this.transportService = transportService;
this.nodeClient = nodeClient;
this.resourceIndex = resourceIndex;
}

@Override
protected void doExecute(Task task, CreateResourceRequest<T> request, ActionListener<CreateResourceResponse> listener) {
try (ThreadContext.StoredContext ignore = transportService.getThreadPool().getThreadContext().stashContext()) {
CreateIndexRequest cir = new CreateIndexRequest(resourceIndex);
ActionListener<CreateIndexResponse> 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<T> request, ActionListener<CreateResourceResponse> listener) {
Resource sample = request.getResource();
try {
IndexRequest ir = nodeClient.prepareIndex(resourceIndex)
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
.setSource(sample.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS))
.request();

ActionListener<IndexResponse> irListener = ActionListener.wrap(idxResponse -> {
listener.onResponse(new CreateResourceResponse(idxResponse.getId()));
}, listener::onFailure);
nodeClient.index(ir, irListener);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -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.security.sample.actions.generic.list;

import java.io.IOException;

import org.opensearch.action.ResourceRequest;
import org.opensearch.core.common.io.stream.StreamInput;

/**
* 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);
}
}
Original file line number Diff line number Diff line change
@@ -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.security.sample.actions.generic.list;

import java.io.IOException;
import java.util.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;

/**
* Response to a ListResourceRequest
*/
public class ListResourceResponse<T extends Resource> extends ActionResponse implements ToXContentObject {
private final List<T> resources;

/**
* Default constructor
*
* @param resources The resources
*/
public ListResourceResponse(List<T> 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<T> 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;
}
}
Loading

0 comments on commit bcc9f8e

Please sign in to comment.