Skip to content

Commit

Permalink
Copy updated HelloWorld action to placeholder RestCreateDetectorAction
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Widdis <[email protected]>
  • Loading branch information
dbwiddis committed Oct 11, 2022
1 parent 12fb000 commit 1deb649
Showing 1 changed file with 101 additions and 22 deletions.
123 changes: 101 additions & 22 deletions src/main/java/org/opensearch/ad/rest/RestCreateDetectorAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,132 @@
import static org.opensearch.rest.RestRequest.Method.GET;
import static org.opensearch.rest.RestRequest.Method.PUT;
import static org.opensearch.rest.RestStatus.BAD_REQUEST;
import static org.opensearch.rest.RestStatus.NOT_ACCEPTABLE;
import static org.opensearch.rest.RestStatus.NOT_FOUND;
import static org.opensearch.rest.RestStatus.NOT_MODIFIED;
import static org.opensearch.rest.RestStatus.OK;

import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.opensearch.common.xcontent.XContentType;
import org.opensearch.extensions.rest.ExtensionRestRequest;
import org.opensearch.extensions.rest.ExtensionRestResponse;
import org.opensearch.rest.RestHandler.Route;
import org.opensearch.rest.RestRequest.Method;
import org.opensearch.sdk.ExtensionRestHandler;
import org.opensearch.sdk.ExtensionRestResponse;

public class RestCreateDetectorAction implements ExtensionRestHandler {

private static final String GREETING = "Hello, %s!";
private String worldName = "World";
private List<String> worldAdjectives = new ArrayList<>();
private Random rand = new Random();

@Override
public List<Route> routes() {
return List.of(new Route(GET, "/hello"), new Route(PUT, "/hello/{name}"));
}

@Override
public ExtensionRestResponse handleRequest(Method method, String uri) {
// We need to track which parameters are consumed to pass back to OpenSearch
List<String> consumedParams = new ArrayList<>();
if (Method.GET.equals(method) && "/hello".equals(uri)) {
return new ExtensionRestResponse(OK, String.format(GREETING, worldName), consumedParams);
} else if (Method.PUT.equals(method) && uri.startsWith("/hello/")) {
// Placeholder code here for parameters in named wildcard paths
// Full implementation based on params() will be implemented as part of
// https://github.com/opensearch-project/opensearch-sdk-java/issues/111
String name = uri.substring("/hello/".length());
consumedParams.add("name");
try {
worldName = URLDecoder.decode(name, StandardCharsets.UTF_8);
} catch (IllegalArgumentException e) {
return new ExtensionRestResponse(BAD_REQUEST, e.getMessage(), consumedParams);
public ExtensionRestResponse handleRequest(ExtensionRestRequest request) {
Method method = request.method();

if (Method.GET.equals(method)) {
return handleGetRequest(request);
} else if (Method.POST.equals(method)) {
return handlePostRequest(request);
} else if (Method.DELETE.equals(method)) {
return handleDeleteRequest(request);
} else if (Method.PUT.equals(method)) {
return handlePutRequest(request);
}
return handleBadRequest(request);
}

private ExtensionRestResponse handleGetRequest(ExtensionRestRequest request) {
String worldNameWithRandomAdjective = worldAdjectives.isEmpty()
? worldName
: String.join(" ", worldAdjectives.get(rand.nextInt(worldAdjectives.size())), worldName);
return new ExtensionRestResponse(request, OK, String.format(GREETING, worldNameWithRandomAdjective));
}

private ExtensionRestResponse handlePostRequest(ExtensionRestRequest request) {
if (request.hasContent()) {
String adjective = "";
XContentType contentType = request.getXContentType();
if (contentType == null) {
// Plain text
adjective = request.content().utf8ToString();
} else if (contentType.equals(XContentType.JSON)) {
adjective = parseJsonAdjective(request.content().utf8ToString());
} else {
return new ExtensionRestResponse(request, NOT_ACCEPTABLE, "Only text and JSON content types are supported");
}
if (!adjective.isBlank()) {
worldAdjectives.add(adjective);
return new ExtensionRestResponse(request, OK, "Added " + adjective + " to words that describe the world!");
}
return new ExtensionRestResponse(request, BAD_REQUEST, "No adjective included with POST request");
}
return new ExtensionRestResponse(request, BAD_REQUEST, "No content included with POST request");
}

private ExtensionRestResponse handleDeleteRequest(ExtensionRestRequest request) {
if (request.hasContent()) {
String adjective = "";
XContentType contentType = request.getXContentType();
if (contentType == null) {
// Plain text
adjective = request.content().utf8ToString();
} else if (contentType.equals(XContentType.JSON)) {
adjective = parseJsonAdjective(request.content().utf8ToString());
} else {
return new ExtensionRestResponse(request, NOT_ACCEPTABLE, "Only text and JSON content types are supported");
}
if (!adjective.isBlank()) {
if (worldAdjectives.remove(adjective)) {
return new ExtensionRestResponse(request, OK, "Goodbye, " + adjective + " world!");
}
return new ExtensionRestResponse(request, NOT_MODIFIED, "");
}
return new ExtensionRestResponse(OK, "Updated the world's name to " + worldName, consumedParams);
return new ExtensionRestResponse(request, BAD_REQUEST, "No adjective included with DELETE request");
}
return new ExtensionRestResponse(request, BAD_REQUEST, "No content included with DELETE request");
}

private ExtensionRestResponse handlePutRequest(ExtensionRestRequest request) {
String name = request.param("name");
try {
worldName = URLDecoder.decode(name, StandardCharsets.UTF_8);
} catch (IllegalArgumentException e) {
return new ExtensionRestResponse(request, BAD_REQUEST, e.getMessage());
}
return new ExtensionRestResponse(
NOT_FOUND,
"Extension REST action improperly configured to handle " + method.name() + " " + uri,
consumedParams
);
return new ExtensionRestResponse(request, OK, "Updated the world's name to " + worldName);
}

private ExtensionRestResponse handleBadRequest(ExtensionRestRequest request) {
return new ExtensionRestResponse(request, NOT_FOUND, "Extension REST action improperly configured to handle " + request.toString());
}

private String parseJsonAdjective(String json) {
// TODO: Once CreateComponents has an XContentRegistry available we can parse from there
// For now we just hack our way into the result.
boolean foundLabel = false;
boolean foundColon = false;
for (String s : json.split("\"")) {
if (!foundLabel) {
foundLabel = "adjective".equals(s);
} else if (!foundColon) {
foundColon = s.contains(":");
} else {
// This is the adjective!
return s;
}
}
return "";
}
}

0 comments on commit 1deb649

Please sign in to comment.