2015-11-10 1 views
10

サーバー送信イベントリソースを追加のCookieでユニットテストしようとしています。私は既にJerseyをEventSourceに、JavaXをクライアント用に使用しています。次のコードは正常に動作します。追加のCookieを含むサーバー送信イベントクライアント

WebTarget target = ClientBuilder.newBuilder() 
     .register(SseFeature.class) 
     .build() 
     .target("http://localhost:8080/sse"); 
    EventSource eventSource = EventSource.target(target).build(); 
    EventListener listener = new EventListener() { 
     @Override 
     public void onEvent(InboundEvent inboundEvent) { 
      LOG.info(inboundEvent.readData(String.class)); 
     } 
    }; 
    eventSource.register(listener); 
    eventSource.open(); 
    serverEventManager.send("/sse", "foo"); 
    eventSource.close(); 

さらにユニットテストのために、リクエストに追加のクッキーを追加する必要があります。私はすでに次のように試しました

target.(...).request.cookie("foo", "bar"); 

しかし、これは私がEventSourceに必要なWebTargetを作成できないBuilderを返します。ここにクッキーを追加する機会を - 私たちは見ることができないとして

 private Invocation.Builder prepareHandshakeRequest() { 
      Invocation.Builder request = EventSource.this.target 
        .request(new MediaType[] { SseFeature.SERVER_SENT_EVENTS_TYPE }); 
      if ((this.lastEventId != null) && (!(this.lastEventId.isEmpty()))) { 
       request.header("Last-Event-ID", this.lastEventId); 
      } 
      if (EventSource.this.disableKeepAlive) { 
       request.header("Connection", "close"); 
      } 
      return request; 
      } 

:ここ

答えて

8

は、与えられたWebTargetにたっを確立するためのEventSource以内に何が起こるかだのです。

したがってWebTarget.request(new MediaType[] { SseFeature.SERVER_SENT_EVENTS_TYPE })は、既に希望のクッキーが追加されている のBuilderを返す必要があります。

すべてrequest*型のメソッドに必要なクッキーを追加し、この委譲クラスを考えてみましょう:

public class CookieAddedWebTarget implements WebTarget { 

    private WebTarget base; 

    private Cookie cookie; 

    public CookieAddedWebTarget(WebTarget base, Cookie cookie) { 
     this.base = base; 
     this.cookie = cookie; 
    } 

    // Inject that cookie whenever someone requests a Builder (like EventSource does): 
    public Builder request() { 
     return base.request().cookie(cookie); 
    } 

    public Builder request(String... paramArrayOfString) { 
     return base.request(paramArrayOfString).cookie(cookie); 
    } 

    public Builder request(MediaType... paramArrayOfMediaType) { 
     return base.request(paramArrayOfMediaType).cookie(cookie); 
    } 

    public Configuration getConfiguration() { 
     return base.getConfiguration(); 
    } 

    //All other methods from WebTarget are delegated as-is: 

    public URI getUri() { 
     return base.getUri(); 
    } 

    public UriBuilder getUriBuilder() { 
     return base.getUriBuilder(); 
    } 

    public WebTarget path(String paramString) { 
     return base.path(paramString); 
    } 

    public WebTarget matrixParam(String paramString, Object... paramArrayOfObject) { 
     return base.matrixParam(paramString, paramArrayOfObject); 
    } 

    public WebTarget property(String paramString, Object paramObject) { 
     return base.property(paramString, paramObject); 
    } 

    public WebTarget queryParam(String paramString, Object... paramArrayOfObject) { 
     return base.queryParam(paramString, paramArrayOfObject); 
    } 

    public WebTarget register(Class<?> paramClass, Class<?>... paramArrayOfClass) { 
     return base.register(paramClass, paramArrayOfClass); 
    } 

    public WebTarget register(Class<?> paramClass, int paramInt) { 
     return base.register(paramClass, paramInt); 
    } 

    public WebTarget register(Class<?> paramClass, Map<Class<?>, Integer> paramMap) { 
     return base.register(paramClass, paramMap); 
    } 

    public WebTarget register(Class<?> paramClass) { 
     return base.register(paramClass); 
    } 

    public WebTarget register(Object paramObject, Class<?>... paramArrayOfClass) { 
     return base.register(paramObject, paramArrayOfClass); 
    } 

    public WebTarget register(Object paramObject, int paramInt) { 
     return base.register(paramObject, paramInt); 
    } 

    public WebTarget register(Object paramObject, Map<Class<?>, Integer> paramMap) { 
     return base.register(paramObject, paramMap); 
    } 

    public WebTarget register(Object paramObject) { 
     return base.register(paramObject); 
    } 

    public WebTarget resolveTemplate(String paramString, Object paramObject) { 
     return base.resolveTemplate(paramString, paramObject); 
    } 

    public WebTarget resolveTemplate(String paramString, Object paramObject, boolean paramBoolean) { 
     return base.resolveTemplate(paramString, paramObject, paramBoolean); 
    } 

    public WebTarget resolveTemplateFromEncoded(String paramString, Object paramObject) { 
     return base.resolveTemplateFromEncoded(paramString, paramObject); 
    } 

    public WebTarget resolveTemplates(Map<String, Object> paramMap) { 
     return base.resolveTemplates(paramMap); 
    } 

    public WebTarget resolveTemplates(Map<String, Object> paramMap, boolean paramBoolean) { 
     return base.resolveTemplates(paramMap, paramBoolean); 
    } 

    public WebTarget resolveTemplatesFromEncoded(Map<String, Object> paramMap) { 
     return base.resolveTemplatesFromEncoded(paramMap); 
    } 

} 

今、あなたがあなたのテストをreeriteすることができるはずです。

EventSource eventSource = EventSource.target(new CookieAddedWebTarget(target, 
          new Cookie("name", "value"))).build(); 

そしてクッキーを挿入する必要があります。

警告:私はこれをテストする方法がありません。 jersey-media-sse-2.22.1のソースコードの読み取りにのみ基づいたソリューション。

Good Luck。

+0

私のテストケースを更新しただけで動作します。ありがとう! – svenkubiak

+0

うん、うまくいく。しかし、真剣に、ジャージーの人々はこれをもう少し便利にすることができますか? – Hank

3

ClientRequestFilterにクッキーを設定できます。 ClientRequestContextgetCookies()は変更できませんが、クッキーは技術的にはヘッダー以上のものではありません。また、要求コンテキスト上のヘッダーマップはで、変更可能なのはです。だからあなたは何かをすることができる

public static class SseCookieFilter implements ClientRequestFilter { 

    @Override 
    public void filter(ClientRequestContext requestContext) throws IOException { 
     Cookie cookie = new Cookie("foo", "bar"); 
     requestContext.getHeaders().add("Cookie", cookie.toString()); 
    } 
} 

フィルタをクライアント(client.register(new SseCookieFilter()))に登録するだけです。あなたがここに

target.(...).request().cookie("foo", "bar"); 

Jersey Test Framework

public class SseCookieFilterTest extends JerseyTest { 

    @Path("events") 
    public static class SseResource { 

     @GET 
     @Produces(SseFeature.SERVER_SENT_EVENTS) 
     public EventOutput getServerSentEvents(@CookieParam("foo") String foo) { 
      final EventOutput eventOutput = new EventOutput(); 
      new Thread(() -> { 
       try { 
        final OutboundEvent.Builder eventBuilder 
          = new OutboundEvent.Builder(); 
        eventBuilder.name("message"); 
        eventBuilder.data(String.class, "Blah " + foo + "!!!"); 
        final OutboundEvent event = eventBuilder.build(); 
        eventOutput.write(event); 

       } catch (IOException e) { 
        throw new RuntimeException(e); 
       } finally { 
        try { 
         eventOutput.close(); 
        } catch (IOException ioClose) { 
         throw new RuntimeException(ioClose); 
        } 
       } 
      }).start(); 
      return eventOutput; 
     } 
    } 

    public static class SseCookieFilter implements ClientRequestFilter { 

     @Override 
     public void filter(ClientRequestContext requestContext) throws IOException { 
      Cookie cookie = new Cookie("foo", "bar"); 
      requestContext.getHeaders().add("Cookie", cookie.toString()); 
     } 
    } 

    @Override 
    public ResourceConfig configure() { 
     return new ResourceConfig(SseResource.class) 
       .register(new LoggingFilter()); 
    } 

    @Test 
    public void doit() throws Exception { 
     Client client = ClientBuilder.newBuilder() 
       .register(SseFeature.class).build(); 
     client.register(new SseCookieFilter()); 
     WebTarget target = client.target("http://localhost:9998/events"); 
     EventSource eventSource = EventSource.target(target).build(); 
     EventListener listener = (InboundEvent inboundEvent) -> { 
      System.out.println("From server ---====++++> " 
        + inboundEvent.readData(String.class)); 
     }; 
     eventSource.register(listener, "message"); 
     eventSource.open(); 
     Thread.sleep(100); 
     eventSource.close(); 
    } 
} 

これらは、ここにある

<dependency> 
    <groupId>org.glassfish.jersey.test-framework.providers</groupId> 
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId> 
    <version>${jersey2.version}</version> 
    <scope>test</scope> 
</dependency> 
<dependency> 
    <groupId>org.glassfish.jersey.media</groupId> 
    <artifactId>jersey-media-sse</artifactId> 
    <version>${jersey2.version}</version> 
    <scope>test</scope> 
</dependency> 

をテストするために必要な依存関係のみです使用して完全な例でやっていたかのように同じ結果になりますサーバー側はLoggingFilterのテストでサーバーに登録しました

INFO: 1 * Server has received a request on thread grizzly-http-server-2 
1 > GET http://localhost:9998/events 
1 > accept: text/event-stream 
1 > connection: close 
1 > cookie: $Version=1;foo=bar 
1 > host: localhost:9998 
1 > user-agent: Jersey/2.19 (HttpUrlConnection 1.8.0_31) 

INFO: 1 * Server responded with a response on thread grizzly-http-server-2 
1 < 200 
1 < Content-Type: text/event-stream 

From server ---====++++> Blah bar!!! 
関連する問題