Skip to content

Commit

Permalink
Properly implement priority of ContainerResponseFilter
Browse files Browse the repository at this point in the history
  • Loading branch information
geoand committed Nov 1, 2024
1 parent 3d022be commit a6edf30
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ class TreeMapComparator implements Comparator<HasPriority> {

public static final TreeMapComparator INSTANCE = new TreeMapComparator();

public static final TreeMapComparator REVERSED = new TreeMapComparator() {
@Override
public int compare(HasPriority o1, HasPriority o2) {
return super.compare(o2, o1);
}
};

@Override
public int compare(HasPriority o1, HasPriority o2) {
int res = o1.priority().compareTo(o2.priority());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ public void setRuntimeType(RuntimeType runtimeType) {
this.runtimeType = runtimeType;
}

// spec says that writer interceptors are sorted in ascending order
@Override
public int compareTo(ResourceInterceptor<T> o) {
return this.priority().compareTo(o.priority());
Expand All @@ -105,12 +104,8 @@ public int compareTo(ResourceInterceptor<T> o) {
public static class Reversed<T> extends ResourceInterceptor<T> {

@Override
public Integer priority() {
Integer p = super.priority();
if (p == null) {
return null;
}
return -p;
public int compareTo(ResourceInterceptor<T> o) {
return o.priority().compareTo(this.priority());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ <T> TreeMap<ResourceInterceptor<T>, T> buildInterceptorMap(
Map<ResourceInterceptor<T>, T> globalInterceptorsMap,
Map<ResourceInterceptor<T>, T> nameInterceptorsMap,
Map<ResourceInterceptor<T>, T> methodSpecificInterceptorsMap, ResourceMethod method, boolean reversed) {
TreeMap<ResourceInterceptor<T>, T> interceptorsToUse = new TreeMap<>(HasPriority.TreeMapComparator.INSTANCE);
TreeMap<ResourceInterceptor<T>, T> interceptorsToUse = new TreeMap<>(
reversed ? HasPriority.TreeMapComparator.REVERSED : HasPriority.TreeMapComparator.INSTANCE);
interceptorsToUse.putAll(globalInterceptorsMap);
interceptorsToUse.putAll(methodSpecificInterceptorsMap);
for (ResourceInterceptor<T> nameInterceptor : nameInterceptorsMap.keySet()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package org.jboss.resteasy.reactive.server.vertx.test.simple;

import static io.restassured.RestAssured.*;
import static io.restassured.RestAssured.when;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.is;

import java.io.IOException;

import jakarta.annotation.Priority;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerResponseContext;
import jakarta.ws.rs.container.ContainerResponseFilter;
import jakarta.ws.rs.ext.Provider;

import org.jboss.resteasy.reactive.server.vertx.test.CookiesSetInFilterTest;
import org.jboss.resteasy.reactive.server.vertx.test.framework.ResteasyReactiveUnitTest;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.restassured.http.Headers;

public class MultipleResponseFiltersWithPrioritiesTest {

@RegisterExtension
static ResteasyReactiveUnitTest test = new ResteasyReactiveUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(CookiesSetInFilterTest.TestResource.class, CookiesSetInFilterTest.Filters.class));

@Test
void requestDoesNotContainCookie() {
when().get("/test")
.then()
.statusCode(200)
.body(is("foo"));
}

@Test
void test() {
Headers headers = get("/hello")
.then()
.statusCode(200)
.extract().headers();
assertThat(headers.getValues("filter-response")).containsOnly("max-default-0-minPlus1-min");
}

@Path("hello")
public static class TestResource {

@GET
public String get() {
return "hello";
}
}

@Provider
@Priority(Integer.MAX_VALUE)
public static class FilterMax implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
responseContext.getHeaders().putSingle("filter-response", "max");
}

}

@Provider
public static class FilterDefault implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
String previousFilterHeaderValue = (String) responseContext.getHeaders().getFirst("filter-response");
responseContext.getHeaders().putSingle("filter-response", previousFilterHeaderValue + "-default");
}

}

@Provider
@Priority(0)
public static class Filter0 implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
String previousFilterHeaderValue = (String) responseContext.getHeaders().getFirst("filter-response");
responseContext.getHeaders().putSingle("filter-response", previousFilterHeaderValue + "-0");
}

}

@Provider
@Priority(Integer.MIN_VALUE + 1)
public static class FilterMinPlus1 implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
String previousFilterHeaderValue = (String) responseContext.getHeaders().getFirst("filter-response");
responseContext.getHeaders().putSingle("filter-response", previousFilterHeaderValue + "-minPlus1");
}

}

@Provider
@Priority(Integer.MIN_VALUE)
public static class FilterMin implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
String previousFilterHeaderValue = (String) responseContext.getHeaders().getFirst("filter-response");
responseContext.getHeaders().putSingle("filter-response", previousFilterHeaderValue + "-min");
}

}
}

0 comments on commit a6edf30

Please sign in to comment.