Skip to content

Commit

Permalink
Adds update sample request flow
Browse files Browse the repository at this point in the history
Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
  • Loading branch information
DarshitChanpura committed Jan 17, 2025
1 parent fe05392 commit b5f2961
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@
import org.opensearch.rest.RestHandler;
import org.opensearch.sample.resource.actions.rest.create.CreateResourceAction;
import org.opensearch.sample.resource.actions.rest.create.CreateResourceRestAction;
import org.opensearch.sample.resource.actions.rest.create.UpdateResourceAction;
import org.opensearch.sample.resource.actions.rest.delete.DeleteResourceAction;
import org.opensearch.sample.resource.actions.rest.delete.DeleteResourceRestAction;
import org.opensearch.sample.resource.actions.transport.CreateResourceTransportAction;
import org.opensearch.sample.resource.actions.transport.DeleteResourceTransportAction;
import org.opensearch.sample.resource.actions.transport.UpdateResourceTransportAction;
import org.opensearch.script.ScriptService;
import org.opensearch.security.spi.resources.ResourceParser;
import org.opensearch.security.spi.resources.ResourceSharingExtension;
Expand Down Expand Up @@ -94,6 +96,7 @@ public List<RestHandler> getRestHandlers(
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
return List.of(
new ActionHandler<>(CreateResourceAction.INSTANCE, CreateResourceTransportAction.class),
new ActionHandler<>(UpdateResourceAction.INSTANCE, UpdateResourceTransportAction.class),
new ActionHandler<>(DeleteResourceAction.INSTANCE, DeleteResourceTransportAction.class)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public CreateResourceRestAction() {}
public List<Route> routes() {
return List.of(
new Route(PUT, "/_plugins/sample_resource_sharing/create"),
new Route(POST, "/_plugins/sample_resource_sharing/update")
new Route(POST, "/_plugins/sample_resource_sharing/update/{resourceId}")
);
}

Expand All @@ -46,6 +46,33 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli
source = parser.map();
}

switch (request.method()) {
case PUT:
return createResource(source, client);
case POST:
return updateResource(source, request.param("resourceId"), client);
default:
throw new IllegalArgumentException("Illegal method: " + request.method());
}
}

private RestChannelConsumer updateResource(Map<String, Object> source, String resourceId, NodeClient client) throws IOException {
String name = (String) source.get("name");
String description = source.containsKey("description") ? (String) source.get("description") : null;
Map<String, String> attributes = source.containsKey("attributes") ? (Map<String, String>) source.get("attributes") : null;
SampleResource resource = new SampleResource();
resource.setName(name);
resource.setDescription(description);
resource.setAttributes(attributes);
final UpdateResourceRequest updateResourceRequest = new UpdateResourceRequest(resourceId, resource);
return channel -> client.executeLocally(
UpdateResourceAction.INSTANCE,
updateResourceRequest,
new RestToXContentListener<>(channel)
);
}

private RestChannelConsumer createResource(Map<String, Object> source, NodeClient client) throws IOException {
String name = (String) source.get("name");
String description = source.containsKey("description") ? (String) source.get("description") : null;
Map<String, String> attributes = source.containsKey("attributes") ? (Map<String, String>) source.get("attributes") : null;
Expand Down
Original file line number Diff line number Diff line change
@@ -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.sample.resource.actions.rest.create;

import org.opensearch.action.ActionType;

/**
* Action to update a sample resource
*/
public class UpdateResourceAction extends ActionType<CreateResourceResponse> {
/**
* Create sample resource action instance
*/
public static final UpdateResourceAction INSTANCE = new UpdateResourceAction();
/**
* Create sample resource action name
*/
public static final String NAME = "cluster:admin/sample-resource-plugin/update";

private UpdateResourceAction() {
super(NAME, CreateResourceResponse::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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.sample.resource.actions.rest.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.security.spi.resources.Resource;

/**
* Request object for UpdateResource transport action
*/
public class UpdateResourceRequest extends ActionRequest {

private final String resourceId;
private final Resource resource;

/**
* Default constructor
*/
public UpdateResourceRequest(String resourceId, Resource resource) {
this.resourceId = resourceId;
this.resource = resource;
}

public UpdateResourceRequest(StreamInput in) throws IOException {
this.resourceId = in.readString();
this.resource = in.readNamedWriteable(Resource.class);
}

@Override
public void writeTo(final StreamOutput out) throws IOException {
out.writeString(resourceId);
resource.writeTo(out);
}

@Override
public ActionRequestValidationException validate() {
return null;
}

public Resource getResource() {
return this.resource;
}

public String getResourceId() {
return this.resourceId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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.sample.resource.actions.transport;

import java.io.IOException;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import org.opensearch.action.support.ActionFilters;
import org.opensearch.action.support.HandledTransportAction;
import org.opensearch.action.support.WriteRequest;
import org.opensearch.action.update.UpdateRequest;
import org.opensearch.client.Client;
import org.opensearch.common.inject.Inject;
import org.opensearch.common.util.concurrent.ThreadContext;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.xcontent.ToXContent;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.sample.resource.actions.rest.create.*;
import org.opensearch.security.spi.resources.Resource;
import org.opensearch.tasks.Task;
import org.opensearch.transport.TransportService;

import static org.opensearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.opensearch.sample.utils.Constants.RESOURCE_INDEX_NAME;

public class UpdateResourceTransportAction extends HandledTransportAction<UpdateResourceRequest, CreateResourceResponse> {
private static final Logger log = LogManager.getLogger(UpdateResourceTransportAction.class);

private final TransportService transportService;
private final Client nodeClient;

@Inject
public UpdateResourceTransportAction(TransportService transportService, ActionFilters actionFilters, Client nodeClient) {
super(UpdateResourceAction.NAME, transportService, actionFilters, UpdateResourceRequest::new);
this.transportService = transportService;
this.nodeClient = nodeClient;
}

@Override
protected void doExecute(Task task, UpdateResourceRequest request, ActionListener<CreateResourceResponse> listener) {
ThreadContext threadContext = transportService.getThreadPool().getThreadContext();
try (ThreadContext.StoredContext ignore = threadContext.stashContext()) {
updateResource(request, listener);
listener.onResponse(
new CreateResourceResponse("Resource " + request.getResource().getResourceName() + " updated successfully.")
);
} catch (Exception e) {
log.info("Failed to update resource: {}", request.getResourceId(), e);
listener.onFailure(e);
}
}

private void updateResource(UpdateResourceRequest request, ActionListener<CreateResourceResponse> listener) {
String resourceId = request.getResourceId();
Resource sample = request.getResource();
try (XContentBuilder builder = jsonBuilder()) {
UpdateRequest ur = new UpdateRequest(RESOURCE_INDEX_NAME, resourceId).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
.doc(sample.toXContent(builder, ToXContent.EMPTY_PARAMS));

log.info("Update Request: {}", ur.toString());

nodeClient.update(
ur,
ActionListener.wrap(updateResponse -> { log.info("Updated resource: {}", updateResponse.toString()); }, listener::onFailure)
);
} catch (IOException e) {
listener.onFailure(new RuntimeException(e));
}

}
}

0 comments on commit b5f2961

Please sign in to comment.