Skip to content

Commit

Permalink
Expose RestController all handlers iterator.
Browse files Browse the repository at this point in the history
Signed-off-by: dblock <[email protected]>
  • Loading branch information
dblock committed Jan 12, 2024
1 parent 5c82ab8 commit 7f5349b
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 3 deletions.
42 changes: 42 additions & 0 deletions server/src/main/java/org/opensearch/common/path/PathTrie.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Stack;
import java.util.function.BiFunction;
import java.util.function.Supplier;

Expand Down Expand Up @@ -405,4 +406,45 @@ public T next() {
}
};
}

public Iterator<T> retrieveAll() {
Stack<TrieNode> stack = new Stack<>();
stack.add(root);

return new Iterator<T>() {
@Override
public boolean hasNext() {
while (!stack.empty()) {
TrieNode node = stack.peek();

if (node.value != null) {
return true;
}

advance();
}

return false;
}

@Override
public T next() {
while (!stack.empty()) {
TrieNode node = advance();

if (node.value != null) {
return node.value;
}
}

Check warning on line 438 in server/src/main/java/org/opensearch/common/path/PathTrie.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/org/opensearch/common/path/PathTrie.java#L438

Added line #L438 was not covered by tests

throw new NoSuchElementException("called next() without validating hasNext()! no more nodes available");

Check warning on line 440 in server/src/main/java/org/opensearch/common/path/PathTrie.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/org/opensearch/common/path/PathTrie.java#L440

Added line #L440 was not covered by tests
}

private TrieNode advance() {
TrieNode node = stack.pop();
stack.addAll(node.children.values());
return node;
}
};
}
}
13 changes: 10 additions & 3 deletions server/src/main/java/org/opensearch/rest/MethodHandlers.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
*
* @opensearch.api
*/
final class MethodHandlers {
public final class MethodHandlers {

private final String path;
private final Map<RestRequest.Method, RestHandler> methodHandlers;
Expand Down Expand Up @@ -79,9 +79,16 @@ RestHandler getHandler(RestRequest.Method method) {
}

/**
* Return a set of all valid HTTP methods for the particular path
* Return a set of all valid HTTP methods for the particular path.
*/
Set<RestRequest.Method> getValidMethods() {
public Set<RestRequest.Method> getValidMethods() {
return methodHandlers.keySet();
}

/**
* Returns the relative HTTP path of the set of method handlers.
*/
public String getPath() {
return path;
}
}
8 changes: 8 additions & 0 deletions server/src/main/java/org/opensearch/rest/RestController.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,14 @@ public RestController(
);
}

/**
* Returns an iterator over registered REST method handlers.
* @return {@link Iterator} of {@link MethodHandlers}
*/
public Iterator<MethodHandlers> getAllHandlers() {
return handlers.retrieveAll();
}

/**
* Registers a REST handler to be executed when the provided {@code method} and {@code path} match the request.
*
Expand Down
31 changes: 31 additions & 0 deletions server/src/test/java/org/opensearch/common/path/PathTrieTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
import org.opensearch.rest.RestUtils;
import org.opensearch.test.OpenSearchTestCase;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import static org.hamcrest.Matchers.equalTo;
Expand Down Expand Up @@ -286,4 +288,33 @@ public void testEscapedSlashWithinUrl() {
assertThat(params.get("type"), equalTo("type"));
assertThat(params.get("id"), equalTo("id"));
}

public void testRetrieveAllEmpty() {
PathTrie<String> trie = new PathTrie<>(NO_DECODER);
Iterator<String> allPaths = trie.retrieveAll();
assertFalse(allPaths.hasNext());
}

public void testRetrieveAll() {
PathTrie<String> trie = new PathTrie<>(NO_DECODER);
trie.insert("{testA}", "test1");
trie.insert("{testA}/{testB}", "test2");
trie.insert("a/{testB}", "test3");
trie.insert("{testA}/b", "test4");
trie.insert("{testA}/b/c", "test5");

Iterator<String> iterator = trie.retrieveAll();
assertTrue(iterator.hasNext());
List<String> paths = new ArrayList<>();
iterator.forEachRemaining(paths::add);
assertEquals(paths, List.of("test1", "test4", "test5", "test2", "test3"));
assertFalse(iterator.hasNext());
}

public void testRetrieveAllWithNllValue() {
PathTrie<String> trie = new PathTrie<>(NO_DECODER);
trie.insert("{testA}", null);
Iterator<String> iterator = trie.retrieveAll();
assertFalse(iterator.hasNext());
}
}
31 changes: 31 additions & 0 deletions server/src/test/java/org/opensearch/rest/RestControllerTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,37 @@ public void teardown() throws IOException {
IOUtils.close(client);
}

public void testDefaultRestControllerGetAllHandlersContainsFavicon() {
final RestController restController = new RestController(null, null, null, circuitBreakerService, usageService, identityService);
Iterator<MethodHandlers> handlers = restController.getAllHandlers();
assertTrue(handlers.hasNext());
MethodHandlers faviconHandler = handlers.next();
assertEquals(faviconHandler.getPath(), "/favicon.ico");
assertEquals(faviconHandler.getValidMethods(), Set.of(RestRequest.Method.GET));
assertFalse(handlers.hasNext());
}

public void testRestControllerGetAllHandlers() {
final RestController restController = new RestController(null, null, null, circuitBreakerService, usageService, identityService);

restController.registerHandler(RestRequest.Method.PATCH, "/foo", mock(RestHandler.class));
restController.registerHandler(RestRequest.Method.GET, "/foo", mock(RestHandler.class));

Iterator<MethodHandlers> handlers = restController.getAllHandlers();

assertTrue(handlers.hasNext());
MethodHandlers rootHandler = handlers.next();
assertEquals(rootHandler.getPath(), "/foo");
assertEquals(rootHandler.getValidMethods(), Set.of(RestRequest.Method.GET, RestRequest.Method.PATCH));

assertTrue(handlers.hasNext());
MethodHandlers faviconHandler = handlers.next();
assertEquals(faviconHandler.getPath(), "/favicon.ico");
assertEquals(faviconHandler.getValidMethods(), Set.of(RestRequest.Method.GET));

assertFalse(handlers.hasNext());
}

public void testApplyRelevantHeaders() throws Exception {
final ThreadContext threadContext = client.threadPool().getThreadContext();
Set<RestHeaderDefinition> headers = new HashSet<>(
Expand Down

0 comments on commit 7f5349b

Please sign in to comment.