private DefaultTransportRequest createRequest( SockJsUrlInfo urlInfo, @Nullable HttpHeaders headers, ServerInfo serverInfo) { List<DefaultTransportRequest> requests = new ArrayList<>(this.transports.size()); for (Transport transport : this.transports) { for (TransportType type : transport.getTransportTypes()) { if (serverInfo.isWebSocketEnabled() || !TransportType.WEBSOCKET.equals(type)) { requests.add(new DefaultTransportRequest(urlInfo, headers, getHttpRequestHeaders(headers), transport, type, getMessageCodec())); } } } if (CollectionUtils.isEmpty(requests)) { throw new IllegalStateException( "No transports: " + urlInfo + ", webSocketEnabled=" + serverInfo.isWebSocketEnabled()); } for (int i = 0; i < requests.size() - 1; i++) { DefaultTransportRequest request = requests.get(i); Principal user = getUser(); if (user != null) { request.setUser(user); } if (this.connectTimeoutScheduler != null) { request.setTimeoutValue(serverInfo.getRetransmissionTimeout()); request.setTimeoutScheduler(this.connectTimeoutScheduler); } request.setFallbackRequest(requests.get(i + 1)); } return requests.get(0); }
@Test public void fallbackAfterTimeout() throws Exception { TaskScheduler scheduler = mock(TaskScheduler.class); Runnable sessionCleanupTask = mock(Runnable.class); DefaultTransportRequest request1 = createTransportRequest(this.webSocketTransport, TransportType.WEBSOCKET); DefaultTransportRequest request2 = createTransportRequest(this.xhrTransport, TransportType.XHR_STREAMING); request1.setFallbackRequest(request2); request1.setTimeoutScheduler(scheduler); request1.addTimeoutTask(sessionCleanupTask); request1.connect(null, this.connectFuture); assertTrue(this.webSocketTransport.invoked()); assertFalse(this.xhrTransport.invoked()); // Get and invoke the scheduled timeout task ArgumentCaptor<Runnable> taskCaptor = ArgumentCaptor.forClass(Runnable.class); verify(scheduler).schedule(taskCaptor.capture(), any(Date.class)); verifyNoMoreInteractions(scheduler); taskCaptor.getValue().run(); assertTrue(this.xhrTransport.invoked()); verify(sessionCleanupTask).run(); }
String message = "Connect timed out for " + DefaultTransportRequest.this; logger.error(message); ex = new SockJsTransportFailureException(message, getSockJsUrlInfo().getSessionId(), ex); fallbackRequest.connect(this.handler, this.future);
@Test public void fallbackAfterTransportError() throws Exception { DefaultTransportRequest request1 = createTransportRequest(this.webSocketTransport, TransportType.WEBSOCKET); DefaultTransportRequest request2 = createTransportRequest(this.xhrTransport, TransportType.XHR_STREAMING); request1.setFallbackRequest(request2); request1.connect(null, this.connectFuture); // Transport error => fallback this.webSocketTransport.getConnectCallback().onFailure(new IOException("Fake exception 1")); assertFalse(this.connectFuture.isDone()); assertTrue(this.xhrTransport.invoked()); // Transport error => no more fallback this.xhrTransport.getConnectCallback().onFailure(new IOException("Fake exception 2")); assertTrue(this.connectFuture.isDone()); this.thrown.expect(ExecutionException.class); this.thrown.expectMessage("Fake exception 2"); this.connectFuture.get(); }
@Override public final ListenableFuture<WebSocketSession> doHandshake( WebSocketHandler handler, @Nullable WebSocketHttpHeaders headers, URI url) { Assert.notNull(handler, "WebSocketHandler is required"); Assert.notNull(url, "URL is required"); String scheme = url.getScheme(); if (!supportedProtocols.contains(scheme)) { throw new IllegalArgumentException("Invalid scheme: '" + scheme + "'"); } SettableListenableFuture<WebSocketSession> connectFuture = new SettableListenableFuture<>(); try { SockJsUrlInfo sockJsUrlInfo = new SockJsUrlInfo(url); ServerInfo serverInfo = getServerInfo(sockJsUrlInfo, getHttpRequestHeaders(headers)); createRequest(sockJsUrlInfo, headers, serverInfo).connect(handler, connectFuture); } catch (Throwable exception) { if (logger.isErrorEnabled()) { logger.error("Initial SockJS \"Info\" request to server failed, url=" + url, exception); } connectFuture.setException(exception); } return connectFuture; }
protected DefaultTransportRequest createTransportRequest(Transport transport, TransportType type) throws Exception { SockJsUrlInfo urlInfo = new SockJsUrlInfo(new URI("http://example.com")); return new DefaultTransportRequest(urlInfo, new HttpHeaders(), new HttpHeaders(), transport, type, CODEC); }
public void connect(WebSocketHandler handler, SettableListenableFuture<WebSocketSession> future) { if (logger.isTraceEnabled()) { logger.trace("Starting " + this); } ConnectCallback connectCallback = new ConnectCallback(handler, future); scheduleConnectTimeoutTask(connectCallback); this.transport.connect(this, handler).addCallback(connectCallback); }
@Override public String toString() { return "TransportRequest[url=" + getTransportUrl() + "]"; }
@Test public void connect() throws Exception { DefaultTransportRequest request = createTransportRequest(this.webSocketTransport, TransportType.WEBSOCKET); request.connect(null, this.connectFuture); WebSocketSession session = mock(WebSocketSession.class); this.webSocketTransport.getConnectCallback().onSuccess(session); assertSame(session, this.connectFuture.get()); }
private ListenableFuture<WebSocketSession> connect(RestOperations restTemplate, ClientHttpResponse... responses) throws Exception { RestTemplateXhrTransport transport = new RestTemplateXhrTransport(restTemplate); transport.setTaskExecutor(new SyncTaskExecutor()); SockJsUrlInfo urlInfo = new SockJsUrlInfo(new URI("http://example.com")); HttpHeaders headers = new HttpHeaders(); headers.add("h-foo", "h-bar"); TransportRequest request = new DefaultTransportRequest(urlInfo, headers, headers, transport, TransportType.XHR, CODEC); return transport.connect(request, this.webSocketHandler); }
public void connect(WebSocketHandler handler, SettableListenableFuture<WebSocketSession> future) { if (logger.isTraceEnabled()) { logger.trace("Starting " + this); } ConnectCallback connectCallback = new ConnectCallback(handler, future); scheduleConnectTimeoutTask(connectCallback); this.transport.connect(this, handler).addCallback(connectCallback); }
@Override public String toString() { return "TransportRequest[url=" + getTransportUrl() + "]"; }
private DefaultTransportRequest createRequest( SockJsUrlInfo urlInfo, @Nullable HttpHeaders headers, ServerInfo serverInfo) { List<DefaultTransportRequest> requests = new ArrayList<>(this.transports.size()); for (Transport transport : this.transports) { for (TransportType type : transport.getTransportTypes()) { if (serverInfo.isWebSocketEnabled() || !TransportType.WEBSOCKET.equals(type)) { requests.add(new DefaultTransportRequest(urlInfo, headers, getHttpRequestHeaders(headers), transport, type, getMessageCodec())); } } } if (CollectionUtils.isEmpty(requests)) { throw new IllegalStateException( "No transports: " + urlInfo + ", webSocketEnabled=" + serverInfo.isWebSocketEnabled()); } for (int i = 0; i < requests.size() - 1; i++) { DefaultTransportRequest request = requests.get(i); Principal user = getUser(); if (user != null) { request.setUser(user); } if (this.connectTimeoutScheduler != null) { request.setTimeoutValue(serverInfo.getRetransmissionTimeout()); request.setTimeoutScheduler(this.connectTimeoutScheduler); } request.setFallbackRequest(requests.get(i + 1)); } return requests.get(0); }
String message = "Connect timed out for " + DefaultTransportRequest.this; logger.error(message); ex = new SockJsTransportFailureException(message, getSockJsUrlInfo().getSessionId(), ex); fallbackRequest.connect(this.handler, this.future);
@Override public final ListenableFuture<WebSocketSession> doHandshake( WebSocketHandler handler, @Nullable WebSocketHttpHeaders headers, URI url) { Assert.notNull(handler, "WebSocketHandler is required"); Assert.notNull(url, "URL is required"); String scheme = url.getScheme(); if (!supportedProtocols.contains(scheme)) { throw new IllegalArgumentException("Invalid scheme: '" + scheme + "'"); } SettableListenableFuture<WebSocketSession> connectFuture = new SettableListenableFuture<>(); try { SockJsUrlInfo sockJsUrlInfo = new SockJsUrlInfo(url); ServerInfo serverInfo = getServerInfo(sockJsUrlInfo, getHttpRequestHeaders(headers)); createRequest(sockJsUrlInfo, headers, serverInfo).connect(handler, connectFuture); } catch (Throwable exception) { if (logger.isErrorEnabled()) { logger.error("Initial SockJS \"Info\" request to server failed, url=" + url, exception); } connectFuture.setException(exception); } return connectFuture; }
@Before public void setup() throws Exception { SockJsUrlInfo urlInfo = new SockJsUrlInfo(new URI("http://example.com")); Transport transport = mock(Transport.class); TransportRequest request = new DefaultTransportRequest(urlInfo, null, null, transport, TransportType.XHR, CODEC); this.handler = mock(WebSocketHandler.class); this.connectFuture = new SettableListenableFuture<>(); this.session = new TestClientSockJsSession(request, this.handler, this.connectFuture); }
public void connect(WebSocketHandler handler, SettableListenableFuture<WebSocketSession> future) { if (logger.isTraceEnabled()) { logger.trace("Starting " + this); } ConnectCallback connectCallback = new ConnectCallback(handler, future); scheduleConnectTimeoutTask(connectCallback); this.transport.connect(this, handler).addCallback(connectCallback); }
@Override public String toString() { return "TransportRequest[url=" + getTransportUrl() + "]"; }
private DefaultTransportRequest createRequest( SockJsUrlInfo urlInfo, @Nullable HttpHeaders headers, ServerInfo serverInfo) { List<DefaultTransportRequest> requests = new ArrayList<>(this.transports.size()); for (Transport transport : this.transports) { for (TransportType type : transport.getTransportTypes()) { if (serverInfo.isWebSocketEnabled() || !TransportType.WEBSOCKET.equals(type)) { requests.add(new DefaultTransportRequest(urlInfo, headers, getHttpRequestHeaders(headers), transport, type, getMessageCodec())); } } } if (CollectionUtils.isEmpty(requests)) { throw new IllegalStateException( "No transports: " + urlInfo + ", webSocketEnabled=" + serverInfo.isWebSocketEnabled()); } for (int i = 0; i < requests.size() - 1; i++) { DefaultTransportRequest request = requests.get(i); Principal user = getUser(); if (user != null) { request.setUser(user); } if (this.connectTimeoutScheduler != null) { request.setTimeoutValue(serverInfo.getRetransmissionTimeout()); request.setTimeoutScheduler(this.connectTimeoutScheduler); } request.setFallbackRequest(requests.get(i + 1)); } return requests.get(0); }
String message = "Connect timed out for " + DefaultTransportRequest.this; logger.error(message); ex = new SockJsTransportFailureException(message, getSockJsUrlInfo().getSessionId(), ex); fallbackRequest.connect(this.handler, this.future);