RestFilters for ES 5.x


(Vinh Nguyen) #1

Goal: log all REST requests made to ElasticSearch 5.6.4 cluster.

*Note: in ES 2.x, this can done via RestFilter and RestFilterChain but I am struggle to find the equivalent for ES 5.x .

Implementation 1:

  • I wrote a plugin (RestlogPlugin) which extends Plugin and implements ActionPlugin.
  • My plugin overrides getRestHandlerWrapper() and returns a RestHandler (RestLogHandler).
  • My rest handler overrides:
    protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client)

Question:

  • within the rest handler once I finish my custom bizlogic, how do I create RestChannelConsumer to continue processing the request through tis normal flow? Specifically, what is the 5.x equivalent of Es 2.x RestFilterChain.continueProcessing()?

Implementation 2:

  • I wrote a plugin (RestlogPlugin) which extends Plugin and implements ActionPlugin.
  • My plugin overrides:

getActionFilters() and returns an ActionFilter (RestLogActionFilter).

  • My action filter overrides:

public <Request extends ActionRequest, Response extends ActionResponse> void apply(Task task, String action, Request request, ActionListener listener, ActionFilterChain<Request, Response> chain

Question:

  • within applyTask(), Request is not a RestRequest so how do I get the information http headers of the REST request?

(Vinh Nguyen) #2

@s1monw . Hi Simon, apologies for pinging you directly. I am a developer here at Netflix and I have hit a blocker that I hope you can provide guidance. I found your handle base on a previous discussion of the same topic (Basic Authentication using RestFilter).

Regards


(Mohamed Arif Hanifa) #3

Hi,

No - I did not able to find a solution for Basic Autentication using RestFilter.

Thanks

-arif


(Simon Willnauer) #4

I assume you use this method: https://github.com/elastic/elasticsearch/blob/5.6/core/src/main/java/org/elasticsearch/plugins/ActionPlugin.java#L93

so you have full control over all rest requests. There is no additional logic and I don't know what you mean by RestChannelConsumer to be honest. you just wrap the incoming RestHandler in your impl and execute you biz logic before delegating to the incoming RestHandler#handleRequest method (https://github.com/elastic/elasticsearch/blob/5.6/core/src/main/java/org/elasticsearch/rest/RestHandler.java#L36). The RestChannelConsumer class doesn't exist in 5.x?


(Vinh Nguyen) #5

@s1monw Hi Simon, thanks for responding. Ok, getting closer, I have the following:

public class RestlogPlugin extends Plugin implements ActionPlugin {

@Override
public UnaryOperator<RestHandler> getRestHandlerWrapper(ThreadContext threadContext) {

         /*
        Simon, I don't see how to get the "incoming RestHandler" that you mentioned?
         */
}

}


(Simon Willnauer) #6

you have to return a factory like this:

UnaryOperator<RestHandler> getRestHandlerWrapper(ThreadContext threadContext) {
    return originalHanlder ->
        (RestHandler) (request, channel, client) -> {
            System.out.println("Log Something");
            originalHanlder.handleRequest(request, channel, client);
        };
}

Authentication Plugin
(Vinh Nguyen) #7

Hi Simon,

It was not obvious to me from javadoc, discussions, or existing 5.x code samples that the original rest handler is provided to an implementation of ActionPlugin. Specifically, RestController.dispatchRequest(...) creates a RestHandler base on the request and gives it to the implementation of ActionPlugin.

Thanks for the help. I can create a PR to update the javadoc for getRestHandlerWrapper(..) if there is value.

Regards


(Surya Moitra) #8

Hi @Vinh_Nguyen - It will be of immense help if you can put together the basics of your implementation here in this forum/topic. For eg: I need to use ES6.x for a Custom Implemengtation in the next week.I guess, the help from @s1monw will also be captured and it need not be repeated across redundant topics.

Something like,
public class CustomRESTPlugin extends Plugin implements ActionPlugin {
@Override
UnaryOperator getRestHandlerWrapper(ThreadContext threadContext) {
return originalHanlder ->
(RestHandler) (request, channel, client) -> {
System.out.println("Log Something");
originalHanlder.handleRequest(request, channel, client);
};
}

//Any other methods/changes?
}

public class CustomRESTHandler extends BaseRestHandler {
//constructor - please add
@Override
public void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws
IOException {
System.out.println("CustomRESTHandler is running");
//custom code - we have the 'request'
}
//any other methods ?

}

@arimoham - Did you find any other implementation ?


(Simon Willnauer) #9

please do and ping me on the issue/PR. my handle on github is the same as here


(Vinh Nguyen) #10

@smoitra A couple of things concerning your object diagram.

1.If your plugin contains logic to handle the request, you don't need the CustomRESTHandler class.
2.If you choose to use CustomRESTHandler:

  • When your plugin instantiates your custom handler, you need to pass it the original handler. Original handler should be use within handleRequest(...) to pass the request along its normal processing.

(Surya Moitra) #11

@Vinh_Nguyen - I need to have some logic on the header(custom security) of the request - hence wanted to have the CustomRESTHandler class.
Can you can please put down the structure/object diagram/psuedo code in that case?

Thanks!


(Vinh Nguyen) #12

@smoitra here it is:

public class YourPlugin extends Plugin implements ActionPlugin {
@Override
public UnaryOperator getRestHandlerWrapper(ThreadContext threadContext) {
UnaryOperator u = (originalRestHandler) -> {
final YourRestLogHandler yourResttLogHandler = new YourRestLogHandler(originalRestHandler);
return yourResttLogHandler;
}
}
}

public class YourRestLogHandler implements RestHandler {
public YourRestLogHandler(RestHandler originalRestHandler) {
this.originalRestHandler = originalRestHandler;
}

@Override
public void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws
Exception {
try {
//your customer bizlogic
} catch (Exception e) {
} finally {
this.originalRestHandler.handleRequest(request, channel, client);
}

}
}


(Surya Moitra) #13

Thanks @Vinh_Nguyen


(system) #14

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.