You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by James Carman <ja...@carmanconsulting.com> on 2018/10/03 21:33:07 UTC

JAX-RS Client Proxies Don't Handle @HeaderParam Set Properly

Suppose I have a service like this:

@Path("/")
public interface HeaderSetResource {
    @GET
    @Path("/hello")
    @Produces(TEXT_PLAIN)
    String sayHello(@HeaderParam("names") Set<String> names);
}


This test case fails:

@RunWith(MockitoJUnitRunner.class)
public class HeaderSetTest {

    @Mock
    private HeaderSetResource resourceMock;

    private Server server;
    private String address;


    private void callHello(Set<String> names) {
        final Invocation.Builder builder = webTarget().path("hello").request();
        names.forEach(name -> builder.header("names", name));
        builder.get();
    }

    public HeaderSetResource clientProxy() {
        final JAXRSClientFactoryBean factoryBean = new JAXRSClientFactoryBean();
        factoryBean.setFeatures(Collections.singletonList(new
LoggingFeature()));
        factoryBean.setResourceClass(HeaderSetResource.class);
        factoryBean.setAddress(address);
        return factoryBean.create(HeaderSetResource.class);
    }

    @Before
    public void createServer() {
        String port = "10090";
        address = String.format("http://localhost:%s/", port);

        final JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
        sf.setBus(BusFactory.getDefaultBus(true));
        sf.setResourceClasses(HeaderSetResource.class);
        sf.setFeatures(Collections.singletonList(new LoggingFeature()));
        sf.setResourceProvider(HeaderSetResource.class, new
SingletonResourceProvider(resourceMock, true));
        sf.setAddress(address);
        server = sf.create();
    }

    @Test
    public void multipleHeadersShouldWorkWithProxy() {
        final Set<String> names = new HashSet<>(Arrays.asList("foo",
"bar", "baz"));
        clientProxy().sayHello(names);
        verify(resourceMock).sayHello(names);
    }

    @Test
    public void multipleHeadersShouldWorkWithWebTarget() {
        final Set<String> names = new HashSet<>(Arrays.asList("foo",
"bar", "baz"));
        callHello(names);
        verify(resourceMock).sayHello(names);
    }

    @Test
    public void singleHeadersShouldWorkWithProxy() {
        final Set<String> names = Collections.singleton("foo");
        clientProxy().sayHello(names);
        verify(resourceMock).sayHello(names);
    }

    @Test
    public void singleHeadersShouldWorkWithWebTarget() {
        final Set<String> names = Collections.singleton("foo");
        callHello(names);
        verify(resourceMock).sayHello(names);
    }

    @After
    public void stopServer() {
        server.stop();
        server.destroy();
    }

    public WebTarget webTarget() {
        final ClientBuilder builder = ClientBuilder.newBuilder();
        builder.register(new LoggingFeature());
        return builder.build()
                .property(AsyncHTTPConduit.USE_ASYNC, Boolean.TRUE)
                .target(address);
    }
}

Re: JAX-RS Client Proxies Don't Handle @HeaderParam Set Properly

Posted by James Carman <ja...@carmanconsulting.com>.
The return isn’t really necessary at all. I’m just verifying that the
parameters are “correct” as they are received in the server
On Thu, Oct 4, 2018 at 3:54 PM Andy McCright <j....@gmail.com>
wrote:

> Hi James,
>
> What is the failure message/stack trace/etc. that you are seeing?  I'm not
> too familiar with Mockito, but I don't see anywhere where the resource
> class returns anything.  Possibly that is the problem?
>
> Also, did these tests previously work and recently started failing?  I have
> been making some changes in this area in order to support the MicroProfile
> Rest Client - it's possible I regressed something.
>
> Thanks,
>
> Andy
>
> On Wed, Oct 3, 2018 at 4:33 PM James Carman <ja...@carmanconsulting.com>
> wrote:
>
> > Suppose I have a service like this:
> >
> > @Path("/")
> > public interface HeaderSetResource {
> >     @GET
> >     @Path("/hello")
> >     @Produces(TEXT_PLAIN)
> >     String sayHello(@HeaderParam("names") Set<String> names);
> > }
> >
> >
> > This test case fails:
> >
> > @RunWith(MockitoJUnitRunner.class)
> > public class HeaderSetTest {
> >
> >     @Mock
> >     private HeaderSetResource resourceMock;
> >
> >     private Server server;
> >     private String address;
> >
> >
> >     private void callHello(Set<String> names) {
> >         final Invocation.Builder builder =
> > webTarget().path("hello").request();
> >         names.forEach(name -> builder.header("names", name));
> >         builder.get();
> >     }
> >
> >     public HeaderSetResource clientProxy() {
> >         final JAXRSClientFactoryBean factoryBean = new
> > JAXRSClientFactoryBean();
> >         factoryBean.setFeatures(Collections.singletonList(new
> > LoggingFeature()));
> >         factoryBean.setResourceClass(HeaderSetResource.class);
> >         factoryBean.setAddress(address);
> >         return factoryBean.create(HeaderSetResource.class);
> >     }
> >
> >     @Before
> >     public void createServer() {
> >         String port = "10090";
> >         address = String.format("http://localhost:%s/", port);
> >
> >         final JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
> >         sf.setBus(BusFactory.getDefaultBus(true));
> >         sf.setResourceClasses(HeaderSetResource.class);
> >         sf.setFeatures(Collections.singletonList(new LoggingFeature()));
> >         sf.setResourceProvider(HeaderSetResource.class, new
> > SingletonResourceProvider(resourceMock, true));
> >         sf.setAddress(address);
> >         server = sf.create();
> >     }
> >
> >     @Test
> >     public void multipleHeadersShouldWorkWithProxy() {
> >         final Set<String> names = new HashSet<>(Arrays.asList("foo",
> > "bar", "baz"));
> >         clientProxy().sayHello(names);
> >         verify(resourceMock).sayHello(names);
> >     }
> >
> >     @Test
> >     public void multipleHeadersShouldWorkWithWebTarget() {
> >         final Set<String> names = new HashSet<>(Arrays.asList("foo",
> > "bar", "baz"));
> >         callHello(names);
> >         verify(resourceMock).sayHello(names);
> >     }
> >
> >     @Test
> >     public void singleHeadersShouldWorkWithProxy() {
> >         final Set<String> names = Collections.singleton("foo");
> >         clientProxy().sayHello(names);
> >         verify(resourceMock).sayHello(names);
> >     }
> >
> >     @Test
> >     public void singleHeadersShouldWorkWithWebTarget() {
> >         final Set<String> names = Collections.singleton("foo");
> >         callHello(names);
> >         verify(resourceMock).sayHello(names);
> >     }
> >
> >     @After
> >     public void stopServer() {
> >         server.stop();
> >         server.destroy();
> >     }
> >
> >     public WebTarget webTarget() {
> >         final ClientBuilder builder = ClientBuilder.newBuilder();
> >         builder.register(new LoggingFeature());
> >         return builder.build()
> >                 .property(AsyncHTTPConduit.USE_ASYNC, Boolean.TRUE)
> >                 .target(address);
> >     }
> > }
> >
>

Re: JAX-RS Client Proxies Don't Handle @HeaderParam Set Properly

Posted by Andy McCright <j....@gmail.com>.
Hi James,

What is the failure message/stack trace/etc. that you are seeing?  I'm not
too familiar with Mockito, but I don't see anywhere where the resource
class returns anything.  Possibly that is the problem?

Also, did these tests previously work and recently started failing?  I have
been making some changes in this area in order to support the MicroProfile
Rest Client - it's possible I regressed something.

Thanks,

Andy

On Wed, Oct 3, 2018 at 4:33 PM James Carman <ja...@carmanconsulting.com>
wrote:

> Suppose I have a service like this:
>
> @Path("/")
> public interface HeaderSetResource {
>     @GET
>     @Path("/hello")
>     @Produces(TEXT_PLAIN)
>     String sayHello(@HeaderParam("names") Set<String> names);
> }
>
>
> This test case fails:
>
> @RunWith(MockitoJUnitRunner.class)
> public class HeaderSetTest {
>
>     @Mock
>     private HeaderSetResource resourceMock;
>
>     private Server server;
>     private String address;
>
>
>     private void callHello(Set<String> names) {
>         final Invocation.Builder builder =
> webTarget().path("hello").request();
>         names.forEach(name -> builder.header("names", name));
>         builder.get();
>     }
>
>     public HeaderSetResource clientProxy() {
>         final JAXRSClientFactoryBean factoryBean = new
> JAXRSClientFactoryBean();
>         factoryBean.setFeatures(Collections.singletonList(new
> LoggingFeature()));
>         factoryBean.setResourceClass(HeaderSetResource.class);
>         factoryBean.setAddress(address);
>         return factoryBean.create(HeaderSetResource.class);
>     }
>
>     @Before
>     public void createServer() {
>         String port = "10090";
>         address = String.format("http://localhost:%s/", port);
>
>         final JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
>         sf.setBus(BusFactory.getDefaultBus(true));
>         sf.setResourceClasses(HeaderSetResource.class);
>         sf.setFeatures(Collections.singletonList(new LoggingFeature()));
>         sf.setResourceProvider(HeaderSetResource.class, new
> SingletonResourceProvider(resourceMock, true));
>         sf.setAddress(address);
>         server = sf.create();
>     }
>
>     @Test
>     public void multipleHeadersShouldWorkWithProxy() {
>         final Set<String> names = new HashSet<>(Arrays.asList("foo",
> "bar", "baz"));
>         clientProxy().sayHello(names);
>         verify(resourceMock).sayHello(names);
>     }
>
>     @Test
>     public void multipleHeadersShouldWorkWithWebTarget() {
>         final Set<String> names = new HashSet<>(Arrays.asList("foo",
> "bar", "baz"));
>         callHello(names);
>         verify(resourceMock).sayHello(names);
>     }
>
>     @Test
>     public void singleHeadersShouldWorkWithProxy() {
>         final Set<String> names = Collections.singleton("foo");
>         clientProxy().sayHello(names);
>         verify(resourceMock).sayHello(names);
>     }
>
>     @Test
>     public void singleHeadersShouldWorkWithWebTarget() {
>         final Set<String> names = Collections.singleton("foo");
>         callHello(names);
>         verify(resourceMock).sayHello(names);
>     }
>
>     @After
>     public void stopServer() {
>         server.stop();
>         server.destroy();
>     }
>
>     public WebTarget webTarget() {
>         final ClientBuilder builder = ClientBuilder.newBuilder();
>         builder.register(new LoggingFeature());
>         return builder.build()
>                 .property(AsyncHTTPConduit.USE_ASYNC, Boolean.TRUE)
>                 .target(address);
>     }
> }
>