@Test
  @SuppressWarnings("unchecked")
  public void websocketHandlersAttributes() {
    loadBeanDefinitions("websocket-config-handlers-attributes.xml");
    HandlerMapping handlerMapping = appContext.getBean(HandlerMapping.class);
    assertNotNull(handlerMapping);
    assertTrue(handlerMapping instanceof SimpleUrlHandlerMapping);

    SimpleUrlHandlerMapping urlHandlerMapping = (SimpleUrlHandlerMapping) handlerMapping;
    assertEquals(2, urlHandlerMapping.getOrder());

    WebSocketHttpRequestHandler handler =
        (WebSocketHttpRequestHandler) urlHandlerMapping.getUrlMap().get("/foo");
    assertNotNull(handler);
    checkDelegateHandlerType(handler.getWebSocketHandler(), FooWebSocketHandler.class);
    HandshakeHandler handshakeHandler =
        (HandshakeHandler) new DirectFieldAccessor(handler).getPropertyValue("handshakeHandler");
    assertNotNull(handshakeHandler);
    assertTrue(handshakeHandler instanceof TestHandshakeHandler);
    List<HandshakeInterceptor> handshakeInterceptorList =
        (List<HandshakeInterceptor>)
            new DirectFieldAccessor(handler).getPropertyValue("interceptors");
    assertNotNull(handshakeInterceptorList);
    assertThat(
        handshakeInterceptorList,
        Matchers.contains(
            Matchers.instanceOf(FooTestInterceptor.class),
            Matchers.instanceOf(BarTestInterceptor.class)));

    handler = (WebSocketHttpRequestHandler) urlHandlerMapping.getUrlMap().get("/test");
    assertNotNull(handler);
    checkDelegateHandlerType(handler.getWebSocketHandler(), TestWebSocketHandler.class);
    handshakeHandler =
        (HandshakeHandler) new DirectFieldAccessor(handler).getPropertyValue("handshakeHandler");
    assertNotNull(handshakeHandler);
    assertTrue(handshakeHandler instanceof TestHandshakeHandler);
    handshakeInterceptorList =
        (List<HandshakeInterceptor>)
            new DirectFieldAccessor(handler).getPropertyValue("interceptors");
    assertNotNull(handshakeInterceptorList);
    assertThat(
        handshakeInterceptorList,
        Matchers.contains(
            Matchers.instanceOf(FooTestInterceptor.class),
            Matchers.instanceOf(BarTestInterceptor.class)));
  }
  @Test
  public void webSocketHandlers() {
    loadBeanDefinitions("websocket-config-handlers.xml");
    Map<String, HandlerMapping> handlersMap = appContext.getBeansOfType(HandlerMapping.class);
    assertNotNull(handlersMap);
    assertThat(handlersMap.values(), Matchers.hasSize(2));

    for (HandlerMapping handlerMapping : handlersMap.values()) {
      assertTrue(handlerMapping instanceof SimpleUrlHandlerMapping);
      SimpleUrlHandlerMapping urlHandlerMapping = (SimpleUrlHandlerMapping) handlerMapping;

      if (urlHandlerMapping.getUrlMap().keySet().contains("/foo")) {
        assertThat(urlHandlerMapping.getUrlMap().keySet(), Matchers.contains("/foo", "/bar"));
        WebSocketHttpRequestHandler handler =
            (WebSocketHttpRequestHandler) urlHandlerMapping.getUrlMap().get("/foo");
        assertNotNull(handler);
        checkDelegateHandlerType(handler.getWebSocketHandler(), FooWebSocketHandler.class);
        HandshakeHandler handshakeHandler =
            (HandshakeHandler)
                new DirectFieldAccessor(handler).getPropertyValue("handshakeHandler");
        assertNotNull(handshakeHandler);
        assertTrue(handshakeHandler instanceof DefaultHandshakeHandler);
      } else {
        assertThat(urlHandlerMapping.getUrlMap().keySet(), Matchers.contains("/test"));
        WebSocketHttpRequestHandler handler =
            (WebSocketHttpRequestHandler) urlHandlerMapping.getUrlMap().get("/test");
        assertNotNull(handler);
        checkDelegateHandlerType(handler.getWebSocketHandler(), TestWebSocketHandler.class);
        HandshakeHandler handshakeHandler =
            (HandshakeHandler)
                new DirectFieldAccessor(handler).getPropertyValue("handshakeHandler");
        assertNotNull(handshakeHandler);
        assertTrue(handshakeHandler instanceof DefaultHandshakeHandler);
      }
    }
  }
  @Test
  public void simpleBroker() {
    loadBeanDefinitions("websocket-config-broker-simple.xml");

    HandlerMapping hm = this.appContext.getBean(HandlerMapping.class);
    assertThat(hm, Matchers.instanceOf(SimpleUrlHandlerMapping.class));
    SimpleUrlHandlerMapping suhm = (SimpleUrlHandlerMapping) hm;
    assertThat(suhm.getUrlMap().keySet(), Matchers.hasSize(4));
    assertThat(suhm.getUrlMap().values(), Matchers.hasSize(4));

    HttpRequestHandler httpRequestHandler = (HttpRequestHandler) suhm.getUrlMap().get("/foo");
    assertNotNull(httpRequestHandler);
    assertThat(httpRequestHandler, Matchers.instanceOf(WebSocketHttpRequestHandler.class));

    WebSocketHttpRequestHandler wsHttpRequestHandler =
        (WebSocketHttpRequestHandler) httpRequestHandler;
    HandshakeHandler handshakeHandler = wsHttpRequestHandler.getHandshakeHandler();
    assertNotNull(handshakeHandler);
    assertTrue(handshakeHandler instanceof TestHandshakeHandler);
    List<HandshakeInterceptor> interceptors = wsHttpRequestHandler.getHandshakeInterceptors();
    assertThat(
        interceptors,
        contains(instanceOf(FooTestInterceptor.class), instanceOf(BarTestInterceptor.class)));

    WebSocketHandler wsHandler = unwrapWebSocketHandler(wsHttpRequestHandler.getWebSocketHandler());
    assertNotNull(wsHandler);
    assertThat(wsHandler, Matchers.instanceOf(SubProtocolWebSocketHandler.class));

    SubProtocolWebSocketHandler subProtocolWsHandler = (SubProtocolWebSocketHandler) wsHandler;
    assertEquals(
        Arrays.asList("v10.stomp", "v11.stomp", "v12.stomp"),
        subProtocolWsHandler.getSubProtocols());
    assertEquals(25 * 1000, subProtocolWsHandler.getSendTimeLimit());
    assertEquals(1024 * 1024, subProtocolWsHandler.getSendBufferSizeLimit());

    StompSubProtocolHandler stompHandler =
        (StompSubProtocolHandler) subProtocolWsHandler.getProtocolHandlerMap().get("v12.stomp");
    assertNotNull(stompHandler);
    assertEquals(128 * 1024, stompHandler.getMessageSizeLimit());

    assertNotNull(new DirectFieldAccessor(stompHandler).getPropertyValue("eventPublisher"));

    httpRequestHandler = (HttpRequestHandler) suhm.getUrlMap().get("/test/**");
    assertNotNull(httpRequestHandler);
    assertThat(httpRequestHandler, Matchers.instanceOf(SockJsHttpRequestHandler.class));

    SockJsHttpRequestHandler sockJsHttpRequestHandler =
        (SockJsHttpRequestHandler) httpRequestHandler;
    wsHandler = unwrapWebSocketHandler(sockJsHttpRequestHandler.getWebSocketHandler());
    assertNotNull(wsHandler);
    assertThat(wsHandler, Matchers.instanceOf(SubProtocolWebSocketHandler.class));
    assertNotNull(sockJsHttpRequestHandler.getSockJsService());
    assertThat(
        sockJsHttpRequestHandler.getSockJsService(),
        Matchers.instanceOf(DefaultSockJsService.class));

    DefaultSockJsService defaultSockJsService =
        (DefaultSockJsService) sockJsHttpRequestHandler.getSockJsService();
    WebSocketTransportHandler wsTransportHandler =
        (WebSocketTransportHandler)
            defaultSockJsService.getTransportHandlers().get(TransportType.WEBSOCKET);
    assertNotNull(wsTransportHandler.getHandshakeHandler());
    assertThat(
        wsTransportHandler.getHandshakeHandler(), Matchers.instanceOf(TestHandshakeHandler.class));

    ThreadPoolTaskScheduler scheduler =
        (ThreadPoolTaskScheduler) defaultSockJsService.getTaskScheduler();
    assertEquals(
        Runtime.getRuntime().availableProcessors(),
        scheduler.getScheduledThreadPoolExecutor().getCorePoolSize());
    assertTrue(scheduler.getScheduledThreadPoolExecutor().getRemoveOnCancelPolicy());

    interceptors = defaultSockJsService.getHandshakeInterceptors();
    assertThat(
        interceptors,
        contains(instanceOf(FooTestInterceptor.class), instanceOf(BarTestInterceptor.class)));

    UserSessionRegistry userSessionRegistry = this.appContext.getBean(UserSessionRegistry.class);
    assertNotNull(userSessionRegistry);

    UserDestinationResolver userDestResolver =
        this.appContext.getBean(UserDestinationResolver.class);
    assertNotNull(userDestResolver);
    assertThat(userDestResolver, Matchers.instanceOf(DefaultUserDestinationResolver.class));
    DefaultUserDestinationResolver defaultUserDestResolver =
        (DefaultUserDestinationResolver) userDestResolver;
    assertEquals("/personal/", defaultUserDestResolver.getDestinationPrefix());
    assertSame(
        stompHandler.getUserSessionRegistry(), defaultUserDestResolver.getUserSessionRegistry());

    UserDestinationMessageHandler userDestHandler =
        this.appContext.getBean(UserDestinationMessageHandler.class);
    assertNotNull(userDestHandler);

    SimpleBrokerMessageHandler brokerMessageHandler =
        this.appContext.getBean(SimpleBrokerMessageHandler.class);
    assertNotNull(brokerMessageHandler);
    assertEquals(
        Arrays.asList("/topic", "/queue"),
        new ArrayList<String>(brokerMessageHandler.getDestinationPrefixes()));

    List<Class<? extends MessageHandler>> subscriberTypes =
        Arrays.<Class<? extends MessageHandler>>asList(
            SimpAnnotationMethodMessageHandler.class,
            UserDestinationMessageHandler.class,
            SimpleBrokerMessageHandler.class);
    testChannel("clientInboundChannel", subscriberTypes, 0);
    testExecutor(
        "clientInboundChannel",
        Runtime.getRuntime().availableProcessors() * 2,
        Integer.MAX_VALUE,
        60);

    subscriberTypes =
        Arrays.<Class<? extends MessageHandler>>asList(SubProtocolWebSocketHandler.class);
    testChannel("clientOutboundChannel", subscriberTypes, 0);
    testExecutor(
        "clientOutboundChannel",
        Runtime.getRuntime().availableProcessors() * 2,
        Integer.MAX_VALUE,
        60);

    subscriberTypes =
        Arrays.<Class<? extends MessageHandler>>asList(
            SimpleBrokerMessageHandler.class, UserDestinationMessageHandler.class);
    testChannel("brokerChannel", subscriberTypes, 0);
    try {
      this.appContext.getBean("brokerChannelExecutor", ThreadPoolTaskExecutor.class);
      fail("expected exception");
    } catch (NoSuchBeanDefinitionException ex) {
      // expected
    }

    assertNotNull(this.appContext.getBean("webSocketScopeConfigurer", CustomScopeConfigurer.class));

    DirectFieldAccessor subscriptionRegistryAccessor =
        new DirectFieldAccessor(brokerMessageHandler.getSubscriptionRegistry());
    String pathSeparator =
        (String)
            new DirectFieldAccessor(subscriptionRegistryAccessor.getPropertyValue("pathMatcher"))
                .getPropertyValue("pathSeparator");
    assertEquals(".", pathSeparator);
  }