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

Fix the filter order in starter #766

Merged
merged 5 commits into from
Nov 2, 2018
Merged

Fix the filter order in starter #766

merged 5 commits into from
Nov 2, 2018

Conversation

dhaval24
Copy link
Contributor

This fixes the order of Filter injection using SpringBoot starter. It allows to capture the correct response code for failed requests.

It turns out that : Ordered.HIGHEST_PRECEDENCE = Integer.MIN_VALUE and we were adding 10 to it which reduced the priority eventually ;)

@grlima @littleaj could you please review this change. It is small and there is request to make hot fix for this.

Deployed the changes in the test app and here is the distributed transaction.

image

@dhaval24 dhaval24 requested review from littleaj and grlima October 25, 2018 17:09
@@ -69,7 +69,7 @@ public FilterRegistrationBean webRequestTrackingFilterRegistrationBean(WebReques
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(webRequestTrackingFilter);
registration.addUrlPatterns("/*");
registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 10);
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ordered.HIGHEST_PRECEDENCE = Integer.MIN_VALUE. Adding 10 to it eventually reduced our filter priority :(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does having Highest Precedence mess up other scenarios? It seems @gavlyukovskiy had concerns with doing this when he first introduced the starter in #518
Specifically, he mentioned it could prevent users or the framework itself from running code before ours. Is it a problem? Can we double check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@grlima For reference : https://www.tuturself.com/posts/view?menuId=3&postId=1141
If any other filter runs before our Filter, it would just not enable us to capture the right timing information, the correct response code etc. It is critical to have our filter as the first filter to get the correct information. For example - this filter was running after our Filter : https://github.com/spring-projects/spring-framework/blob/master/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java
after which the response code in the response object changed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be ok to order it as highest as long as it can be changed by the user. @dhaval24 , is this possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@littleaj currently there is no such mechanism in starter, but it would be fairly easy to bring this if needed. However, in case of a conflict it is upto the Spring to decide which order it wants to execute the filters. Also there are multiple filters in Spring with highest precedence. It is fine for them to execute in relative order among themselves.

The important point here is that our filter executes above any other filter whose priority is less that HIGHEST_ORDER. @grlima this should also explain your concern.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially I did it to let user the ability to put something before this filter. For instance we had logging filter that we needed to run earlier whatever happens in other libraries.
I think +2 would be okay, at least users have some room to breathe.

@littleaj
Copy link
Contributor

littleaj commented Oct 25, 2018

@dhaval24, have you tested this with spring error/exception handlers?

@dhaval24
Copy link
Contributor Author

@dhaval24, have you tested this with spring error/exception handlers?

@littleaj can you elaborate a bit on this.

@dhaval24
Copy link
Contributor Author

@grlima and @littleaj ok, I did some more research: https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-embedded-container-servlets-filters-listeners

It says to avoid HIGHEST_PRECEDENCE. But I think +10 is making it too late in the chain. May +2 so that it just comes after the metrics filter should be okay.

@dhaval24
Copy link
Contributor Author

Spring’s WebMVC Metrics filter : https://github.com/spring-projects/spring-boot/blob/5a4220c77383741205203b615d40de82b890e153/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilter.java#L166 is responsible to set the status code for the request ultimately.

The priority of this filter is : Ordered.HIGHEST_PRECEDENCE + 1
Based on SpringBoot docs here: https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-embedded-container-servlets-filters-listeners

Therefore, if we would not have the Ordered.HIGHEST_PRECEDENCE, it would be impossible to capture the correct response code from the Filter Based Method we have today. We need to be first in the filter chain in one way or the other.

@dhaval24
Copy link
Contributor Author

Spring’s WebMVC Metrics filter : https://github.com/spring-projects/spring-boot/blob/5a4220c77383741205203b615d40de82b890e153/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilter.java#L166 is responsible to set the status code for the request ultimately.

The priority of this filter is : Ordered.HIGHEST_PRECEDENCE + 1
Based on SpringBoot docs here: https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-embedded-container-servlets-filters-listeners

Therefore, if we would not have the Ordered.HIGHEST_PRECEDENCE, it would be impossible to capture the correct response code from the Filter Based Method we have today. We need to be first in the filter chain in one way or the other.

@gavlyukovskiy please consider the above!! and let me know your thoughts

@littleaj
Copy link
Contributor

@dhaval24 ErrorPageFilter can also set the status

@dhaval24
Copy link
Contributor Author

@dhaval24 ErrorPageFilter can also set the status

Sure @littleaj that makes sense. It's precedence is also Ordered.HIGHEST_PRECEDENCE + 1 (as from SpringBoot docs). Therefore I think we would need to have the filter at HIGHEST_PRECEDENCE if we want to stick with the filter based solution.

@littleaj
Copy link
Contributor

@dhaval24 regarding error handlers, in j2ee you can specify error pages to handle certain exceptions. These pages can change the result code sent back to the user (which don't make it back to the filter). I was wondering if Spring has the same issue. Spring lets you define error handlers which do the same thing.

@littleaj
Copy link
Contributor

@dhaval24 What happens if you define more filters with HIGHEST_PRECEDENCE? Is the order determinate by some other factor?

@gavlyukovskiy
Copy link
Contributor

@littleaj order of beans with order value is non deterministic, though there is interface PriorityOrdered which is used in exceptional cases and those beans have higher precedence over the beans that don't implement it.

Copy link
Contributor

@littleaj littleaj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Just need a passing build.

@dhaval24
Copy link
Contributor Author

Thanks @littleaj , I queued a new build.

@dhaval24
Copy link
Contributor Author

dhaval24 commented Oct 29, 2018

@dhaval24
Copy link
Contributor Author

dhaval24 commented Nov 2, 2018

@grlima and @littleaj I also verified the correlation and it works good with this change too.
image

Here is a node app communicating with java app. I think this change is good to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants