-
Notifications
You must be signed in to change notification settings - Fork 24.9k
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
RestHandlers declare handled routes #51950
Conversation
This commit changes how RestHandlers are registered with the RestController so that a RestHandler no longer needs to register itself with the RestController. Instead the RestHandler interface has new methods which when called provide information about the method and path combinations that are handled by the handler including any deprecated and/or replaced combinations. This change also makes the publication of RestHandlers safe since they no longer publish a reference to themselves within their constructors. Closes elastic#51622
Pinging @elastic/es-core-infra (:Core/Infra/REST API) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a comment.
return Collections.unmodifiableMap(MapBuilder.<String, List<Method>>newMapBuilder() | ||
.put("/_noop_bulk", unmodifiableList(asList(POST, PUT))) | ||
.put("/{index}/_noop_bulk", unmodifiableList(asList(POST, PUT))) | ||
.map()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or:
diff --git a/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java b/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java
index d6c0ef736e3..b0d17af1846 100644
--- a/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java
+++ b/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java
@@ -27,7 +27,6 @@ import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.node.NodeClient;
-import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.rest.BaseRestHandler;
@@ -39,12 +38,9 @@ import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.action.RestBuilderListener;
import java.io.IOException;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
-import static java.util.Arrays.asList;
-import static java.util.Collections.unmodifiableList;
import static org.elasticsearch.rest.RestRequest.Method.POST;
import static org.elasticsearch.rest.RestRequest.Method.PUT;
import static org.elasticsearch.rest.RestStatus.OK;
@@ -53,10 +49,9 @@ public class RestNoopBulkAction extends BaseRestHandler {
@Override
public Map<String, List<Method>> handledMethodsAndPaths() {
- return Collections.unmodifiableMap(MapBuilder.<String, List<Method>>newMapBuilder()
- .put("/_noop_bulk", unmodifiableList(asList(POST, PUT)))
- .put("/{index}/_noop_bulk", unmodifiableList(asList(POST, PUT)))
- .map());
+ return Map.of(
+ "/_noop_bulk", List.of(POST, PUT),
+ "/{index}/_noop_bulk", List.of(POST, PUT));
}
@Override
I had been working to remove uses of MapBuilder
in master, in light of the new JDK APIs for map construction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I wonder if we should take this farther, and instead of using a simple datatype we formalize the notion of a route and make that part of the API:
diff --git a/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java b/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java
index d6c0ef736e3..1e70bc9f15b 100644
--- a/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java
+++ b/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java
@@ -27,7 +27,6 @@ import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.node.NodeClient;
-import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.rest.BaseRestHandler;
@@ -37,14 +36,12 @@ import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestRequest.Method;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.action.RestBuilderListener;
+import org.elasticsearch.rest.action.Route;
import java.io.IOException;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
-import static java.util.Arrays.asList;
-import static java.util.Collections.unmodifiableList;
import static org.elasticsearch.rest.RestRequest.Method.POST;
import static org.elasticsearch.rest.RestRequest.Method.PUT;
import static org.elasticsearch.rest.RestStatus.OK;
@@ -52,11 +49,10 @@ import static org.elasticsearch.rest.RestStatus.OK;
public class RestNoopBulkAction extends BaseRestHandler {
@Override
- public Map<String, List<Method>> handledMethodsAndPaths() {
- return Collections.unmodifiableMap(MapBuilder.<String, List<Method>>newMapBuilder()
- .put("/_noop_bulk", unmodifiableList(asList(POST, PUT)))
- .put("/{index}/_noop_bulk", unmodifiableList(asList(POST, PUT)))
- .map());
+ public List<Route> handledMethodsAndPaths() {
+ return List.of(
+ new Route("/_noop_bulk", List.of(POST, PUT)),
+ new Route("/{index}/_noop_bulk", List.of(POST, PUT)));
}
@Override
diff --git a/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java b/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java
index 26ba8aa27fb..66d65b0b70e 100644
--- a/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java
+++ b/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java
@@ -28,6 +28,7 @@ import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.rest.RestRequest.Method;
+import org.elasticsearch.rest.action.Route;
import org.elasticsearch.rest.action.admin.cluster.RestNodesUsageAction;
import java.io.IOException;
@@ -74,7 +75,7 @@ public abstract class BaseRestHandler implements RestHandler {
* {@inheritDoc}
*/
@Override
- public abstract Map<String, List<Method>> handledMethodsAndPaths();
+ public abstract List<Route> handledMethodsAndPaths();
@Override
public final void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws Exception {
diff --git a/server/src/main/java/org/elasticsearch/rest/RestController.java b/server/src/main/java/org/elasticsearch/rest/RestController.java
index 239f89c5c20..9bf52ced99d 100644
--- a/server/src/main/java/org/elasticsearch/rest/RestController.java
+++ b/server/src/main/java/org/elasticsearch/rest/RestController.java
@@ -160,8 +160,8 @@ public class RestController implements HttpServerTransport.Dispatcher {
* and {@code path} combinations.
*/
public void registerHandler(RestHandler restHandler) {
- restHandler.handledMethodsAndPaths().forEach((path, methods) ->
- methods.forEach(method -> registerHandler(method, path, restHandler)));
+ restHandler.handledMethodsAndPaths().forEach(route ->
+ route.methods().forEach(method -> registerHandler(method, route.path(), restHandler)));
restHandler.deprecatedHandledMethodsAndPaths().forEach(api -> api.getMethods().forEach(method ->
registerAsDeprecatedHandler(method, api.getPath(), restHandler, api.getDeprecationMessage(), api.getLogger())));
restHandler.replacedMethodsAndPaths().forEach(api -> registerWithDeprecatedHandler(api.getMethod(), api.getPath(), restHandler,
diff --git a/server/src/main/java/org/elasticsearch/rest/RestHandler.java b/server/src/main/java/org/elasticsearch/rest/RestHandler.java
index 5f0862ed80e..6504656ee3c 100644
--- a/server/src/main/java/org/elasticsearch/rest/RestHandler.java
+++ b/server/src/main/java/org/elasticsearch/rest/RestHandler.java
@@ -23,6 +23,7 @@ import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.rest.RestRequest.Method;
+import org.elasticsearch.rest.action.Route;
import java.util.Collections;
import java.util.List;
@@ -69,8 +70,8 @@ public interface RestHandler {
/**
* The map of {@code path} to {@code methods} that this RestHandler is responsible for handling.
*/
- default Map<String, List<Method>> handledMethodsAndPaths() {
- return Collections.emptyMap();
+ default List<Route> handledMethodsAndPaths() {
+ return List.of();
}
/**
diff --git a/server/src/main/java/org/elasticsearch/rest/action/Route.java b/server/src/main/java/org/elasticsearch/rest/action/Route.java
index d42b4fb851a..05e38fdce74 100644
--- a/server/src/main/java/org/elasticsearch/rest/action/Route.java
+++ b/server/src/main/java/org/elasticsearch/rest/action/Route.java
@@ -1,4 +1,26 @@
package org.elasticsearch.rest.action;
+import org.elasticsearch.rest.RestRequest;
+
+import java.util.List;
+
public class Route {
+
+ private final String path;
+
+ public String path() {
+ return path;
+ }
+
+ private List<RestRequest.Method> methods;
+
+ public List<RestRequest.Method> methods() {
+ return methods;
+ }
+
+ public Route(final String path, final List<RestRequest.Method> methods) {
+ this.path = path;
+ this.methods = methods;
+ }
+
}
This is close to what you have done with deprecated routes, but I think we should take it the whole way and cover all routes. Then a DeprecatedRoute
is a Route
with some additional fields, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left one other thought.
return Collections.unmodifiableMap(MapBuilder.<String, List<Method>>newMapBuilder() | ||
.put("/_noop_bulk", unmodifiableList(asList(POST, PUT))) | ||
.put("/{index}/_noop_bulk", unmodifiableList(asList(POST, PUT))) | ||
.map()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I wonder if we should take this farther, and instead of using a simple datatype we formalize the notion of a route and make that part of the API:
diff --git a/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java b/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java
index d6c0ef736e3..1e70bc9f15b 100644
--- a/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java
+++ b/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java
@@ -27,7 +27,6 @@ import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.node.NodeClient;
-import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.rest.BaseRestHandler;
@@ -37,14 +36,12 @@ import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestRequest.Method;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.action.RestBuilderListener;
+import org.elasticsearch.rest.action.Route;
import java.io.IOException;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
-import static java.util.Arrays.asList;
-import static java.util.Collections.unmodifiableList;
import static org.elasticsearch.rest.RestRequest.Method.POST;
import static org.elasticsearch.rest.RestRequest.Method.PUT;
import static org.elasticsearch.rest.RestStatus.OK;
@@ -52,11 +49,10 @@ import static org.elasticsearch.rest.RestStatus.OK;
public class RestNoopBulkAction extends BaseRestHandler {
@Override
- public Map<String, List<Method>> handledMethodsAndPaths() {
- return Collections.unmodifiableMap(MapBuilder.<String, List<Method>>newMapBuilder()
- .put("/_noop_bulk", unmodifiableList(asList(POST, PUT)))
- .put("/{index}/_noop_bulk", unmodifiableList(asList(POST, PUT)))
- .map());
+ public List<Route> handledMethodsAndPaths() {
+ return List.of(
+ new Route("/_noop_bulk", List.of(POST, PUT)),
+ new Route("/{index}/_noop_bulk", List.of(POST, PUT)));
}
@Override
diff --git a/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java b/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java
index 26ba8aa27fb..66d65b0b70e 100644
--- a/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java
+++ b/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java
@@ -28,6 +28,7 @@ import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.rest.RestRequest.Method;
+import org.elasticsearch.rest.action.Route;
import org.elasticsearch.rest.action.admin.cluster.RestNodesUsageAction;
import java.io.IOException;
@@ -74,7 +75,7 @@ public abstract class BaseRestHandler implements RestHandler {
* {@inheritDoc}
*/
@Override
- public abstract Map<String, List<Method>> handledMethodsAndPaths();
+ public abstract List<Route> handledMethodsAndPaths();
@Override
public final void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws Exception {
diff --git a/server/src/main/java/org/elasticsearch/rest/RestController.java b/server/src/main/java/org/elasticsearch/rest/RestController.java
index 239f89c5c20..9bf52ced99d 100644
--- a/server/src/main/java/org/elasticsearch/rest/RestController.java
+++ b/server/src/main/java/org/elasticsearch/rest/RestController.java
@@ -160,8 +160,8 @@ public class RestController implements HttpServerTransport.Dispatcher {
* and {@code path} combinations.
*/
public void registerHandler(RestHandler restHandler) {
- restHandler.handledMethodsAndPaths().forEach((path, methods) ->
- methods.forEach(method -> registerHandler(method, path, restHandler)));
+ restHandler.handledMethodsAndPaths().forEach(route ->
+ route.methods().forEach(method -> registerHandler(method, route.path(), restHandler)));
restHandler.deprecatedHandledMethodsAndPaths().forEach(api -> api.getMethods().forEach(method ->
registerAsDeprecatedHandler(method, api.getPath(), restHandler, api.getDeprecationMessage(), api.getLogger())));
restHandler.replacedMethodsAndPaths().forEach(api -> registerWithDeprecatedHandler(api.getMethod(), api.getPath(), restHandler,
diff --git a/server/src/main/java/org/elasticsearch/rest/RestHandler.java b/server/src/main/java/org/elasticsearch/rest/RestHandler.java
index 5f0862ed80e..6504656ee3c 100644
--- a/server/src/main/java/org/elasticsearch/rest/RestHandler.java
+++ b/server/src/main/java/org/elasticsearch/rest/RestHandler.java
@@ -23,6 +23,7 @@ import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.rest.RestRequest.Method;
+import org.elasticsearch.rest.action.Route;
import java.util.Collections;
import java.util.List;
@@ -69,8 +70,8 @@ public interface RestHandler {
/**
* The map of {@code path} to {@code methods} that this RestHandler is responsible for handling.
*/
- default Map<String, List<Method>> handledMethodsAndPaths() {
- return Collections.emptyMap();
+ default List<Route> handledMethodsAndPaths() {
+ return List.of();
}
/**
diff --git a/server/src/main/java/org/elasticsearch/rest/action/Route.java b/server/src/main/java/org/elasticsearch/rest/action/Route.java
index d42b4fb851a..05e38fdce74 100644
--- a/server/src/main/java/org/elasticsearch/rest/action/Route.java
+++ b/server/src/main/java/org/elasticsearch/rest/action/Route.java
@@ -1,4 +1,26 @@
package org.elasticsearch.rest.action;
+import org.elasticsearch.rest.RestRequest;
+
+import java.util.List;
+
public class Route {
+
+ private final String path;
+
+ public String path() {
+ return path;
+ }
+
+ private List<RestRequest.Method> methods;
+
+ public List<RestRequest.Method> methods() {
+ return methods;
+ }
+
+ public Route(final String path, final List<RestRequest.Method> methods) {
+ this.path = path;
+ this.methods = methods;
+ }
+
}
This is close to what you have done with deprecated routes, but I think we should take it the whole way and cover all routes. Then a DeprecatedRoute
is a Route
with some additional fields, etc.
I was trying to make this easier to backport to 7.x by not using
I agree and thank you for the reminder of the name |
I'm fine either way, for example using the collection convenience methods here, and changing them before backporting, whichever you prefer.
Perfect, thanks. |
Given the name Route, I do wonder whether having a list of methods still makes sense. My current inclination is that a |
That sounds better to me @jaymode. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are brave to do this all in one pr!
controller.registerHandler(POST, "/{index}/_noop_bulk", this); | ||
controller.registerHandler(PUT, "/{index}/_noop_bulk", this); | ||
@Override | ||
public List<Route> handledRoutes() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handlesRoutes?
Any chance you could reverse the order of the args on the routes ctor? In my mind the method comes first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On further thought, I lean more towards routes
rather than handledRoutes
or handlesRoutes
. What do you think?
I agree regarding the parameter ordering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DEPRECATED_ENDPOINT, deprecationLogger); | ||
@Override | ||
public List<DeprecatedRoute> deprecatedRoutes() { | ||
return singletonList( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't looked deeply but I wonder if we need both a separate method and a separate class for deprecated routes. Could you return Deprecated routes in the handledRoutes method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at that briefly and decided against doing so to avoid instanceOf
checks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this is better, it's merely a suggestion for how we could do something like this:
diff --git a/server/src/main/java/org/elasticsearch/rest/RestController.java b/server/src/main/java/org/elasticsearch/rest/RestController.java
index 6a16007465c..90763fd1336 100644
--- a/server/src/main/java/org/elasticsearch/rest/RestController.java
+++ b/server/src/main/java/org/elasticsearch/rest/RestController.java
@@ -48,6 +48,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
@@ -62,6 +63,7 @@ import static org.elasticsearch.rest.RestStatus.OK;
public class RestController implements HttpServerTransport.Dispatcher {
private static final Logger logger = LogManager.getLogger(RestController.class);
+ private static final DeprecationLogger deprecationLogger = new DeprecationLogger(logger);
private final PathTrie<MethodHandlers> handlers = new PathTrie<>(RestUtils.REST_DECODER);
@@ -130,11 +132,7 @@ public class RestController implements HttpServerTransport.Dispatcher {
*/
protected void registerWithDeprecatedHandler(RestRequest.Method method, String path, RestHandler handler,
RestRequest.Method deprecatedMethod, String deprecatedPath,
- DeprecationLogger logger) {
- // e.g., [POST /_optimize] is deprecated! Use [POST /_forcemerge] instead.
- final String deprecationMessage =
- "[" + deprecatedMethod.name() + " " + deprecatedPath + "] is deprecated! Use [" + method.name() + " " + path + "] instead.";
-
+ String deprecationMessage, DeprecationLogger logger) {
registerHandler(method, path, handler);
registerAsDeprecatedHandler(deprecatedMethod, deprecatedPath, handler, deprecationMessage, logger);
}
@@ -160,11 +158,12 @@ public class RestController implements HttpServerTransport.Dispatcher {
* and {@code path} combinations.
*/
public void registerHandler(final RestHandler restHandler) {
- restHandler.routes().forEach(route -> registerHandler(route.getMethod(), route.getPath(), restHandler));
- restHandler.deprecatedRoutes().forEach(route ->
- registerAsDeprecatedHandler(route.getMethod(), route.getPath(), restHandler, route.getDeprecationMessage(), route.getLogger()));
- restHandler.replacedRoutes().forEach(route -> registerWithDeprecatedHandler(route.getMethod(), route.getPath(),
- restHandler, route.getDeprecatedMethod(), route.getDeprecatedPath(), route.getLogger()));
+ final List<RestHandler.Route> routes = restHandler.routes();
+ routes.stream().filter(Predicate.not(RestHandler.Route::isDeprecated)).forEach(route -> registerHandler(route.getMethod(), route.getPath(), restHandler));
+ routes.stream().filter(RestHandler.Route::isDeprecated).forEach(route ->
+ registerAsDeprecatedHandler(route.getMethod(), route.getPath(), restHandler, route.deprecationMessage(), deprecationLogger));
+ routes.stream().filter(RestHandler.Route::isReplacement).forEach(route -> registerWithDeprecatedHandler(route.getMethod(), route.getPath(),
+ restHandler, route.replacedRoute().getMethod(), route.replacedRoute().getPath(), route.replacedRoute().deprecationMessage(), deprecationLogger));
}
@Override
diff --git a/server/src/main/java/org/elasticsearch/rest/RestHandler.java b/server/src/main/java/org/elasticsearch/rest/RestHandler.java
index ab7b468f757..9638933053d 100644
--- a/server/src/main/java/org/elasticsearch/rest/RestHandler.java
+++ b/server/src/main/java/org/elasticsearch/rest/RestHandler.java
@@ -20,7 +20,6 @@
package org.elasticsearch.rest;
import org.elasticsearch.client.node.NodeClient;
-import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.rest.RestRequest.Method;
@@ -72,32 +71,30 @@ public interface RestHandler {
return Collections.emptyList();
}
- /**
- * A list of routes handled by this RestHandler that are deprecated and do not have a direct
- * replacement. If changing the {@code path} or {@code method} of a route,
- * use {@link #replacedRoutes()}.
- */
- default List<DeprecatedRoute> deprecatedRoutes() {
- return Collections.emptyList();
- }
-
- /**
- * A list of routes handled by this RestHandler that have had their {@code path} and/or
- * {@code method} changed. The pre-existing {@code route} will be registered
- * as deprecated alongside the updated {@code route}.
- */
- default List<ReplacedRoute> replacedRoutes() {
- return Collections.emptyList();
- }
-
class Route {
private final String path;
private final Method method;
+ private final DeprecationInfo deprecationInfo;
+ private final ReplacementInfo replacementInfo;
public Route(Method method, String path) {
+ this(method, path, DeprecationInfo.NON_DEPRECATED_ROUTE, ReplacementInfo.NONE);
+ }
+
+ public Route(Method method, String path, Method deprecatedMethod, String deprecatedPath) {
+ this(
+ method,
+ path,
+ DeprecationInfo.NON_DEPRECATED_ROUTE,
+ ReplacementInfo.replacedRoute(new Route(deprecatedMethod, deprecatedPath, DeprecationInfo.deprecatedRoute("[" + deprecatedMethod.name() + " " + deprecatedPath + "] is deprecated! Use [" + method.name() + " " + path + "] instead."), ReplacementInfo.NONE)));
+ }
+
+ private Route(Method method, String path, DeprecationInfo deprecationInfo, ReplacementInfo replacementInfo) {
this.path = path;
this.method = method;
+ this.deprecationInfo = deprecationInfo;
+ this.replacementInfo = replacementInfo;
}
public String getPath() {
@@ -107,58 +104,88 @@ public interface RestHandler {
public Method getMethod() {
return method;
}
+
+ public boolean isDeprecated() {
+ return deprecationInfo.isDeprecated();
+ }
+
+ public String deprecationMessage() {
+ return deprecationInfo.deprecationMessage();
+ }
+
+ public boolean isReplacement() {
+ return replacementInfo.isReplacement();
+ }
+
+ public Route replacedRoute() {
+ return replacementInfo.replacedRoute();
+ }
+
}
- /**
- * Represents an API that has been deprecated and is slated for removal.
- */
- class DeprecatedRoute extends Route {
+ class DeprecationInfo {
+ private final boolean isDeprecated;
private final String deprecationMessage;
- private final DeprecationLogger logger;
- public DeprecatedRoute(Method method, String path, String deprecationMessage, DeprecationLogger logger) {
- super(method, path);
+ public static final DeprecationInfo NON_DEPRECATED_ROUTE = new DeprecationInfo(false, null);
+
+ public static DeprecationInfo deprecatedRoute(String deprecationMessage) {
+ return new DeprecationInfo(true, deprecationMessage);
+ }
+
+ private DeprecationInfo(boolean isDeprecated, String deprecationMessage) {
+ assert (isDeprecated && deprecationMessage != null) || (isDeprecated == false && deprecationMessage == null);
+ this.isDeprecated = isDeprecated;
this.deprecationMessage = deprecationMessage;
- this.logger = logger;
}
- public String getDeprecationMessage() {
- return deprecationMessage;
+ public boolean isDeprecated() {
+ return isDeprecated;
}
- public DeprecationLogger getLogger() {
- return logger;
+ public String deprecationMessage() {
+ if (isDeprecated) {
+ return deprecationMessage;
+ } else {
+ throw new IllegalStateException();
+ }
}
+
}
- /**
- * Represents an API that has had its {@code path} or {@code method} changed. Holds both the
- * new and previous {@code path} and {@code method} combination.
- */
- class ReplacedRoute extends Route {
+ class ReplacementInfo {
+
+ private final boolean isReplacement;
+ private final Route replacedRoute;
- private final String deprecatedPath;
- private final Method deprecatedMethod;
- private final DeprecationLogger logger;
+ public static final ReplacementInfo NONE = new ReplacementInfo(false, null);
- public ReplacedRoute(Method method, String path, Method deprecatedMethod, String deprecatedPath, DeprecationLogger logger) {
- super(method, path);
- this.deprecatedMethod = deprecatedMethod;
- this.deprecatedPath = deprecatedPath;
- this.logger = logger;
+ public static ReplacementInfo replacedRoute(Route replacedRoute) {
+ return new ReplacementInfo(true, replacedRoute);
}
- public String getDeprecatedPath() {
- return deprecatedPath;
+ private ReplacementInfo(boolean isReplacement, Route replacedRoute) {
+ assert (isReplacement && replacedRoute != null) || (isReplacement == false && replacedRoute == null);
+ if (replacedRoute.isDeprecated() == false) {
+ throw new IllegalArgumentException();
+ }
+ this.isReplacement = isReplacement;
+ this.replacedRoute = replacedRoute;
}
- public Method getDeprecatedMethod() {
- return deprecatedMethod;
+ public boolean isReplacement() {
+ return isReplacement;
}
- public DeprecationLogger getLogger() {
- return logger;
+ public Route replacedRoute() {
+ if (isReplacement) {
+ return replacedRoute;
+ } else {
+ throw new IllegalStateException();
+ }
}
+
}
+
}
diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/rest/RestDeleteExpiredDataAction.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/rest/RestDeleteExpiredDataAction.java
index 11ca99d9d3a..faa96d23755 100644
--- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/rest/RestDeleteExpiredDataAction.java
+++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/rest/RestDeleteExpiredDataAction.java
@@ -5,9 +5,7 @@
*/
package org.elasticsearch.xpack.ml.rest;
-import org.apache.logging.log4j.LogManager;
import org.elasticsearch.client.node.NodeClient;
-import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.RestToXContentListener;
@@ -22,21 +20,10 @@ import static org.elasticsearch.rest.RestRequest.Method.DELETE;
public class RestDeleteExpiredDataAction extends BaseRestHandler {
- private static final DeprecationLogger deprecationLogger =
- new DeprecationLogger(LogManager.getLogger(RestDeleteExpiredDataAction.class));
-
@Override
public List<Route> routes() {
- return Collections.emptyList();
- }
-
- @Override
- public List<ReplacedRoute> replacedRoutes() {
- // TODO: remove deprecated endpoint in 8.0.0
return Collections.singletonList(
- new ReplacedRoute(DELETE, MachineLearning.BASE_PATH + "_delete_expired_data",
- DELETE, MachineLearning.PRE_V7_BASE_PATH + "_delete_expired_data",
- deprecationLogger)
+ new Route(DELETE, MachineLearning.BASE_PATH + "_delete_expired_data", DELETE, MachineLearning.PRE_V7_BASE_PATH + "_delete_expired_data")
);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The more I think about it, the more I think we should keep it how you have it for now. If we find reasons to combine this into a single pattern in the future, the above gives us a way forward on how we do that. Let's leave it out of this change though, this is already a huge improvement over where we were, and no need to delay getting it in any further when it's not clear what the benefits are.
for (ActionPlugin plugin : actionPlugins) { | ||
for (RestHandler handler : plugin.getRestHandlers(settings, restController, clusterSettings, indexScopedSettings, | ||
settingsFilter, indexNameExpressionResolver, nodesInCluster)) { | ||
registerHandler.accept(handler); | ||
} | ||
} | ||
registerHandler.accept(new RestCatAction(restController, catActions)); | ||
registerHandler.accept(new RestCatAction(catActions)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
private final String deprecationMessage; | ||
private final DeprecationLogger logger; | ||
|
||
public DeprecatedRoute(Method method, String path, String deprecationMessage, DeprecationLogger logger) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a follow-up, let's get these loggers out of here. It doesn't make sense they are put of the route, and reflecting on it, I don't think we need a dedicated deprecation logger for every REST handler that deprecates some method. I think we can create a top-level RestController deprecation logger for this purpose.
private final Method deprecatedMethod; | ||
private final DeprecationLogger logger; | ||
|
||
public ReplacedRoute(Method method, String path, Method deprecatedMethod, String deprecatedPath, DeprecationLogger logger) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment here about the deprecation logger.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Lgtm2
…On Sat, Feb 8, 2020, 20:04 Jason Tedor ***@***.***> wrote:
***@***.**** approved this pull request.
LGTM.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#51950?email_source=notifications&email_token=AABUXIXYSNXVVXZLO5TUG6LRB5JCNA5CNFSM4KQNSCTKYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCUY24QI#pullrequestreview-355577409>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABUXITDHKUNR44NAIEFNYLRB5JCNANCNFSM4KQNSCTA>
.
|
This commit changes how RestHandlers are registered with the RestController so that a RestHandler no longer needs to register itself with the RestController. Instead the RestHandler interface has new methods which when called provide information about the routes (method and path combinations) that are handled by the handler including any deprecated and/or replaced combinations. This change also makes the publication of RestHandlers safe since they no longer publish a reference to themselves within their constructors. Closes #51622 Co-authored-by: Jason Tedor <jason@tedor.me> Backport of #51950
This commit adapts searchable snapshots to the latest changes from master. The REST handlers declare their routes differently since #51950 and SearchableSnapshotIndexInput need to account for segment infos files that are stored in shard snapshot metadata hash and not uploaded to the blob store anymore since #51729.
This commit removes the need for DeprecatedRoute and ReplacedRoute to have an instance of a DeprecationLogger. Instead the RestController now has a DeprecationLogger that will be used for all deprecated and replaced route messages. Relates elastic#51950
This commit removes the need for DeprecatedRoute and ReplacedRoute to have an instance of a DeprecationLogger. Instead the RestController now has a DeprecationLogger that will be used for all deprecated and replaced route messages. Relates #51950
This commit removes the need for DeprecatedRoute and ReplacedRoute to have an instance of a DeprecationLogger. Instead the RestController now has a DeprecationLogger that will be used for all deprecated and replaced route messages. Relates elastic#51950
This commit replaces usages of older collection utility methods with the JDK 9 convenience method `List.of()`. Relates elastic#51950
This commit replaces usages of older collection utility methods with the JDK 9 convenience method `List.of()`. Relates #51950
* upgrade gradle to 6.4 * Routes replace usage of RestController.register elastic/elasticsearch#51950 * add setting index.hidden=true to createIndex * solve IT allowed action list problem * try hard code jvmArgs * add release note * revert immutableList change, use listOf jvmArgs put into afterEvaluate phase
* upgrade gradle to 6.4 * Routes replace usage of RestController.register elastic/elasticsearch#51950 * add setting index.hidden=true to createIndex * solve IT allowed action list problem * try hard code jvmArgs * add release note * revert immutableList change, use listOf jvmArgs put into afterEvaluate phase
This commit changes how RestHandlers are registered with the
RestController so that a RestHandler no longer needs to register itself
with the RestController. Instead the RestHandler interface has new
methods which when called provide information about the method and path
combinations that are handled by the handler including any deprecated
and/or replaced combinations.
This change also makes the publication of RestHandlers safe since they
no longer publish a reference to themselves within their constructors.
Closes #51622