Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support transport action names when registering NamedRoutes #7957

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
5603475
Adds ability to register legacy action names along with route
DarshitChanpura Jun 7, 2023
8fee10c
Adds tests to cover legacy action name registration
DarshitChanpura Jun 7, 2023
8087f6a
Merge branch 'opensearch-project:main' into legacy-action-names
DarshitChanpura Jun 7, 2023
3cd35e4
Adds this PR to CHANGELOG
DarshitChanpura Jun 7, 2023
d8c3abf
Adds javadoc and addresses PR comments
DarshitChanpura Jun 7, 2023
66b3f88
Renames getter to match variable name
DarshitChanpura Jun 7, 2023
98564f9
Fix spotless errors
DarshitChanpura Jun 7, 2023
411c12a
Makes legacyActionName an optional nullable reference
DarshitChanpura Jun 7, 2023
655da5e
Unregisters action name upon route unregister call
DarshitChanpura Jun 8, 2023
31e9f5e
Adds support for mapping multiple transport action names when registe…
DarshitChanpura Jun 13, 2023
a9ab347
Updates tests
DarshitChanpura Jun 13, 2023
97f1383
Merge branch 'main' into legacy-action-names
DarshitChanpura Jun 13, 2023
6e10d89
Fixes test failures
DarshitChanpura Jun 13, 2023
becd844
Updates CHANGELOG entry
DarshitChanpura Jun 13, 2023
6444687
Enforces all new routes being registered to have a unique name associ…
DarshitChanpura Jun 14, 2023
eff42d6
Modifies existing test and adds a new test to verify correct behaviour
DarshitChanpura Jun 14, 2023
27aeccf
Adds route unique name to the log
DarshitChanpura Jun 14, 2023
041f9b6
Moves RouteHandler class to SDK
DarshitChanpura Jun 16, 2023
d7acb47
Merge branch 'main' into legacy-action-names
DarshitChanpura Jun 20, 2023
1c42675
Fixes unregister route logic
DarshitChanpura Jun 20, 2023
33e00dd
Fixes failed tests
DarshitChanpura Jun 20, 2023
320a7bc
Merge branch 'main' into legacy-action-names
DarshitChanpura Jun 21, 2023
5ecb11e
Merge remote-tracking branch 'upstream/main' into legacy-action-names
DarshitChanpura Jun 22, 2023
2f515dc
Addresses PR feedback
DarshitChanpura Jun 22, 2023
5f726d6
Merge remote-tracking branch 'upstream/main' into legacy-action-names
DarshitChanpura Jun 28, 2023
aa3bd2e
Adds deprecated and replaced named routes
DarshitChanpura Jun 28, 2023
fe81396
Adds tests for deprecated and replaced named routes
DarshitChanpura Jun 28, 2023
c750d47
Adds an interface for named routes
DarshitChanpura Jun 29, 2023
7569781
Replaces all NamedRoute instances with NamedRouteWrapper in ActionModule
DarshitChanpura Jun 29, 2023
1c0269b
Updates registration of deprecated routes to now be deprecated named …
DarshitChanpura Jun 29, 2023
6bb2d53
Merge remote-tracking branch 'upstream/main' into legacy-action-names
DarshitChanpura Jun 29, 2023
abb3fd3
Fixes broken tests
DarshitChanpura Jun 29, 2023
81f2f22
Merge remote-tracking branch 'upstream/main' into legacy-action-names
DarshitChanpura Jun 29, 2023
9d6a210
Rewrites NamedRoutes using builder pattern, and removes named route i…
DarshitChanpura Jun 29, 2023
0acbb14
Merge remote-tracking branch 'upstream/main' into legacy-action-names
DarshitChanpura Jun 29, 2023
e65a219
Adds missing javadoc to named route class
DarshitChanpura Jun 29, 2023
830fb22
Makes NamedRoute constructor public and fixes tests
DarshitChanpura Jun 30, 2023
356da3e
Makes extensions initialization route a NamedRoute
DarshitChanpura Jun 30, 2023
e752075
Makes NamedRoute builder private
DarshitChanpura Jun 30, 2023
36b2202
Adds a handler property to NamedRoute
DarshitChanpura Jun 30, 2023
3abb85e
Merge remote-tracking branch 'upstream/main' into legacy-action-names
DarshitChanpura Jun 30, 2023
9203903
Adds tests for handler property
DarshitChanpura Jun 30, 2023
238ebc0
Addresses PR feedback
DarshitChanpura Jun 30, 2023
b41aee0
Fixes CHANGELOG entry
DarshitChanpura Jun 30, 2023
804a038
Adds more NamedRoute tests
DarshitChanpura Jun 30, 2023
d6e2d08
Addresses PR feedback
DarshitChanpura Jul 4, 2023
0da4388
Merge remote-tracking branch 'upstream/main' into legacy-action-names
DarshitChanpura Jul 5, 2023
cb9ad3d
Makes build fail one not setting builder fields
DarshitChanpura Jul 5, 2023
aac062a
Addresses PR feedback
DarshitChanpura Jul 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Enable Point based optimization for custom comparators ([#8168](https://github.com/opensearch-project/OpenSearch/pull/8168))
- [Extensions] Support extension additional settings with extension REST initialization ([#8414](https://github.com/opensearch-project/OpenSearch/pull/8414))
- Adds mock implementation for TelemetryPlugin ([#7545](https://github.com/opensearch-project/OpenSearch/issues/7545))
- Support transport action names when registering NamedRoutes ([#7957](https://github.com/opensearch-project/OpenSearch/pull/7957))

### Dependencies
- Bump `com.azure:azure-storage-common` from 12.21.0 to 12.21.1 (#7566, #7814)
Expand Down Expand Up @@ -168,4 +169,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Security

[Unreleased 3.0]: https://github.com/opensearch-project/OpenSearch/compare/2.x...HEAD
[Unreleased 2.x]: https://github.com/opensearch-project/OpenSearch/compare/2.8...2.x
[Unreleased 2.x]: https://github.com/opensearch-project/OpenSearch/compare/2.8...2.x
41 changes: 26 additions & 15 deletions server/src/main/java/org/opensearch/action/ActionModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,9 @@

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;
Expand Down Expand Up @@ -1044,7 +1044,7 @@ public static class DynamicActionRegistry {

// A dynamic registry to add or remove Route / RestSendToExtensionAction pairs
// at times other than node bootstrap.
private final Map<RestHandler.Route, RestSendToExtensionAction> routeRegistry = new ConcurrentHashMap<>();
private final Map<NamedRoute, RestSendToExtensionAction> routeRegistry = new ConcurrentHashMap<>();

private final Set<String> registeredActionNames = new ConcurrentSkipListSet<>();

Expand Down Expand Up @@ -1112,41 +1112,52 @@ public boolean isActionRegistered(String actionName) {
}

/**
* Add a dynamic action to the registry.
* Adds a dynamic route to the registry.
*
* @param route The route instance to add
* @param action The corresponding instance of RestSendToExtensionAction to execute
*/
public void registerDynamicRoute(RestHandler.Route route, RestSendToExtensionAction action) {
public void registerDynamicRoute(NamedRoute route, RestSendToExtensionAction action) {
requireNonNull(route, "route is required");
requireNonNull(action, "action is required");
Optional<String> routeName = Optional.empty();
if (route instanceof NamedRoute) {
routeName = Optional.of(((NamedRoute) route).name());
if (isActionRegistered(routeName.get()) || registeredActionNames.contains(routeName.get())) {
throw new IllegalArgumentException("route [" + route + "] already registered");
}

String routeName = route.name();
requireNonNull(routeName, "route name is required");
if (isActionRegistered(routeName)) {
throw new IllegalArgumentException("route [" + route + "] already registered");
}

Set<String> actionNames = route.actionNames();
if (!Collections.disjoint(actionNames, registeredActionNames)) {
Set<String> alreadyRegistered = new HashSet<>(registeredActionNames);
alreadyRegistered.retainAll(actionNames);
String acts = String.join(", ", alreadyRegistered);
throw new IllegalArgumentException(
"action" + (alreadyRegistered.size() > 1 ? "s [" : " [") + acts + "] already registered"
);
}

if (routeRegistry.containsKey(route)) {
throw new IllegalArgumentException("route [" + route + "] already registered");
}
routeRegistry.put(route, action);
routeName.ifPresent(registeredActionNames::add);
registeredActionNames.add(routeName);
registeredActionNames.addAll(actionNames);
dbwiddis marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Remove a dynamic route from the registry.
*
* @param route The route to remove
*/
public void unregisterDynamicRoute(RestHandler.Route route) {
public void unregisterDynamicRoute(NamedRoute route) {
requireNonNull(route, "route is required");
if (routeRegistry.remove(route) == null) {
throw new IllegalArgumentException("action [" + route + "] was not registered");
}
if (route instanceof NamedRoute) {
registeredActionNames.remove(((NamedRoute) route).name());
}

registeredActionNames.remove(route.name());
dbwiddis marked this conversation as resolved.
Show resolved Hide resolved
registeredActionNames.removeAll(route.actionNames());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.opensearch.extensions.ExtensionsSettings.Extension;
import org.opensearch.rest.BaseRestHandler;
import org.opensearch.rest.BytesRestResponse;
import org.opensearch.rest.NamedRoute;
import org.opensearch.rest.RestRequest;
import org.opensearch.rest.RestStatus;
import org.opensearch.transport.ConnectTransportException;
Expand Down Expand Up @@ -54,7 +55,7 @@ public String getName() {

@Override
public List<Route> routes() {
return List.of(new Route(POST, "/_extensions/initialize"));
return List.of(new NamedRoute.Builder().method(POST).path("/_extensions/initialize").uniqueName("extensions:initialize").build());
}

public RestInitializeExtensionAction(ExtensionsManager extensionsManager) {
Expand Down Expand Up @@ -187,6 +188,5 @@ public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client
channel.sendResponse(new BytesRestResponse(RestStatus.ACCEPTED, builder));
}
};

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.concurrent.CompletableFuture;
Expand Down Expand Up @@ -90,33 +90,43 @@ public RestSendToExtensionAction(

List<Route> restActionsAsRoutes = new ArrayList<>();
for (String restAction : restActionsRequest.getRestActions()) {
Optional<String> name = Optional.empty();

// TODO Find a better way to parse these to avoid code-smells

String name;
Set<String> actionNames = new HashSet<>();
String[] parts = restAction.split(" ");
if (parts.length < 2) {
throw new IllegalArgumentException("REST action must contain at least a REST method and route");
if (parts.length < 3) {
throw new IllegalArgumentException("REST action must contain at least a REST method, a route and a unique name");
}
try {
method = RestRequest.Method.valueOf(parts[0].trim());
path = pathPrefix + parts[1].trim();
if (parts.length > 2) {
name = Optional.of(parts[2].trim());
name = parts[2].trim();

// comma-separated action names
DarshitChanpura marked this conversation as resolved.
Show resolved Hide resolved
if (parts.length > 3) {
String[] actions = parts[3].split(",");
for (String action : actions) {
String trimmed = action.trim();
if (!trimmed.isEmpty()) {
actionNames.add(trimmed);
}
}
}
} catch (IndexOutOfBoundsException | IllegalArgumentException e) {
throw new IllegalArgumentException(restAction + " does not begin with a valid REST method");
}
logger.info("Registering: " + method + " " + path);
if (name.isPresent()) {
NamedRoute nr = new NamedRoute(method, path, name.get());
restActionsAsRoutes.add(nr);
dynamicActionRegistry.registerDynamicRoute(nr, this);
} else {
Route r = new Route(method, path);
restActionsAsRoutes.add(r);
dynamicActionRegistry.registerDynamicRoute(r, this);
}
logger.info("Registering: " + method + " " + path + " " + name);

// All extension routes being registered must have a unique name associated with them
NamedRoute nr = new NamedRoute.Builder().method(method).path(path).uniqueName(name).legacyActionNames(actionNames).build();
restActionsAsRoutes.add(nr);
dynamicActionRegistry.registerDynamicRoute(nr, this);
}
this.routes = unmodifiableList(restActionsAsRoutes);

// TODO: Modify {@link NamedRoute} to support deprecated route registration
List<DeprecatedRoute> restActionsAsDeprecatedRoutes = new ArrayList<>();
// Iterate in pairs of route / deprecation message
List<String> deprecatedActions = restActionsRequest.getDeprecatedRestActions();
Expand Down

This file was deleted.

Loading