Polishing
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -49,8 +49,7 @@ import org.springframework.util.Assert;
|
|||||||
* @see #setBeforeExistingAdvisors
|
* @see #setBeforeExistingAdvisors
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class AsyncAnnotationBeanPostProcessor extends AbstractAdvisingBeanPostProcessor
|
public class AsyncAnnotationBeanPostProcessor extends AbstractAdvisingBeanPostProcessor implements BeanFactoryAware {
|
||||||
implements BeanFactoryAware {
|
|
||||||
|
|
||||||
private Class<? extends Annotation> asyncAnnotationType;
|
private Class<? extends Annotation> asyncAnnotationType;
|
||||||
|
|
||||||
@@ -61,6 +60,7 @@ public class AsyncAnnotationBeanPostProcessor extends AbstractAdvisingBeanPostPr
|
|||||||
setBeforeExistingAdvisors(true);
|
setBeforeExistingAdvisors(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the 'async' annotation type to be detected at either class or method
|
* Set the 'async' annotation type to be detected at either class or method
|
||||||
* level. By default, both the {@link Async} annotation and the EJB 3.1
|
* level. By default, both the {@link Async} annotation and the EJB 3.1
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -30,18 +30,16 @@ import java.util.concurrent.ExecutionException;
|
|||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public abstract class ListenableFutureAdapter<T, S> extends FutureAdapter<T, S>
|
public abstract class ListenableFutureAdapter<T, S> extends FutureAdapter<T, S> implements ListenableFuture<T> {
|
||||||
implements ListenableFuture<T> {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@code ListenableFutureAdapter} with the given adaptee.
|
* Construct a new {@code ListenableFutureAdapter} with the given adaptee.
|
||||||
* @param adaptee the future to adaptee to
|
* @param adaptee the future to adaptee to
|
||||||
*/
|
*/
|
||||||
protected ListenableFutureAdapter(ListenableFuture<S> adaptee) {
|
protected ListenableFutureAdapter(ListenableFuture<S> adaptee) {
|
||||||
super(adaptee);
|
super(adaptee);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCallback(final ListenableFutureCallback<? super T> callback) {
|
public void addCallback(final ListenableFutureCallback<? super T> callback) {
|
||||||
ListenableFuture<S> listenableAdaptee = (ListenableFuture<S>) getAdaptee();
|
ListenableFuture<S> listenableAdaptee = (ListenableFuture<S>) getAdaptee();
|
||||||
@@ -59,11 +57,11 @@ public abstract class ListenableFutureAdapter<T, S> extends FutureAdapter<T, S>
|
|||||||
onFailure(t);
|
onFailure(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
callback.onFailure(t);
|
callback.onFailure(ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -33,8 +33,8 @@ public interface ListenableFutureCallback<T> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the {@link ListenableFuture} fails to complete.
|
* Called when the {@link ListenableFuture} fails to complete.
|
||||||
* @param t the exception that triggered the failure
|
* @param ex the exception that triggered the failure
|
||||||
*/
|
*/
|
||||||
void onFailure(Throwable t);
|
void onFailure(Throwable ex);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -48,54 +48,52 @@ public class ListenableFutureCallbackRegistry<T> {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void addCallback(ListenableFutureCallback<? super T> callback) {
|
public void addCallback(ListenableFutureCallback<? super T> callback) {
|
||||||
Assert.notNull(callback, "'callback' must not be null");
|
Assert.notNull(callback, "'callback' must not be null");
|
||||||
|
synchronized (this.mutex) {
|
||||||
synchronized (mutex) {
|
switch (this.state) {
|
||||||
switch (state) {
|
|
||||||
case NEW:
|
case NEW:
|
||||||
callbacks.add(callback);
|
this.callbacks.add(callback);
|
||||||
break;
|
break;
|
||||||
case SUCCESS:
|
case SUCCESS:
|
||||||
callback.onSuccess((T)result);
|
callback.onSuccess((T) this.result);
|
||||||
break;
|
break;
|
||||||
case FAILURE:
|
case FAILURE:
|
||||||
callback.onFailure((Throwable) result);
|
callback.onFailure((Throwable) this.result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers a {@link ListenableFutureCallback#onSuccess(Object)} call on all added
|
* Triggers a {@link ListenableFutureCallback#onSuccess(Object)} call on all
|
||||||
* callbacks with the given result
|
* added callbacks with the given result.
|
||||||
* @param result the result to trigger the callbacks with
|
* @param result the result to trigger the callbacks with
|
||||||
*/
|
*/
|
||||||
public void success(T result) {
|
public void success(T result) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
state = State.SUCCESS;
|
this.state = State.SUCCESS;
|
||||||
this.result = result;
|
this.result = result;
|
||||||
|
while (!this.callbacks.isEmpty()) {
|
||||||
while (!callbacks.isEmpty()) {
|
this.callbacks.poll().onSuccess(result);
|
||||||
callbacks.poll().onSuccess(result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers a {@link ListenableFutureCallback#onFailure(Throwable)} call on all added
|
* Triggers a {@link ListenableFutureCallback#onFailure(Throwable)} call on all
|
||||||
* callbacks with the given {@code Throwable}.
|
* added callbacks with the given {@code Throwable}.
|
||||||
* @param t the exception to trigger the callbacks with
|
* @param ex the exception to trigger the callbacks with
|
||||||
*/
|
*/
|
||||||
public void failure(Throwable t) {
|
public void failure(Throwable ex) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
state = State.FAILURE;
|
this.state = State.FAILURE;
|
||||||
this.result = t;
|
this.result = ex;
|
||||||
|
while (!this.callbacks.isEmpty()) {
|
||||||
while (!callbacks.isEmpty()) {
|
this.callbacks.poll().onFailure(ex);
|
||||||
callbacks.poll().onFailure(t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private enum State {NEW, SUCCESS, FAILURE}
|
private enum State {NEW, SUCCESS, FAILURE}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -20,10 +20,10 @@ import java.io.IOException;
|
|||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
*/
|
*/
|
||||||
@@ -44,10 +44,9 @@ public class ListenableFutureTaskTests {
|
|||||||
public void onSuccess(String result) {
|
public void onSuccess(String result) {
|
||||||
assertEquals(s, result);
|
assertEquals(s, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
fail(t.getMessage());
|
fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
task.run();
|
task.run();
|
||||||
@@ -68,15 +67,12 @@ public class ListenableFutureTaskTests {
|
|||||||
public void onSuccess(String result) {
|
public void onSuccess(String result) {
|
||||||
fail("onSuccess not expected");
|
fail("onSuccess not expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
assertEquals(s, t.getMessage());
|
assertEquals(s, ex.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
task.run();
|
task.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ import org.springframework.util.concurrent.ListenableFutureCallback;
|
|||||||
import org.springframework.util.concurrent.ListenableFutureTask;
|
import org.springframework.util.concurrent.ListenableFutureTask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link org.springframework.messaging.MessageHandler} that handles messages by forwarding them to a STOMP broker.
|
* A {@link org.springframework.messaging.MessageHandler} that handles messages by
|
||||||
* For each new {@link SimpMessageType#CONNECT CONNECT} message, an independent TCP
|
* forwarding them to a STOMP broker.
|
||||||
|
*
|
||||||
|
* <p>For each new {@link SimpMessageType#CONNECT CONNECT} message, an independent TCP
|
||||||
* connection to the broker is opened and used exclusively for all messages from the
|
* connection to the broker is opened and used exclusively for all messages from the
|
||||||
* client that originated the CONNECT message. Messages from the same client are
|
* client that originated the CONNECT message. Messages from the same client are
|
||||||
* identified through the session id message header. Reversely, when the STOMP broker
|
* identified through the session id message header. Reversely, when the STOMP broker
|
||||||
@@ -57,10 +59,10 @@ import org.springframework.util.concurrent.ListenableFutureTask;
|
|||||||
* shared and cannot be used to receive messages. Several properties are provided to
|
* shared and cannot be used to receive messages. Several properties are provided to
|
||||||
* configure the "system" connection including:
|
* configure the "system" connection including:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link #setSystemLogin(String)}</li>
|
* <li>{@link #setSystemLogin(String)}</li>
|
||||||
* <li>{@link #setSystemPasscode(String)}</li>
|
* <li>{@link #setSystemPasscode(String)}</li>
|
||||||
* <li>{@link #setSystemHeartbeatSendInterval(long)}</li>
|
* <li>{@link #setSystemHeartbeatSendInterval(long)}</li>
|
||||||
* <li>{@link #setSystemHeartbeatReceiveInterval(long)}</li>
|
* <li>{@link #setSystemHeartbeatReceiveInterval(long)}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
@@ -84,10 +86,11 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
|
|
||||||
private static final Message<byte[]> HEARTBEAT_MESSAGE;
|
private static final Message<byte[]> HEARTBEAT_MESSAGE;
|
||||||
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
EMPTY_TASK.run();
|
||||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.HEARTBEAT);
|
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.HEARTBEAT);
|
||||||
HEARTBEAT_MESSAGE = MessageBuilder.withPayload(new byte[] {'\n'}).setHeaders(headers).build();
|
HEARTBEAT_MESSAGE = MessageBuilder.withPayload(new byte[] {'\n'}).setHeaders(headers).build();
|
||||||
EMPTY_TASK.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -124,7 +127,6 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
/**
|
/**
|
||||||
* Create a StompBrokerRelayMessageHandler instance with the given message channels
|
* Create a StompBrokerRelayMessageHandler instance with the given message channels
|
||||||
* and destination prefixes.
|
* and destination prefixes.
|
||||||
*
|
|
||||||
* @param clientInChannel the channel for receiving messages from clients (e.g. WebSocket clients)
|
* @param clientInChannel the channel for receiving messages from clients (e.g. WebSocket clients)
|
||||||
* @param clientOutChannel the channel for sending messages to clients (e.g. WebSocket clients)
|
* @param clientOutChannel the channel for sending messages to clients (e.g. WebSocket clients)
|
||||||
* @param brokerChannel the channel for the application to send messages to the broker
|
* @param brokerChannel the channel for the application to send messages to the broker
|
||||||
@@ -135,11 +137,9 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
SubscribableChannel brokerChannel, Collection<String> destinationPrefixes) {
|
SubscribableChannel brokerChannel, Collection<String> destinationPrefixes) {
|
||||||
|
|
||||||
super(destinationPrefixes);
|
super(destinationPrefixes);
|
||||||
|
|
||||||
Assert.notNull(clientInChannel, "'clientInChannel' must not be null");
|
Assert.notNull(clientInChannel, "'clientInChannel' must not be null");
|
||||||
Assert.notNull(clientOutChannel, "'clientOutChannel' must not be null");
|
Assert.notNull(clientOutChannel, "'clientOutChannel' must not be null");
|
||||||
Assert.notNull(brokerChannel, "'brokerChannel' must not be null");
|
Assert.notNull(brokerChannel, "'brokerChannel' must not be null");
|
||||||
|
|
||||||
this.clientInboundChannel = clientInChannel;
|
this.clientInboundChannel = clientInChannel;
|
||||||
this.clientOutboundChannel = clientOutChannel;
|
this.clientOutboundChannel = clientOutChannel;
|
||||||
this.brokerChannel = brokerChannel;
|
this.brokerChannel = brokerChannel;
|
||||||
@@ -155,7 +155,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the STOMP message broker host.
|
* Return the STOMP message broker host.
|
||||||
*/
|
*/
|
||||||
public String getRelayHost() {
|
public String getRelayHost() {
|
||||||
return this.relayHost;
|
return this.relayHost;
|
||||||
@@ -169,7 +169,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the STOMP message broker port.
|
* Return the STOMP message broker port.
|
||||||
*/
|
*/
|
||||||
public int getRelayPort() {
|
public int getRelayPort() {
|
||||||
return this.relayPort;
|
return this.relayPort;
|
||||||
@@ -187,7 +187,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The interval, in milliseconds, at which the "system" connection will
|
* Return the interval, in milliseconds, at which the "system" connection will
|
||||||
* send heartbeats to the STOMP broker.
|
* send heartbeats to the STOMP broker.
|
||||||
*/
|
*/
|
||||||
public long getSystemHeartbeatSendInterval() {
|
public long getSystemHeartbeatSendInterval() {
|
||||||
@@ -207,7 +207,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The interval, in milliseconds, at which the "system" connection expects
|
* Return the interval, in milliseconds, at which the "system" connection expects
|
||||||
* to receive heartbeats from the STOMP broker.
|
* to receive heartbeats from the STOMP broker.
|
||||||
*/
|
*/
|
||||||
public long getSystemHeartbeatReceiveInterval() {
|
public long getSystemHeartbeatReceiveInterval() {
|
||||||
@@ -217,8 +217,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
/**
|
/**
|
||||||
* Set the login to use when creating connections to the STOMP broker on
|
* Set the login to use when creating connections to the STOMP broker on
|
||||||
* behalf of connected clients.
|
* behalf of connected clients.
|
||||||
* <p>
|
* <p>By default this is set to "guest".
|
||||||
* By default this is set to "guest".
|
|
||||||
* @see #setSystemLogin(String)
|
* @see #setSystemLogin(String)
|
||||||
*/
|
*/
|
||||||
public void setClientLogin(String clientLogin) {
|
public void setClientLogin(String clientLogin) {
|
||||||
@@ -227,7 +226,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the configured login to use for connections to the STOMP broker
|
* Return the configured login to use for connections to the STOMP broker
|
||||||
* on behalf of connected clients.
|
* on behalf of connected clients.
|
||||||
* @see #getSystemLogin()
|
* @see #getSystemLogin()
|
||||||
*/
|
*/
|
||||||
@@ -236,11 +235,10 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the clientPasscode to use to create connections to the STOMP broker on
|
* Set the client passcode to use to create connections to the STOMP broker on
|
||||||
* behalf of connected clients.
|
* behalf of connected clients.
|
||||||
* <p>
|
* <p>By default this is set to "guest".
|
||||||
* By default this is set to "guest".
|
* @see #setSystemPasscode
|
||||||
* @see #setSystemPasscode(String)
|
|
||||||
*/
|
*/
|
||||||
public void setClientPasscode(String clientPasscode) {
|
public void setClientPasscode(String clientPasscode) {
|
||||||
Assert.hasText(clientPasscode, "clientPasscode must not be empty");
|
Assert.hasText(clientPasscode, "clientPasscode must not be empty");
|
||||||
@@ -248,7 +246,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the configured passocde to use for connections to the STOMP broker on
|
* Return the configured passcode to use for connections to the STOMP broker on
|
||||||
* behalf of connected clients.
|
* behalf of connected clients.
|
||||||
* @see #getSystemPasscode()
|
* @see #getSystemPasscode()
|
||||||
*/
|
*/
|
||||||
@@ -260,8 +258,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
* Set the login for the shared "system" connection used to send messages to
|
* Set the login for the shared "system" connection used to send messages to
|
||||||
* the STOMP broker from within the application, i.e. messages not associated
|
* the STOMP broker from within the application, i.e. messages not associated
|
||||||
* with a specific client session (e.g. REST/HTTP request handling method).
|
* with a specific client session (e.g. REST/HTTP request handling method).
|
||||||
* <p>
|
* <p>By default this is set to "guest".
|
||||||
* By default this is set to "guest".
|
|
||||||
*/
|
*/
|
||||||
public void setSystemLogin(String systemLogin) {
|
public void setSystemLogin(String systemLogin) {
|
||||||
Assert.hasText(systemLogin, "systemLogin must not be empty");
|
Assert.hasText(systemLogin, "systemLogin must not be empty");
|
||||||
@@ -269,7 +266,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the login used for the shared "system" connection to the STOMP broker
|
* Return the login used for the shared "system" connection to the STOMP broker.
|
||||||
*/
|
*/
|
||||||
public String getSystemLogin() {
|
public String getSystemLogin() {
|
||||||
return this.systemLogin;
|
return this.systemLogin;
|
||||||
@@ -279,15 +276,14 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
* Set the passcode for the shared "system" connection used to send messages to
|
* Set the passcode for the shared "system" connection used to send messages to
|
||||||
* the STOMP broker from within the application, i.e. messages not associated
|
* the STOMP broker from within the application, i.e. messages not associated
|
||||||
* with a specific client session (e.g. REST/HTTP request handling method).
|
* with a specific client session (e.g. REST/HTTP request handling method).
|
||||||
* <p>
|
* <p>By default this is set to "guest".
|
||||||
* By default this is set to "guest".
|
|
||||||
*/
|
*/
|
||||||
public void setSystemPasscode(String systemPasscode) {
|
public void setSystemPasscode(String systemPasscode) {
|
||||||
this.systemPasscode = systemPasscode;
|
this.systemPasscode = systemPasscode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the passcode used for the shared "system" connection to the STOMP broker
|
* Return the passcode used for the shared "system" connection to the STOMP broker.
|
||||||
*/
|
*/
|
||||||
public String getSystemPasscode() {
|
public String getSystemPasscode() {
|
||||||
return this.systemPasscode;
|
return this.systemPasscode;
|
||||||
@@ -306,7 +302,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the configured virtual host value.
|
* Return the configured virtual host value.
|
||||||
*/
|
*/
|
||||||
public String getVirtualHost() {
|
public String getVirtualHost() {
|
||||||
return this.virtualHost;
|
return this.virtualHost;
|
||||||
@@ -367,7 +363,6 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void stopInternal() {
|
protected void stopInternal() {
|
||||||
|
|
||||||
publishBrokerUnavailableEvent();
|
publishBrokerUnavailableEvent();
|
||||||
|
|
||||||
this.clientInboundChannel.unsubscribe(this);
|
this.clientInboundChannel.unsubscribe(this);
|
||||||
@@ -376,19 +371,18 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
try {
|
try {
|
||||||
this.tcpClient.shutdown().get(5000, TimeUnit.MILLISECONDS);
|
this.tcpClient.shutdown().get(5000, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Throwable ex) {
|
||||||
logger.error("Error while shutting down TCP client", t);
|
logger.error("Error in shutdown of TCP client", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleMessageInternal(Message<?> message) {
|
protected void handleMessageInternal(Message<?> message) {
|
||||||
|
|
||||||
StompHeaderAccessor headers = StompHeaderAccessor.wrap(message);
|
StompHeaderAccessor headers = StompHeaderAccessor.wrap(message);
|
||||||
String sessionId = headers.getSessionId();
|
String sessionId = headers.getSessionId();
|
||||||
|
|
||||||
if (!isBrokerAvailable()) {
|
if (!isBrokerAvailable()) {
|
||||||
if (sessionId == null || sessionId == SystemStompConnectionHandler.SESSION_ID) {
|
if (sessionId == null || sessionId.equals(SystemStompConnectionHandler.SESSION_ID)) {
|
||||||
throw new MessageDeliveryException("Message broker is not active.");
|
throw new MessageDeliveryException("Message broker is not active.");
|
||||||
}
|
}
|
||||||
if (SimpMessageType.CONNECT.equals(headers.getMessageType()) && logger.isErrorEnabled()) {
|
if (SimpMessageType.CONNECT.equals(headers.getMessageType()) && logger.isErrorEnabled()) {
|
||||||
@@ -418,7 +412,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((command != null) && command.requiresDestination() && !checkDestinationPrefix(destination)) {
|
if (command != null && command.requiresDestination() && !checkDestinationPrefix(destination)) {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("Ignoring message to destination=" + destination);
|
logger.trace("Ignoring message to destination=" + destination);
|
||||||
}
|
}
|
||||||
@@ -482,15 +476,12 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
this(sessionId, connectHeaders, true);
|
this(sessionId, connectHeaders, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StompConnectionHandler(String sessionId, StompHeaderAccessor connectHeaders,
|
private StompConnectionHandler(String sessionId, StompHeaderAccessor connectHeaders, boolean isClientSession) {
|
||||||
boolean isRemoteClientSession) {
|
Assert.notNull(sessionId, "'sessionId' must not be null");
|
||||||
|
Assert.notNull(connectHeaders, "'connectHeaders' must not be null");
|
||||||
Assert.notNull(sessionId, "SessionId must not be null");
|
|
||||||
Assert.notNull(connectHeaders, "ConnectHeaders must not be null");
|
|
||||||
|
|
||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
this.connectHeaders = connectHeaders;
|
this.connectHeaders = connectHeaders;
|
||||||
this.isRemoteClientSession = isRemoteClientSession;
|
this.isRemoteClientSession = isClientSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSessionId() {
|
public String getSessionId() {
|
||||||
@@ -513,7 +504,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when any TCP connectivity issue is detected, i.e. failure to establish
|
* Invoked when any TCP connectivity issue is detected, i.e. failure to establish
|
||||||
* the TCP connection, failure to send a message, missed heartbeat.
|
* the TCP connection, failure to send a message, missed heartbeat, etc.
|
||||||
*/
|
*/
|
||||||
protected void handleTcpConnectionFailure(String errorMessage, Throwable ex) {
|
protected void handleTcpConnectionFailure(String errorMessage, Throwable ex) {
|
||||||
if (logger.isErrorEnabled()) {
|
if (logger.isErrorEnabled()) {
|
||||||
@@ -526,9 +517,9 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
try {
|
try {
|
||||||
clearConnection();
|
clearConnection();
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Throwable ex2) {
|
||||||
if (logger.isErrorEnabled()) {
|
if (logger.isErrorEnabled()) {
|
||||||
logger.error("Failed to close connection: " + t.getMessage());
|
logger.error("Failed to close connection: " + ex2.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -552,7 +543,6 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message<byte[]> message) {
|
public void handleMessage(Message<byte[]> message) {
|
||||||
|
|
||||||
StompHeaderAccessor headers = StompHeaderAccessor.wrap(message);
|
StompHeaderAccessor headers = StompHeaderAccessor.wrap(message);
|
||||||
headers.setSessionId(this.sessionId);
|
headers.setSessionId(this.sessionId);
|
||||||
|
|
||||||
@@ -584,7 +574,6 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initHeartbeats(StompHeaderAccessor connectedHeaders) {
|
private void initHeartbeats(StompHeaderAccessor connectedHeaders) {
|
||||||
|
|
||||||
// Remote clients do their own heartbeat management
|
// Remote clients do their own heartbeat management
|
||||||
if (this.isRemoteClientSession) {
|
if (this.isRemoteClientSession) {
|
||||||
return;
|
return;
|
||||||
@@ -592,11 +581,10 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
|
|
||||||
long clientSendInterval = this.connectHeaders.getHeartbeat()[0];
|
long clientSendInterval = this.connectHeaders.getHeartbeat()[0];
|
||||||
long clientReceiveInterval = this.connectHeaders.getHeartbeat()[1];
|
long clientReceiveInterval = this.connectHeaders.getHeartbeat()[1];
|
||||||
|
|
||||||
long serverSendInterval = connectedHeaders.getHeartbeat()[0];
|
long serverSendInterval = connectedHeaders.getHeartbeat()[0];
|
||||||
long serverReceiveInterval = connectedHeaders.getHeartbeat()[1];
|
long serverReceiveInterval = connectedHeaders.getHeartbeat()[1];
|
||||||
|
|
||||||
if ((clientSendInterval > 0) && (serverReceiveInterval > 0)) {
|
if (clientSendInterval > 0 && serverReceiveInterval > 0) {
|
||||||
long interval = Math.max(clientSendInterval, serverReceiveInterval);
|
long interval = Math.max(clientSendInterval, serverReceiveInterval);
|
||||||
this.tcpConnection.onWriteInactivity(new Runnable() {
|
this.tcpConnection.onWriteInactivity(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -605,10 +593,11 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
conn.send(HEARTBEAT_MESSAGE).addCallback(
|
conn.send(HEARTBEAT_MESSAGE).addCallback(
|
||||||
new ListenableFutureCallback<Void>() {
|
new ListenableFutureCallback<Void>() {
|
||||||
public void onFailure(Throwable t) {
|
public void onSuccess(Void result) {
|
||||||
handleTcpConnectionFailure("Failed to send heartbeat", t);
|
}
|
||||||
|
public void onFailure(Throwable ex) {
|
||||||
|
handleTcpConnectionFailure("Failed to send heartbeat", ex);
|
||||||
}
|
}
|
||||||
public void onSuccess(Void result) {}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -620,8 +609,8 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
this.tcpConnection.onReadInactivity(new Runnable() {
|
this.tcpConnection.onReadInactivity(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
handleTcpConnectionFailure("No hearbeat from broker for more than " +
|
handleTcpConnectionFailure("No heartbeat from broker for more than " + interval +
|
||||||
interval + "ms, closing connection", null);
|
"ms, closing connection", null);
|
||||||
}
|
}
|
||||||
}, interval);
|
}, interval);
|
||||||
}
|
}
|
||||||
@@ -652,17 +641,14 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
this.tcpConnection = null;
|
this.tcpConnection = null;
|
||||||
clearConnection();
|
clearConnection();
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Throwable ex) {
|
||||||
if (logger.isErrorEnabled()) {
|
// Shouldn't happen with connection reset beforehand
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forward the given message to the STOMP broker.
|
* Forward the given message to the STOMP broker.
|
||||||
*
|
|
||||||
* <p>The method checks whether we have an active TCP connection and have
|
* <p>The method checks whether we have an active TCP connection and have
|
||||||
* received the STOMP CONNECTED frame. For client messages this should be
|
* received the STOMP CONNECTED frame. For client messages this should be
|
||||||
* false only if we lose the TCP connection around the same time when a
|
* false only if we lose the TCP connection around the same time when a
|
||||||
@@ -671,7 +657,6 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
* the "system" connection an exception is raised so that components sending
|
* the "system" connection an exception is raised so that components sending
|
||||||
* the message have a chance to handle it -- by default the broker message
|
* the message have a chance to handle it -- by default the broker message
|
||||||
* channel is synchronous.
|
* channel is synchronous.
|
||||||
*
|
|
||||||
* <p>Note that if messages arrive concurrently around the same time a TCP
|
* <p>Note that if messages arrive concurrently around the same time a TCP
|
||||||
* connection is lost, there is a brief period of time before the connection
|
* connection is lost, there is a brief period of time before the connection
|
||||||
* is reset when one or more messages may sneak through and an attempt made
|
* is reset when one or more messages may sneak through and an attempt made
|
||||||
@@ -679,13 +664,11 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
* method simply lets them try and fail. For client sessions that may
|
* method simply lets them try and fail. For client sessions that may
|
||||||
* result in an additional STOMP ERROR frame(s) being sent downstream but
|
* result in an additional STOMP ERROR frame(s) being sent downstream but
|
||||||
* code handling that downstream should be idempotent in such cases.
|
* code handling that downstream should be idempotent in such cases.
|
||||||
*
|
* @param message the message to send (never {@code null})
|
||||||
* @param message the message to send, never {@code null}
|
|
||||||
* @return a future to wait for the result
|
* @return a future to wait for the result
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public ListenableFuture<Void> forward(final Message<?> message) {
|
public ListenableFuture<Void> forward(final Message<?> message) {
|
||||||
|
|
||||||
TcpConnection<byte[]> conn = this.tcpConnection;
|
TcpConnection<byte[]> conn = this.tcpConnection;
|
||||||
|
|
||||||
if (!this.isStompConnected) {
|
if (!this.isStompConnected) {
|
||||||
@@ -725,12 +708,12 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
if (tcpConnection == null) {
|
if (tcpConnection == null) {
|
||||||
// already reset
|
// already reset
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
handleTcpConnectionFailure("Failed to send message " + message, t);
|
handleTcpConnectionFailure("Failed to send message " + message, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -742,13 +725,11 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
* Close the TCP connection to the broker and release the connection reference,
|
* Close the TCP connection to the broker and release the connection reference,
|
||||||
* Any exception arising from closing the connection is propagated. The caller
|
* Any exception arising from closing the connection is propagated. The caller
|
||||||
* must handle and log the exception accordingly.
|
* must handle and log the exception accordingly.
|
||||||
*
|
|
||||||
* <p>If the connection belongs to a client session, the connection handler
|
* <p>If the connection belongs to a client session, the connection handler
|
||||||
* for the session (basically the current instance) is also released from the
|
* for the session (basically the current instance) is also released from the
|
||||||
* {@link org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler}.
|
* {@link org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler}.
|
||||||
*/
|
*/
|
||||||
public void clearConnection() {
|
public void clearConnection() {
|
||||||
|
|
||||||
if (this.isRemoteClientSession) {
|
if (this.isRemoteClientSession) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Removing session '" + sessionId + "' (total remaining=" +
|
logger.debug("Removing session '" + sessionId + "' (total remaining=" +
|
||||||
@@ -772,11 +753,11 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class SystemStompConnectionHandler extends StompConnectionHandler {
|
private class SystemStompConnectionHandler extends StompConnectionHandler {
|
||||||
|
|
||||||
public static final String SESSION_ID = "stompRelaySystemSessionId";
|
public static final String SESSION_ID = "stompRelaySystemSessionId";
|
||||||
|
|
||||||
|
|
||||||
public SystemStompConnectionHandler(StompHeaderAccessor connectHeaders) {
|
public SystemStompConnectionHandler(StompHeaderAccessor connectHeaders) {
|
||||||
super(SESSION_ID, connectHeaders, false);
|
super(SESSION_ID, connectHeaders, false);
|
||||||
}
|
}
|
||||||
@@ -788,8 +769,8 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleTcpConnectionFailure(String errorMessage, Throwable t) {
|
protected void handleTcpConnectionFailure(String errorMessage, Throwable ex) {
|
||||||
super.handleTcpConnectionFailure(errorMessage, t);
|
super.handleTcpConnectionFailure(errorMessage, ex);
|
||||||
publishBrokerUnavailableEvent();
|
publishBrokerUnavailableEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -806,12 +787,13 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
future.get();
|
future.get();
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Throwable ex) {
|
||||||
throw new MessageDeliveryException(message, t);
|
throw new MessageDeliveryException(message, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class Reactor11TcpClientFactory {
|
private static class Reactor11TcpClientFactory {
|
||||||
|
|
||||||
public TcpOperations<byte[]> create(String host, int port) {
|
public TcpOperations<byte[]> create(String host, int port) {
|
||||||
@@ -820,6 +802,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class Reactor10TcpClientFactory {
|
private static class Reactor10TcpClientFactory {
|
||||||
|
|
||||||
public TcpOperations<byte[]> create(String host, int port) {
|
public TcpOperations<byte[]> create(String host, int port) {
|
||||||
@@ -828,6 +811,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class VoidCallable implements Callable<Void> {
|
private static class VoidCallable implements Callable<Void> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -88,8 +88,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
*/
|
*/
|
||||||
public AsyncRestTemplate(AsyncListenableTaskExecutor taskExecutor) {
|
public AsyncRestTemplate(AsyncListenableTaskExecutor taskExecutor) {
|
||||||
Assert.notNull(taskExecutor, "AsyncTaskExecutor must not be null");
|
Assert.notNull(taskExecutor, "AsyncTaskExecutor must not be null");
|
||||||
SimpleClientHttpRequestFactory requestFactory =
|
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
|
||||||
new SimpleClientHttpRequestFactory();
|
|
||||||
requestFactory.setTaskExecutor(taskExecutor);
|
requestFactory.setTaskExecutor(taskExecutor);
|
||||||
this.syncTemplate = new RestTemplate(requestFactory);
|
this.syncTemplate = new RestTemplate(requestFactory);
|
||||||
setAsyncRequestFactory(requestFactory);
|
setAsyncRequestFactory(requestFactory);
|
||||||
@@ -114,8 +113,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
* @param asyncRequestFactory the asynchronous request factory
|
* @param asyncRequestFactory the asynchronous request factory
|
||||||
* @param syncRequestFactory the synchronous request factory
|
* @param syncRequestFactory the synchronous request factory
|
||||||
*/
|
*/
|
||||||
public AsyncRestTemplate(AsyncClientHttpRequestFactory asyncRequestFactory,
|
public AsyncRestTemplate(AsyncClientHttpRequestFactory asyncRequestFactory, ClientHttpRequestFactory syncRequestFactory) {
|
||||||
ClientHttpRequestFactory syncRequestFactory) {
|
|
||||||
this(asyncRequestFactory, new RestTemplate(syncRequestFactory));
|
this(asyncRequestFactory, new RestTemplate(syncRequestFactory));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,8 +123,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
* @param requestFactory the asynchronous request factory to use
|
* @param requestFactory the asynchronous request factory to use
|
||||||
* @param restTemplate the synchronous template to use
|
* @param restTemplate the synchronous template to use
|
||||||
*/
|
*/
|
||||||
public AsyncRestTemplate(AsyncClientHttpRequestFactory requestFactory,
|
public AsyncRestTemplate(AsyncClientHttpRequestFactory requestFactory, RestTemplate restTemplate) {
|
||||||
RestTemplate restTemplate) {
|
|
||||||
Assert.notNull(restTemplate, "'restTemplate' must not be null");
|
Assert.notNull(restTemplate, "'restTemplate' must not be null");
|
||||||
this.syncTemplate = restTemplate;
|
this.syncTemplate = restTemplate;
|
||||||
setAsyncRequestFactory(requestFactory);
|
setAsyncRequestFactory(requestFactory);
|
||||||
@@ -195,6 +192,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
return execute(url, HttpMethod.GET, requestCallback, responseExtractor);
|
return execute(url, HttpMethod.GET, requestCallback, responseExtractor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// HEAD
|
// HEAD
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -218,30 +216,29 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
// POST
|
// POST
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<URI> postForLocation(String url, HttpEntity<?> request,
|
public ListenableFuture<URI> postForLocation(String url, HttpEntity<?> request, Object... uriVariables)
|
||||||
Object... uriVariables) throws RestClientException {
|
|
||||||
AsyncRequestCallback requestCallback = httpEntityCallback(request);
|
|
||||||
ResponseExtractor<HttpHeaders> headersExtractor = headersExtractor();
|
|
||||||
ListenableFuture<HttpHeaders> headersFuture =
|
|
||||||
execute(url, HttpMethod.POST, requestCallback, headersExtractor,
|
|
||||||
uriVariables);
|
|
||||||
return extractLocationHeader(headersFuture);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ListenableFuture<URI> postForLocation(String url, HttpEntity<?> request,
|
|
||||||
Map<String, ?> uriVariables) throws RestClientException {
|
|
||||||
AsyncRequestCallback requestCallback = httpEntityCallback(request);
|
|
||||||
ResponseExtractor<HttpHeaders> headersExtractor = headersExtractor();
|
|
||||||
ListenableFuture<HttpHeaders> headersFuture =
|
|
||||||
execute(url, HttpMethod.POST, requestCallback, headersExtractor,
|
|
||||||
uriVariables);
|
|
||||||
return extractLocationHeader(headersFuture);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ListenableFuture<URI> postForLocation(URI url, HttpEntity<?> request)
|
|
||||||
throws RestClientException {
|
throws RestClientException {
|
||||||
|
|
||||||
|
AsyncRequestCallback requestCallback = httpEntityCallback(request);
|
||||||
|
ResponseExtractor<HttpHeaders> headersExtractor = headersExtractor();
|
||||||
|
ListenableFuture<HttpHeaders> headersFuture =
|
||||||
|
execute(url, HttpMethod.POST, requestCallback, headersExtractor, uriVariables);
|
||||||
|
return extractLocationHeader(headersFuture);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<URI> postForLocation(String url, HttpEntity<?> request, Map<String, ?> uriVariables)
|
||||||
|
throws RestClientException {
|
||||||
|
|
||||||
|
AsyncRequestCallback requestCallback = httpEntityCallback(request);
|
||||||
|
ResponseExtractor<HttpHeaders> headersExtractor = headersExtractor();
|
||||||
|
ListenableFuture<HttpHeaders> headersFuture =
|
||||||
|
execute(url, HttpMethod.POST, requestCallback, headersExtractor, uriVariables);
|
||||||
|
return extractLocationHeader(headersFuture);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<URI> postForLocation(URI url, HttpEntity<?> request) throws RestClientException {
|
||||||
AsyncRequestCallback requestCallback = httpEntityCallback(request);
|
AsyncRequestCallback requestCallback = httpEntityCallback(request);
|
||||||
ResponseExtractor<HttpHeaders> headersExtractor = headersExtractor();
|
ResponseExtractor<HttpHeaders> headersExtractor = headersExtractor();
|
||||||
ListenableFuture<HttpHeaders> headersFuture =
|
ListenableFuture<HttpHeaders> headersFuture =
|
||||||
@@ -251,7 +248,6 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
|
|
||||||
private static ListenableFuture<URI> extractLocationHeader(final ListenableFuture<HttpHeaders> headersFuture) {
|
private static ListenableFuture<URI> extractLocationHeader(final ListenableFuture<HttpHeaders> headersFuture) {
|
||||||
return new ListenableFuture<URI>() {
|
return new ListenableFuture<URI>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCallback(final ListenableFutureCallback<? super URI> callback) {
|
public void addCallback(final ListenableFutureCallback<? super URI> callback) {
|
||||||
headersFuture.addCallback(new ListenableFutureCallback<HttpHeaders>() {
|
headersFuture.addCallback(new ListenableFutureCallback<HttpHeaders>() {
|
||||||
@@ -259,14 +255,12 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
public void onSuccess(HttpHeaders result) {
|
public void onSuccess(HttpHeaders result) {
|
||||||
callback.onSuccess(result.getLocation());
|
callback.onSuccess(result.getLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
callback.onFailure(t);
|
callback.onFailure(ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||||
return headersFuture.cancel(mayInterruptIfRunning);
|
return headersFuture.cancel(mayInterruptIfRunning);
|
||||||
@@ -285,8 +279,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
return headers.getLocation();
|
return headers.getLocation();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public URI get(long timeout, TimeUnit unit)
|
public URI get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
HttpHeaders headers = headersFuture.get(timeout, unit);
|
HttpHeaders headers = headersFuture.get(timeout, unit);
|
||||||
return headers.getLocation();
|
return headers.getLocation();
|
||||||
}
|
}
|
||||||
@@ -296,45 +289,41 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
@Override
|
@Override
|
||||||
public <T> ListenableFuture<ResponseEntity<T>> postForEntity(String url, HttpEntity<?> request,
|
public <T> ListenableFuture<ResponseEntity<T>> postForEntity(String url, HttpEntity<?> request,
|
||||||
Class<T> responseType, Object... uriVariables) throws RestClientException {
|
Class<T> responseType, Object... uriVariables) throws RestClientException {
|
||||||
|
|
||||||
AsyncRequestCallback requestCallback = httpEntityCallback(request, responseType);
|
AsyncRequestCallback requestCallback = httpEntityCallback(request, responseType);
|
||||||
ResponseExtractor<ResponseEntity<T>> responseExtractor =
|
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
|
||||||
responseEntityExtractor(responseType);
|
return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
|
||||||
return execute(url, HttpMethod.POST, requestCallback, responseExtractor,
|
|
||||||
uriVariables);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> ListenableFuture<ResponseEntity<T>> postForEntity(String url, HttpEntity<?> request,
|
public <T> ListenableFuture<ResponseEntity<T>> postForEntity(String url, HttpEntity<?> request,
|
||||||
Class<T> responseType, Map<String, ?> uriVariables)
|
Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
|
||||||
throws RestClientException {
|
|
||||||
AsyncRequestCallback requestCallback = httpEntityCallback(request, responseType);
|
AsyncRequestCallback requestCallback = httpEntityCallback(request, responseType);
|
||||||
ResponseExtractor<ResponseEntity<T>> responseExtractor =
|
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
|
||||||
responseEntityExtractor(responseType);
|
return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
|
||||||
return execute(url, HttpMethod.POST, requestCallback, responseExtractor,
|
|
||||||
uriVariables);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> ListenableFuture<ResponseEntity<T>> postForEntity(URI url, HttpEntity<?> request,
|
public <T> ListenableFuture<ResponseEntity<T>> postForEntity(URI url, HttpEntity<?> request, Class<T> responseType)
|
||||||
Class<T> responseType) throws RestClientException {
|
throws RestClientException {
|
||||||
|
|
||||||
AsyncRequestCallback requestCallback = httpEntityCallback(request, responseType);
|
AsyncRequestCallback requestCallback = httpEntityCallback(request, responseType);
|
||||||
ResponseExtractor<ResponseEntity<T>> responseExtractor =
|
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
|
||||||
responseEntityExtractor(responseType);
|
|
||||||
return execute(url, HttpMethod.POST, requestCallback, responseExtractor);
|
return execute(url, HttpMethod.POST, requestCallback, responseExtractor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// PUT
|
// PUT
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<?> put(String url, HttpEntity<?> request, Object... uriVariables)
|
public ListenableFuture<?> put(String url, HttpEntity<?> request, Object... uriVariables) throws RestClientException {
|
||||||
throws RestClientException {
|
|
||||||
AsyncRequestCallback requestCallback = httpEntityCallback(request);
|
AsyncRequestCallback requestCallback = httpEntityCallback(request);
|
||||||
return execute(url, HttpMethod.PUT, requestCallback, null, uriVariables);
|
return execute(url, HttpMethod.PUT, requestCallback, null, uriVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<?> put(String url, HttpEntity<?> request,
|
public ListenableFuture<?> put(String url, HttpEntity<?> request, Map<String, ?> uriVariables) throws RestClientException {
|
||||||
Map<String, ?> uriVariables) throws RestClientException {
|
|
||||||
AsyncRequestCallback requestCallback = httpEntityCallback(request);
|
AsyncRequestCallback requestCallback = httpEntityCallback(request);
|
||||||
return execute(url, HttpMethod.PUT, requestCallback, null, uriVariables);
|
return execute(url, HttpMethod.PUT, requestCallback, null, uriVariables);
|
||||||
}
|
}
|
||||||
@@ -345,17 +334,16 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
return execute(url, HttpMethod.PUT, requestCallback, null);
|
return execute(url, HttpMethod.PUT, requestCallback, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// DELETE
|
// DELETE
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<?> delete(String url, Object... urlVariables)
|
public ListenableFuture<?> delete(String url, Object... urlVariables) throws RestClientException {
|
||||||
throws RestClientException {
|
|
||||||
return execute(url, HttpMethod.DELETE, null, null, urlVariables);
|
return execute(url, HttpMethod.DELETE, null, null, urlVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<?> delete(String url, Map<String, ?> urlVariables)
|
public ListenableFuture<?> delete(String url, Map<String, ?> urlVariables) throws RestClientException {
|
||||||
throws RestClientException {
|
|
||||||
return execute(url, HttpMethod.DELETE, null, null, urlVariables);
|
return execute(url, HttpMethod.DELETE, null, null, urlVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,6 +352,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
return execute(url, HttpMethod.DELETE, null, null);
|
return execute(url, HttpMethod.DELETE, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// OPTIONS
|
// OPTIONS
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -389,23 +378,19 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
|
|
||||||
private static ListenableFuture<Set<HttpMethod>> extractAllowHeader(final ListenableFuture<HttpHeaders> headersFuture) {
|
private static ListenableFuture<Set<HttpMethod>> extractAllowHeader(final ListenableFuture<HttpHeaders> headersFuture) {
|
||||||
return new ListenableFuture<Set<HttpMethod>>() {
|
return new ListenableFuture<Set<HttpMethod>>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCallback(
|
public void addCallback(final ListenableFutureCallback<? super Set<HttpMethod>> callback) {
|
||||||
final ListenableFutureCallback<? super Set<HttpMethod>> callback) {
|
|
||||||
headersFuture.addCallback(new ListenableFutureCallback<HttpHeaders>() {
|
headersFuture.addCallback(new ListenableFutureCallback<HttpHeaders>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(HttpHeaders result) {
|
public void onSuccess(HttpHeaders result) {
|
||||||
callback.onSuccess(result.getAllow());
|
callback.onSuccess(result.getAllow());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
callback.onFailure(t);
|
callback.onFailure(ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||||
return headersFuture.cancel(mayInterruptIfRunning);
|
return headersFuture.cancel(mayInterruptIfRunning);
|
||||||
@@ -424,8 +409,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
return headers.getAllow();
|
return headers.getAllow();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public Set<HttpMethod> get(long timeout, TimeUnit unit)
|
public Set<HttpMethod> get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
HttpHeaders headers = headersFuture.get(timeout, unit);
|
HttpHeaders headers = headersFuture.get(timeout, unit);
|
||||||
return headers.getAllow();
|
return headers.getAllow();
|
||||||
}
|
}
|
||||||
@@ -436,68 +420,59 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
// exchange
|
// exchange
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method,
|
public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
|
||||||
HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables)
|
Class<T> responseType, Object... uriVariables) throws RestClientException {
|
||||||
throws RestClientException {
|
|
||||||
AsyncRequestCallback requestCallback =
|
AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);
|
||||||
httpEntityCallback(requestEntity, responseType);
|
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
|
||||||
ResponseExtractor<ResponseEntity<T>> responseExtractor =
|
|
||||||
responseEntityExtractor(responseType);
|
|
||||||
return execute(url, method, requestCallback, responseExtractor, uriVariables);
|
return execute(url, method, requestCallback, responseExtractor, uriVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method,
|
public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
|
||||||
HttpEntity<?> requestEntity, Class<T> responseType,
|
Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
|
||||||
Map<String, ?> uriVariables) throws RestClientException {
|
|
||||||
AsyncRequestCallback requestCallback =
|
AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);
|
||||||
httpEntityCallback(requestEntity, responseType);
|
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
|
||||||
ResponseExtractor<ResponseEntity<T>> responseExtractor =
|
|
||||||
responseEntityExtractor(responseType);
|
|
||||||
return execute(url, method, requestCallback, responseExtractor, uriVariables);
|
return execute(url, method, requestCallback, responseExtractor, uriVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> ListenableFuture<ResponseEntity<T>> exchange(URI url, HttpMethod method,
|
public <T> ListenableFuture<ResponseEntity<T>> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
|
||||||
HttpEntity<?> requestEntity, Class<T> responseType)
|
Class<T> responseType) throws RestClientException {
|
||||||
throws RestClientException {
|
|
||||||
AsyncRequestCallback requestCallback =
|
AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);
|
||||||
httpEntityCallback(requestEntity, responseType);
|
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
|
||||||
ResponseExtractor<ResponseEntity<T>> responseExtractor =
|
|
||||||
responseEntityExtractor(responseType);
|
|
||||||
return execute(url, method, requestCallback, responseExtractor);
|
return execute(url, method, requestCallback, responseExtractor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method,
|
public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
|
||||||
HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType,
|
ParameterizedTypeReference<T> responseType, Object... uriVariables) throws RestClientException {
|
||||||
Object... uriVariables) throws RestClientException {
|
|
||||||
Type type = responseType.getType();
|
Type type = responseType.getType();
|
||||||
AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, type);
|
AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, type);
|
||||||
ResponseExtractor<ResponseEntity<T>> responseExtractor =
|
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(type);
|
||||||
responseEntityExtractor(type);
|
|
||||||
return execute(url, method, requestCallback, responseExtractor, uriVariables);
|
return execute(url, method, requestCallback, responseExtractor, uriVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method,
|
public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
|
||||||
HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType,
|
ParameterizedTypeReference<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
|
||||||
Map<String, ?> uriVariables) throws RestClientException {
|
|
||||||
Type type = responseType.getType();
|
Type type = responseType.getType();
|
||||||
AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, type);
|
AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, type);
|
||||||
ResponseExtractor<ResponseEntity<T>> responseExtractor =
|
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(type);
|
||||||
responseEntityExtractor(type);
|
|
||||||
return execute(url, method, requestCallback, responseExtractor, uriVariables);
|
return execute(url, method, requestCallback, responseExtractor, uriVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> ListenableFuture<ResponseEntity<T>> exchange(URI url, HttpMethod method,
|
public <T> ListenableFuture<ResponseEntity<T>> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
|
||||||
HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType)
|
ParameterizedTypeReference<T> responseType) throws RestClientException {
|
||||||
throws RestClientException {
|
|
||||||
Type type = responseType.getType();
|
Type type = responseType.getType();
|
||||||
AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, type);
|
AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, type);
|
||||||
ResponseExtractor<ResponseEntity<T>> responseExtractor =
|
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(type);
|
||||||
responseEntityExtractor(type);
|
|
||||||
return execute(url, method, requestCallback, responseExtractor);
|
return execute(url, method, requestCallback, responseExtractor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,27 +480,24 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
// general execution
|
// general execution
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> ListenableFuture<T> execute(String url, HttpMethod method,
|
public <T> ListenableFuture<T> execute(String url, HttpMethod method, AsyncRequestCallback requestCallback,
|
||||||
AsyncRequestCallback requestCallback, ResponseExtractor<T> responseExtractor,
|
ResponseExtractor<T> responseExtractor, Object... urlVariables) throws RestClientException {
|
||||||
Object... urlVariables) throws RestClientException {
|
|
||||||
|
|
||||||
URI expanded = new UriTemplate(url).expand(urlVariables);
|
URI expanded = new UriTemplate(url).expand(urlVariables);
|
||||||
return doExecute(expanded, method, requestCallback, responseExtractor);
|
return doExecute(expanded, method, requestCallback, responseExtractor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> ListenableFuture<T> execute(String url, HttpMethod method,
|
public <T> ListenableFuture<T> execute(String url, HttpMethod method, AsyncRequestCallback requestCallback,
|
||||||
AsyncRequestCallback requestCallback, ResponseExtractor<T> responseExtractor,
|
ResponseExtractor<T> responseExtractor, Map<String, ?> urlVariables) throws RestClientException {
|
||||||
Map<String, ?> urlVariables) throws RestClientException {
|
|
||||||
|
|
||||||
URI expanded = new UriTemplate(url).expand(urlVariables);
|
URI expanded = new UriTemplate(url).expand(urlVariables);
|
||||||
return doExecute(expanded, method, requestCallback, responseExtractor);
|
return doExecute(expanded, method, requestCallback, responseExtractor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> ListenableFuture<T> execute(URI url, HttpMethod method,
|
public <T> ListenableFuture<T> execute(URI url, HttpMethod method, AsyncRequestCallback requestCallback,
|
||||||
AsyncRequestCallback requestCallback, ResponseExtractor<T> responseExtractor)
|
ResponseExtractor<T> responseExtractor) throws RestClientException {
|
||||||
throws RestClientException {
|
|
||||||
|
|
||||||
return doExecute(url, method, requestCallback, responseExtractor);
|
return doExecute(url, method, requestCallback, responseExtractor);
|
||||||
}
|
}
|
||||||
@@ -553,8 +525,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
requestCallback.doWithRequest(request);
|
requestCallback.doWithRequest(request);
|
||||||
}
|
}
|
||||||
ListenableFuture<ClientHttpResponse> responseFuture = request.executeAsync();
|
ListenableFuture<ClientHttpResponse> responseFuture = request.executeAsync();
|
||||||
return new ResponseExtractorFuture<T>(method, url, responseFuture,
|
return new ResponseExtractorFuture<T>(method, url, responseFuture, responseExtractor);
|
||||||
responseExtractor);
|
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
throw new ResourceAccessException("I/O error on " + method.name() +
|
throw new ResourceAccessException("I/O error on " + method.name() +
|
||||||
@@ -565,9 +536,8 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
private void logResponseStatus(HttpMethod method, URI url, ClientHttpResponse response) {
|
private void logResponseStatus(HttpMethod method, URI url, ClientHttpResponse response) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
try {
|
try {
|
||||||
logger.debug("Async " + method.name() + " request for \"" + url +
|
logger.debug("Async " + method.name() + " request for \"" + url + "\" resulted in " +
|
||||||
"\" resulted in " + response.getStatusCode() + " (" +
|
response.getStatusCode() + " (" + response.getStatusText() + ")");
|
||||||
response.getStatusText() + ")");
|
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
// ignore
|
// ignore
|
||||||
@@ -578,9 +548,8 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
private void handleResponseError(HttpMethod method, URI url, ClientHttpResponse response) throws IOException {
|
private void handleResponseError(HttpMethod method, URI url, ClientHttpResponse response) throws IOException {
|
||||||
if (logger.isWarnEnabled()) {
|
if (logger.isWarnEnabled()) {
|
||||||
try {
|
try {
|
||||||
logger.warn("Async " + method.name() + " request for \"" + url +
|
logger.warn("Async " + method.name() + " request for \"" + url + "\" resulted in " +
|
||||||
"\" resulted in " + response.getStatusCode() + " (" +
|
response.getStatusCode() + " (" + response.getStatusText() + "); invoking error handler");
|
||||||
response.getStatusText() + "); invoking error handler");
|
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
// ignore
|
// ignore
|
||||||
@@ -628,12 +597,12 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
return this.syncTemplate.headersExtractor();
|
return this.syncTemplate.headersExtractor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Future returned from
|
* Future returned from
|
||||||
* {@link #doExecute(URI, HttpMethod, AsyncRequestCallback, ResponseExtractor)}
|
* {@link #doExecute(URI, HttpMethod, AsyncRequestCallback, ResponseExtractor)}
|
||||||
*/
|
*/
|
||||||
private class ResponseExtractorFuture<T>
|
private class ResponseExtractorFuture<T> extends ListenableFutureAdapter<T, ClientHttpResponse> {
|
||||||
extends ListenableFutureAdapter<T, ClientHttpResponse> {
|
|
||||||
|
|
||||||
private final HttpMethod method;
|
private final HttpMethod method;
|
||||||
|
|
||||||
@@ -642,8 +611,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
private final ResponseExtractor<T> responseExtractor;
|
private final ResponseExtractor<T> responseExtractor;
|
||||||
|
|
||||||
public ResponseExtractorFuture(HttpMethod method, URI url,
|
public ResponseExtractorFuture(HttpMethod method, URI url,
|
||||||
ListenableFuture<ClientHttpResponse> clientHttpResponseFuture,
|
ListenableFuture<ClientHttpResponse> clientHttpResponseFuture, ResponseExtractor<T> responseExtractor) {
|
||||||
ResponseExtractor<T> responseExtractor) {
|
|
||||||
super(clientHttpResponseFuture);
|
super(clientHttpResponseFuture);
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
@@ -672,12 +640,11 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected T convertResponse(ClientHttpResponse response) throws IOException {
|
protected T convertResponse(ClientHttpResponse response) throws IOException {
|
||||||
return responseExtractor != null ? responseExtractor.extractData(response) :
|
return (this.responseExtractor != null ? this.responseExtractor.extractData(response) : null);
|
||||||
null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapts a {@link RequestCallback} to the {@link AsyncRequestCallback} interface.
|
* Adapts a {@link RequestCallback} to the {@link AsyncRequestCallback} interface.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ import org.springframework.util.concurrent.ListenableFutureCallback;
|
|||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public abstract class AbstractAsyncHttpRequestFactoryTestCase extends
|
public abstract class AbstractAsyncHttpRequestFactoryTestCase extends AbstractJettyServerTestCase {
|
||||||
AbstractJettyServerTestCase {
|
|
||||||
|
|
||||||
protected AsyncClientHttpRequestFactory factory;
|
protected AsyncClientHttpRequestFactory factory;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public final void createFactory() throws Exception {
|
public final void createFactory() throws Exception {
|
||||||
factory = createRequestFactory();
|
factory = createRequestFactory();
|
||||||
@@ -52,6 +52,7 @@ public abstract class AbstractAsyncHttpRequestFactoryTestCase extends
|
|||||||
|
|
||||||
protected abstract AsyncClientHttpRequestFactory createRequestFactory();
|
protected abstract AsyncClientHttpRequestFactory createRequestFactory();
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void status() throws Exception {
|
public void status() throws Exception {
|
||||||
URI uri = new URI(baseUrl + "/status/notfound");
|
URI uri = new URI(baseUrl + "/status/notfound");
|
||||||
@@ -60,8 +61,7 @@ public abstract class AbstractAsyncHttpRequestFactoryTestCase extends
|
|||||||
assertEquals("Invalid HTTP URI", uri, request.getURI());
|
assertEquals("Invalid HTTP URI", uri, request.getURI());
|
||||||
Future<ClientHttpResponse> futureResponse = request.executeAsync();
|
Future<ClientHttpResponse> futureResponse = request.executeAsync();
|
||||||
ClientHttpResponse response = futureResponse.get();
|
ClientHttpResponse response = futureResponse.get();
|
||||||
assertEquals("Invalid status code", HttpStatus.NOT_FOUND,
|
assertEquals("Invalid status code", HttpStatus.NOT_FOUND, response.getStatusCode());
|
||||||
response.getStatusCode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -70,46 +70,34 @@ public abstract class AbstractAsyncHttpRequestFactoryTestCase extends
|
|||||||
AsyncClientHttpRequest request = factory.createAsyncRequest(uri, HttpMethod.GET);
|
AsyncClientHttpRequest request = factory.createAsyncRequest(uri, HttpMethod.GET);
|
||||||
assertEquals("Invalid HTTP method", HttpMethod.GET, request.getMethod());
|
assertEquals("Invalid HTTP method", HttpMethod.GET, request.getMethod());
|
||||||
assertEquals("Invalid HTTP URI", uri, request.getURI());
|
assertEquals("Invalid HTTP URI", uri, request.getURI());
|
||||||
Future<ClientHttpResponse> futureResponse = request.executeAsync();
|
ListenableFuture<ClientHttpResponse> listenableFuture = request.executeAsync();
|
||||||
if (futureResponse instanceof ListenableFuture) {
|
listenableFuture.addCallback(new ListenableFutureCallback<ClientHttpResponse>() {
|
||||||
ListenableFuture<ClientHttpResponse> listenableFuture =
|
@Override
|
||||||
(ListenableFuture<ClientHttpResponse>) futureResponse;
|
public void onSuccess(ClientHttpResponse result) {
|
||||||
|
try {
|
||||||
|
System.out.println("SUCCESS! " + result.getStatusCode());
|
||||||
listenableFuture.addCallback(new ListenableFutureCallback<ClientHttpResponse>() {
|
System.out.println("Callback: " + System.currentTimeMillis());
|
||||||
@Override
|
System.out.println(Thread.currentThread().getId());
|
||||||
public void onSuccess(ClientHttpResponse result) {
|
assertEquals("Invalid status code", HttpStatus.NOT_FOUND, result.getStatusCode());
|
||||||
try {
|
|
||||||
System.out.println("SUCCESS! " + result.getStatusCode());
|
|
||||||
System.out.println("Callback: " + System.currentTimeMillis());
|
|
||||||
System.out.println(Thread.currentThread().getId());
|
|
||||||
assertEquals("Invalid status code", HttpStatus.NOT_FOUND,
|
|
||||||
result.getStatusCode());
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
@Override
|
ex.printStackTrace();
|
||||||
public void onFailure(Throwable t) {
|
|
||||||
System.out.println("FAILURE: " + t);
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
@Override
|
||||||
}
|
public void onFailure(Throwable ex) {
|
||||||
ClientHttpResponse response = futureResponse.get();
|
System.out.println("FAILURE: " + ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ClientHttpResponse response = listenableFuture.get();
|
||||||
System.out.println("Main thread: " + System.currentTimeMillis());
|
System.out.println("Main thread: " + System.currentTimeMillis());
|
||||||
assertEquals("Invalid status code", HttpStatus.NOT_FOUND,
|
assertEquals("Invalid status code", HttpStatus.NOT_FOUND, response.getStatusCode());
|
||||||
response.getStatusCode());
|
|
||||||
System.out.println(Thread.currentThread().getId());
|
System.out.println(Thread.currentThread().getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void echo() throws Exception {
|
public void echo() throws Exception {
|
||||||
AsyncClientHttpRequest
|
AsyncClientHttpRequest request = factory.createAsyncRequest(new URI(baseUrl + "/echo"), HttpMethod.PUT);
|
||||||
request = factory.createAsyncRequest(new URI(baseUrl + "/echo"),
|
|
||||||
HttpMethod.PUT);
|
|
||||||
assertEquals("Invalid HTTP method", HttpMethod.PUT, request.getMethod());
|
assertEquals("Invalid HTTP method", HttpMethod.PUT, request.getMethod());
|
||||||
String headerName = "MyHeader";
|
String headerName = "MyHeader";
|
||||||
String headerValue1 = "value1";
|
String headerValue1 = "value1";
|
||||||
@@ -118,9 +106,9 @@ public abstract class AbstractAsyncHttpRequestFactoryTestCase extends
|
|||||||
request.getHeaders().add(headerName, headerValue2);
|
request.getHeaders().add(headerName, headerValue2);
|
||||||
final byte[] body = "Hello World".getBytes("UTF-8");
|
final byte[] body = "Hello World".getBytes("UTF-8");
|
||||||
request.getHeaders().setContentLength(body.length);
|
request.getHeaders().setContentLength(body.length);
|
||||||
|
|
||||||
if (request instanceof StreamingHttpOutputMessage) {
|
if (request instanceof StreamingHttpOutputMessage) {
|
||||||
StreamingHttpOutputMessage streamingRequest =
|
StreamingHttpOutputMessage streamingRequest = (StreamingHttpOutputMessage) request;
|
||||||
(StreamingHttpOutputMessage) request;
|
|
||||||
streamingRequest.setBody(new StreamingHttpOutputMessage.Body() {
|
streamingRequest.setBody(new StreamingHttpOutputMessage.Body() {
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(OutputStream outputStream) throws IOException {
|
public void writeTo(OutputStream outputStream) throws IOException {
|
||||||
@@ -131,6 +119,7 @@ public abstract class AbstractAsyncHttpRequestFactoryTestCase extends
|
|||||||
else {
|
else {
|
||||||
StreamUtils.copy(body, request.getBody());
|
StreamUtils.copy(body, request.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ClientHttpResponse> futureResponse = request.executeAsync();
|
Future<ClientHttpResponse> futureResponse = request.executeAsync();
|
||||||
ClientHttpResponse response = futureResponse.get();
|
ClientHttpResponse response = futureResponse.get();
|
||||||
try {
|
try {
|
||||||
@@ -148,13 +137,11 @@ public abstract class AbstractAsyncHttpRequestFactoryTestCase extends
|
|||||||
|
|
||||||
@Test(expected = IllegalStateException.class)
|
@Test(expected = IllegalStateException.class)
|
||||||
public void multipleWrites() throws Exception {
|
public void multipleWrites() throws Exception {
|
||||||
AsyncClientHttpRequest
|
AsyncClientHttpRequest request = factory.createAsyncRequest(new URI(baseUrl + "/echo"), HttpMethod.POST);
|
||||||
request = factory.createAsyncRequest(new URI(baseUrl + "/echo"),
|
|
||||||
HttpMethod.POST);
|
|
||||||
final byte[] body = "Hello World".getBytes("UTF-8");
|
final byte[] body = "Hello World".getBytes("UTF-8");
|
||||||
|
|
||||||
if (request instanceof StreamingHttpOutputMessage) {
|
if (request instanceof StreamingHttpOutputMessage) {
|
||||||
StreamingHttpOutputMessage streamingRequest =
|
StreamingHttpOutputMessage streamingRequest = (StreamingHttpOutputMessage) request;
|
||||||
(StreamingHttpOutputMessage) request;
|
|
||||||
streamingRequest.setBody(new StreamingHttpOutputMessage.Body() {
|
streamingRequest.setBody(new StreamingHttpOutputMessage.Body() {
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(OutputStream outputStream) throws IOException {
|
public void writeTo(OutputStream outputStream) throws IOException {
|
||||||
@@ -178,9 +165,7 @@ public abstract class AbstractAsyncHttpRequestFactoryTestCase extends
|
|||||||
|
|
||||||
@Test(expected = UnsupportedOperationException.class)
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
public void headersAfterExecute() throws Exception {
|
public void headersAfterExecute() throws Exception {
|
||||||
AsyncClientHttpRequest
|
AsyncClientHttpRequest request = factory.createAsyncRequest(new URI(baseUrl + "/echo"), HttpMethod.POST);
|
||||||
request = factory.createAsyncRequest(new URI(baseUrl + "/echo"),
|
|
||||||
HttpMethod.POST);
|
|
||||||
request.getHeaders().add("MyHeader", "value");
|
request.getHeaders().add("MyHeader", "value");
|
||||||
byte[] body = "Hello World".getBytes("UTF-8");
|
byte[] body = "Hello World".getBytes("UTF-8");
|
||||||
FileCopyUtils.copy(body, request.getBody());
|
FileCopyUtils.copy(body, request.getBody());
|
||||||
@@ -208,9 +193,7 @@ public abstract class AbstractAsyncHttpRequestFactoryTestCase extends
|
|||||||
protected void assertHttpMethod(String path, HttpMethod method) throws Exception {
|
protected void assertHttpMethod(String path, HttpMethod method) throws Exception {
|
||||||
ClientHttpResponse response = null;
|
ClientHttpResponse response = null;
|
||||||
try {
|
try {
|
||||||
AsyncClientHttpRequest request = factory.createAsyncRequest(
|
AsyncClientHttpRequest request = factory.createAsyncRequest(new URI(baseUrl + "/methods/" + path), method);
|
||||||
new URI(baseUrl + "/methods/" + path), method);
|
|
||||||
|
|
||||||
Future<ClientHttpResponse> futureResponse = request.executeAsync();
|
Future<ClientHttpResponse> futureResponse = request.executeAsync();
|
||||||
response = futureResponse.get();
|
response = futureResponse.get();
|
||||||
assertEquals("Invalid response status", HttpStatus.OK, response.getStatusCode());
|
assertEquals("Invalid response status", HttpStatus.OK, response.getStatusCode());
|
||||||
|
|||||||
@@ -16,16 +16,12 @@
|
|||||||
|
|
||||||
package org.springframework.web.client;
|
package org.springframework.web.client;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -43,23 +39,27 @@ import org.springframework.util.MultiValueMap;
|
|||||||
import org.springframework.util.concurrent.ListenableFuture;
|
import org.springframework.util.concurrent.ListenableFuture;
|
||||||
import org.springframework.util.concurrent.ListenableFutureCallback;
|
import org.springframework.util.concurrent.ListenableFutureCallback;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
|
* @author Sebastien Deleuze
|
||||||
*/
|
*/
|
||||||
public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCase {
|
public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCase {
|
||||||
|
|
||||||
private AsyncRestTemplate template;
|
private AsyncRestTemplate template;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createTemplate() {
|
public void createTemplate() {
|
||||||
template = new AsyncRestTemplate(
|
template = new AsyncRestTemplate(new HttpComponentsAsyncClientHttpRequestFactory());
|
||||||
new HttpComponentsAsyncClientHttpRequestFactory());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEntity() throws ExecutionException, InterruptedException {
|
public void getEntity() throws Exception {
|
||||||
Future<ResponseEntity<String>>
|
Future<ResponseEntity<String>> futureEntity =
|
||||||
futureEntity = template.getForEntity(baseUrl + "/{method}", String.class, "get");
|
template.getForEntity(baseUrl + "/{method}", String.class, "get");
|
||||||
ResponseEntity<String> entity = futureEntity.get();
|
ResponseEntity<String> entity = futureEntity.get();
|
||||||
assertEquals("Invalid content", helloWorld, entity.getBody());
|
assertEquals("Invalid content", helloWorld, entity.getBody());
|
||||||
assertFalse("No headers", entity.getHeaders().isEmpty());
|
assertFalse("No headers", entity.getHeaders().isEmpty());
|
||||||
@@ -68,17 +68,17 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void multipleFutureGets() throws ExecutionException, InterruptedException {
|
public void multipleFutureGets() throws Exception {
|
||||||
Future<ResponseEntity<String>>
|
Future<ResponseEntity<String>> futureEntity =
|
||||||
futureEntity = template.getForEntity(baseUrl + "/{method}", String.class, "get");
|
template.getForEntity(baseUrl + "/{method}", String.class, "get");
|
||||||
futureEntity.get();
|
futureEntity.get();
|
||||||
futureEntity.get();
|
futureEntity.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getEntityCallback() throws ExecutionException, InterruptedException {
|
public void getEntityCallback() throws Exception {
|
||||||
ListenableFuture<ResponseEntity<String>>
|
ListenableFuture<ResponseEntity<String>> futureEntity =
|
||||||
futureEntity = template.getForEntity(baseUrl + "/{method}", String.class, "get");
|
template.getForEntity(baseUrl + "/{method}", String.class, "get");
|
||||||
futureEntity.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
|
futureEntity.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(ResponseEntity<String> entity) {
|
public void onSuccess(ResponseEntity<String> entity) {
|
||||||
@@ -87,10 +87,9 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
assertEquals("Invalid content-type", contentType, entity.getHeaders().getContentType());
|
assertEquals("Invalid content-type", contentType, entity.getHeaders().getContentType());
|
||||||
assertEquals("Invalid status code", HttpStatus.OK, entity.getStatusCode());
|
assertEquals("Invalid status code", HttpStatus.OK, entity.getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
fail(t.getMessage());
|
fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// wait till done
|
// wait till done
|
||||||
@@ -99,65 +98,55 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getNoResponse() throws ExecutionException, InterruptedException {
|
public void getNoResponse() throws Exception {
|
||||||
Future<ResponseEntity<String>>
|
Future<ResponseEntity<String>> futureEntity = template.getForEntity(baseUrl + "/get/nothing", String.class);
|
||||||
futureEntity = template.getForEntity(baseUrl + "/get/nothing", String.class);
|
|
||||||
ResponseEntity<String> entity = futureEntity.get();
|
ResponseEntity<String> entity = futureEntity.get();
|
||||||
assertNull("Invalid content", entity.getBody());
|
assertNull("Invalid content", entity.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getNoContentTypeHeader()
|
public void getNoContentTypeHeader() throws Exception {
|
||||||
throws UnsupportedEncodingException, ExecutionException,
|
Future<ResponseEntity<byte[]>> futureEntity = template.getForEntity(baseUrl + "/get/nocontenttype", byte[].class);
|
||||||
InterruptedException {
|
|
||||||
Future<ResponseEntity<byte[]>>
|
|
||||||
futureEntity = template.getForEntity(baseUrl + "/get/nocontenttype",
|
|
||||||
byte[].class);
|
|
||||||
ResponseEntity<byte[]> responseEntity = futureEntity.get();
|
ResponseEntity<byte[]> responseEntity = futureEntity.get();
|
||||||
assertArrayEquals("Invalid content", helloWorld.getBytes("UTF-8"),
|
assertArrayEquals("Invalid content", helloWorld.getBytes("UTF-8"), responseEntity.getBody());
|
||||||
responseEntity.getBody());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getNoContent() throws ExecutionException, InterruptedException {
|
public void getNoContent() throws Exception {
|
||||||
Future<ResponseEntity<String>>
|
Future<ResponseEntity<String>> responseFuture = template.getForEntity(baseUrl + "/status/nocontent", String.class);
|
||||||
responseFuture = template.getForEntity(baseUrl + "/status/nocontent", String.class);
|
|
||||||
ResponseEntity<String> entity = responseFuture.get();
|
ResponseEntity<String> entity = responseFuture.get();
|
||||||
assertEquals("Invalid response code", HttpStatus.NO_CONTENT, entity.getStatusCode());
|
assertEquals("Invalid response code", HttpStatus.NO_CONTENT, entity.getStatusCode());
|
||||||
assertNull("Invalid content", entity.getBody());
|
assertNull("Invalid content", entity.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getNotModified() throws ExecutionException, InterruptedException {
|
public void getNotModified() throws Exception {
|
||||||
Future<ResponseEntity<String>>
|
Future<ResponseEntity<String>> responseFuture = template.getForEntity(baseUrl + "/status/notmodified", String.class);
|
||||||
responseFuture = template.getForEntity(baseUrl + "/status/notmodified",
|
|
||||||
String.class);
|
|
||||||
ResponseEntity<String> entity = responseFuture.get();
|
ResponseEntity<String> entity = responseFuture.get();
|
||||||
assertEquals("Invalid response code", HttpStatus.NOT_MODIFIED, entity.getStatusCode());
|
assertEquals("Invalid response code", HttpStatus.NOT_MODIFIED, entity.getStatusCode());
|
||||||
assertNull("Invalid content", entity.getBody());
|
assertNull("Invalid content", entity.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void headForHeaders() throws ExecutionException, InterruptedException {
|
public void headForHeaders() throws Exception {
|
||||||
Future<HttpHeaders> headersFuture = template.headForHeaders(baseUrl + "/get");
|
Future<HttpHeaders> headersFuture = template.headForHeaders(baseUrl + "/get");
|
||||||
HttpHeaders headers = headersFuture.get();
|
HttpHeaders headers = headersFuture.get();
|
||||||
assertTrue("No Content-Type header", headers.containsKey("Content-Type"));
|
assertTrue("No Content-Type header", headers.containsKey("Content-Type"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void headForHeadersCallback() throws ExecutionException, InterruptedException {
|
public void headForHeadersCallback() throws Exception {
|
||||||
ListenableFuture<HttpHeaders> headersFuture = template.headForHeaders(baseUrl + "/get");
|
ListenableFuture<HttpHeaders> headersFuture = template.headForHeaders(baseUrl + "/get");
|
||||||
headersFuture.addCallback(new ListenableFutureCallback<HttpHeaders>() {
|
headersFuture.addCallback(new ListenableFutureCallback<HttpHeaders>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(HttpHeaders result) {
|
public void onSuccess(HttpHeaders result) {
|
||||||
assertTrue("No Content-Type header", result.containsKey("Content-Type"));
|
assertTrue("No Content-Type header", result.containsKey("Content-Type"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
fail(t.getMessage());
|
fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
while (!headersFuture.isDone()) {
|
while (!headersFuture.isDone()) {
|
||||||
@@ -165,37 +154,30 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void postForLocation()
|
public void postForLocation() throws Exception {
|
||||||
throws URISyntaxException, ExecutionException, InterruptedException {
|
|
||||||
HttpHeaders entityHeaders = new HttpHeaders();
|
HttpHeaders entityHeaders = new HttpHeaders();
|
||||||
entityHeaders.setContentType(new MediaType("text", "plain", Charset.forName("ISO-8859-15")));
|
entityHeaders.setContentType(new MediaType("text", "plain", Charset.forName("ISO-8859-15")));
|
||||||
HttpEntity<String> entity = new HttpEntity<String>(helloWorld, entityHeaders);
|
HttpEntity<String> entity = new HttpEntity<String>(helloWorld, entityHeaders);
|
||||||
Future<URI>
|
Future<URI> locationFuture = template.postForLocation(baseUrl + "/{method}", entity, "post");
|
||||||
locationFuture = template.postForLocation(baseUrl + "/{method}", entity,
|
|
||||||
"post");
|
|
||||||
URI location = locationFuture.get();
|
URI location = locationFuture.get();
|
||||||
assertEquals("Invalid location", new URI(baseUrl + "/post/1"), location);
|
assertEquals("Invalid location", new URI(baseUrl + "/post/1"), location);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void postForLocationCallback()
|
public void postForLocationCallback() throws Exception {
|
||||||
throws URISyntaxException, ExecutionException, InterruptedException {
|
|
||||||
HttpHeaders entityHeaders = new HttpHeaders();
|
HttpHeaders entityHeaders = new HttpHeaders();
|
||||||
entityHeaders.setContentType(new MediaType("text", "plain", Charset.forName("ISO-8859-15")));
|
entityHeaders.setContentType(new MediaType("text", "plain", Charset.forName("ISO-8859-15")));
|
||||||
HttpEntity<String> entity = new HttpEntity<String>(helloWorld, entityHeaders);
|
HttpEntity<String> entity = new HttpEntity<String>(helloWorld, entityHeaders);
|
||||||
final URI expected = new URI(baseUrl + "/post/1");
|
final URI expected = new URI(baseUrl + "/post/1");
|
||||||
ListenableFuture<URI>
|
ListenableFuture<URI> locationFuture = template.postForLocation(baseUrl + "/{method}", entity, "post");
|
||||||
locationFuture = template.postForLocation(baseUrl + "/{method}", entity,
|
|
||||||
"post");
|
|
||||||
locationFuture.addCallback(new ListenableFutureCallback<URI>() {
|
locationFuture.addCallback(new ListenableFutureCallback<URI>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(URI result) {
|
public void onSuccess(URI result) {
|
||||||
assertEquals("Invalid location", expected, result);
|
assertEquals("Invalid location", expected, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
fail(t.getMessage());
|
fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
while (!locationFuture.isDone()) {
|
while (!locationFuture.isDone()) {
|
||||||
@@ -203,32 +185,27 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void postForEntity()
|
public void postForEntity() throws Exception {
|
||||||
throws URISyntaxException, ExecutionException, InterruptedException {
|
|
||||||
HttpEntity<String> requestEntity = new HttpEntity<>(helloWorld);
|
HttpEntity<String> requestEntity = new HttpEntity<>(helloWorld);
|
||||||
Future<ResponseEntity<String>>
|
Future<ResponseEntity<String>> responseEntityFuture =
|
||||||
responseEntityFuture = template.postForEntity(baseUrl + "/{method}", requestEntity,
|
template.postForEntity(baseUrl + "/{method}", requestEntity, String.class, "post");
|
||||||
String.class, "post");
|
|
||||||
ResponseEntity<String> responseEntity = responseEntityFuture.get();
|
ResponseEntity<String> responseEntity = responseEntityFuture.get();
|
||||||
assertEquals("Invalid content", helloWorld, responseEntity.getBody());
|
assertEquals("Invalid content", helloWorld, responseEntity.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void postForEntityCallback()
|
public void postForEntityCallback() throws Exception {
|
||||||
throws URISyntaxException, ExecutionException, InterruptedException {
|
|
||||||
HttpEntity<String> requestEntity = new HttpEntity<>(helloWorld);
|
HttpEntity<String> requestEntity = new HttpEntity<>(helloWorld);
|
||||||
ListenableFuture<ResponseEntity<String>>
|
ListenableFuture<ResponseEntity<String>> responseEntityFuture =
|
||||||
responseEntityFuture = template.postForEntity(baseUrl + "/{method}", requestEntity,
|
template.postForEntity(baseUrl + "/{method}", requestEntity, String.class, "post");
|
||||||
String.class, "post");
|
|
||||||
responseEntityFuture.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
|
responseEntityFuture.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(ResponseEntity<String> result) {
|
public void onSuccess(ResponseEntity<String> result) {
|
||||||
assertEquals("Invalid content", helloWorld, result.getBody());
|
assertEquals("Invalid content", helloWorld, result.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
fail(t.getMessage());
|
fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
while (!responseEntityFuture.isDone()) {
|
while (!responseEntityFuture.isDone()) {
|
||||||
@@ -236,31 +213,24 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void put()
|
public void put() throws Exception {
|
||||||
throws URISyntaxException, ExecutionException, InterruptedException {
|
|
||||||
HttpEntity<String> requestEntity = new HttpEntity<>(helloWorld);
|
HttpEntity<String> requestEntity = new HttpEntity<>(helloWorld);
|
||||||
Future<?>
|
Future<?> responseEntityFuture = template.put(baseUrl + "/{method}", requestEntity, "put");
|
||||||
responseEntityFuture = template.put(baseUrl + "/{method}", requestEntity,
|
|
||||||
"put");
|
|
||||||
responseEntityFuture.get();
|
responseEntityFuture.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void putCallback()
|
public void putCallback() throws Exception {
|
||||||
throws URISyntaxException, ExecutionException, InterruptedException {
|
|
||||||
HttpEntity<String> requestEntity = new HttpEntity<>(helloWorld);
|
HttpEntity<String> requestEntity = new HttpEntity<>(helloWorld);
|
||||||
ListenableFuture<?>
|
ListenableFuture<?> responseEntityFuture = template.put(baseUrl + "/{method}", requestEntity, "put");
|
||||||
responseEntityFuture = template.put(baseUrl + "/{method}", requestEntity,
|
|
||||||
"put");
|
|
||||||
responseEntityFuture.addCallback(new ListenableFutureCallback<Object>() {
|
responseEntityFuture.addCallback(new ListenableFutureCallback<Object>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Object result) {
|
public void onSuccess(Object result) {
|
||||||
assertNull(result);
|
assertNull(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
fail(t.getMessage());
|
fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
while (!responseEntityFuture.isDone()) {
|
while (!responseEntityFuture.isDone()) {
|
||||||
@@ -268,26 +238,22 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void delete()
|
public void delete() throws Exception {
|
||||||
throws URISyntaxException, ExecutionException, InterruptedException {
|
|
||||||
Future<?> deletedFuture = template.delete(new URI(baseUrl + "/delete"));
|
Future<?> deletedFuture = template.delete(new URI(baseUrl + "/delete"));
|
||||||
|
|
||||||
deletedFuture.get();
|
deletedFuture.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteCallback()
|
public void deleteCallback() throws Exception {
|
||||||
throws URISyntaxException, ExecutionException, InterruptedException {
|
|
||||||
ListenableFuture<?> deletedFuture = template.delete(new URI(baseUrl + "/delete"));
|
ListenableFuture<?> deletedFuture = template.delete(new URI(baseUrl + "/delete"));
|
||||||
deletedFuture.addCallback(new ListenableFutureCallback<Object>() {
|
deletedFuture.addCallback(new ListenableFutureCallback<Object>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Object result) {
|
public void onSuccess(Object result) {
|
||||||
assertNull(result);
|
assertNull(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
fail(t.getMessage());
|
fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
while (!deletedFuture.isDone()) {
|
while (!deletedFuture.isDone()) {
|
||||||
@@ -295,7 +261,7 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void notFound() throws ExecutionException, InterruptedException {
|
public void notFound() throws Exception {
|
||||||
try {
|
try {
|
||||||
Future<?> future = template.execute(baseUrl + "/status/notfound", HttpMethod.GET, null, null);
|
Future<?> future = template.execute(baseUrl + "/status/notfound", HttpMethod.GET, null, null);
|
||||||
future.get();
|
future.get();
|
||||||
@@ -309,16 +275,13 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void notFoundCallback() throws ExecutionException, InterruptedException {
|
public void notFoundCallback() throws Exception {
|
||||||
ListenableFuture<?> future =
|
ListenableFuture<?> future = template.execute(baseUrl + "/status/notfound", HttpMethod.GET, null, null);
|
||||||
template.execute(baseUrl + "/status/notfound", HttpMethod.GET, null,
|
|
||||||
null);
|
|
||||||
future.addCallback(new ListenableFutureCallback<Object>() {
|
future.addCallback(new ListenableFutureCallback<Object>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Object result) {
|
public void onSuccess(Object result) {
|
||||||
fail("onSuccess not expected");
|
fail("onSuccess not expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable t) {
|
||||||
assertTrue(t instanceof HttpClientErrorException);
|
assertTrue(t instanceof HttpClientErrorException);
|
||||||
@@ -333,7 +296,7 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void serverError() throws ExecutionException, InterruptedException {
|
public void serverError() throws Exception {
|
||||||
try {
|
try {
|
||||||
Future<Void> future = template.execute(baseUrl + "/status/server", HttpMethod.GET, null, null);
|
Future<Void> future = template.execute(baseUrl + "/status/server", HttpMethod.GET, null, null);
|
||||||
future.get();
|
future.get();
|
||||||
@@ -347,21 +310,20 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void serverErrorCallback() throws ExecutionException, InterruptedException {
|
public void serverErrorCallback() throws Exception {
|
||||||
ListenableFuture<Void> future = template.execute(baseUrl + "/status/server", HttpMethod.GET, null, null);
|
ListenableFuture<Void> future = template.execute(baseUrl + "/status/server", HttpMethod.GET, null, null);
|
||||||
future.addCallback(new ListenableFutureCallback<Void>() {
|
future.addCallback(new ListenableFutureCallback<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Void result) {
|
public void onSuccess(Void result) {
|
||||||
fail("onSuccess not expected");
|
fail("onSuccess not expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
assertTrue(t instanceof HttpServerErrorException);
|
assertTrue(ex instanceof HttpServerErrorException);
|
||||||
HttpServerErrorException ex = (HttpServerErrorException) t;
|
HttpServerErrorException hsex = (HttpServerErrorException) ex;
|
||||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, ex.getStatusCode());
|
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, hsex.getStatusCode());
|
||||||
assertNotNull(ex.getStatusText());
|
assertNotNull(hsex.getStatusText());
|
||||||
assertNotNull(ex.getResponseBodyAsString());
|
assertNotNull(hsex.getResponseBodyAsString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
while (!future.isDone()) {
|
while (!future.isDone()) {
|
||||||
@@ -369,30 +331,25 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void optionsForAllow()
|
public void optionsForAllow() throws Exception {
|
||||||
throws URISyntaxException, ExecutionException, InterruptedException {
|
Future<Set<HttpMethod>> allowedFuture = template.optionsForAllow(new URI(baseUrl + "/get"));
|
||||||
Future<Set<HttpMethod>>
|
|
||||||
allowedFuture = template.optionsForAllow(new URI(baseUrl + "/get"));
|
|
||||||
Set<HttpMethod> allowed = allowedFuture.get();
|
Set<HttpMethod> allowed = allowedFuture.get();
|
||||||
assertEquals("Invalid response",
|
assertEquals("Invalid response",
|
||||||
EnumSet.of(HttpMethod.GET, HttpMethod.OPTIONS, HttpMethod.HEAD, HttpMethod.TRACE), allowed);
|
EnumSet.of(HttpMethod.GET, HttpMethod.OPTIONS, HttpMethod.HEAD, HttpMethod.TRACE), allowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void optionsForAllowCallback()
|
public void optionsForAllowCallback() throws Exception {
|
||||||
throws URISyntaxException, ExecutionException, InterruptedException {
|
ListenableFuture<Set<HttpMethod>> allowedFuture = template.optionsForAllow(new URI(baseUrl + "/get"));
|
||||||
ListenableFuture<Set<HttpMethod>>
|
|
||||||
allowedFuture = template.optionsForAllow(new URI(baseUrl + "/get"));
|
|
||||||
allowedFuture.addCallback(new ListenableFutureCallback<Set<HttpMethod>>() {
|
allowedFuture.addCallback(new ListenableFutureCallback<Set<HttpMethod>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Set<HttpMethod> result) {
|
public void onSuccess(Set<HttpMethod> result) {
|
||||||
assertEquals("Invalid response",
|
assertEquals("Invalid response", EnumSet.of(HttpMethod.GET, HttpMethod.OPTIONS,
|
||||||
EnumSet.of(HttpMethod.GET, HttpMethod.OPTIONS, HttpMethod.HEAD, HttpMethod.TRACE), result);
|
HttpMethod.HEAD, HttpMethod.TRACE), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
fail(t.getMessage());
|
fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
while (!allowedFuture.isDone()) {
|
while (!allowedFuture.isDone()) {
|
||||||
@@ -406,8 +363,7 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
requestHeaders.set("MyHeader", "MyValue");
|
requestHeaders.set("MyHeader", "MyValue");
|
||||||
HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);
|
HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);
|
||||||
Future<ResponseEntity<String>> responseFuture =
|
Future<ResponseEntity<String>> responseFuture =
|
||||||
template.exchange(baseUrl + "/{method}", HttpMethod.GET, requestEntity,
|
template.exchange(baseUrl + "/{method}", HttpMethod.GET, requestEntity, String.class, "get");
|
||||||
String.class, "get");
|
|
||||||
ResponseEntity<String> response = responseFuture.get();
|
ResponseEntity<String> response = responseFuture.get();
|
||||||
assertEquals("Invalid content", helloWorld, response.getBody());
|
assertEquals("Invalid content", helloWorld, response.getBody());
|
||||||
}
|
}
|
||||||
@@ -419,17 +375,15 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
requestHeaders.set("MyHeader", "MyValue");
|
requestHeaders.set("MyHeader", "MyValue");
|
||||||
HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);
|
HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);
|
||||||
ListenableFuture<ResponseEntity<String>> responseFuture =
|
ListenableFuture<ResponseEntity<String>> responseFuture =
|
||||||
template.exchange(baseUrl + "/{method}", HttpMethod.GET, requestEntity,
|
template.exchange(baseUrl + "/{method}", HttpMethod.GET, requestEntity, String.class, "get");
|
||||||
String.class, "get");
|
|
||||||
responseFuture.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
|
responseFuture.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(ResponseEntity<String> result) {
|
public void onSuccess(ResponseEntity<String> result) {
|
||||||
assertEquals("Invalid content", helloWorld, result.getBody());
|
assertEquals("Invalid content", helloWorld, result.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
fail(t.getMessage());
|
fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
while (!responseFuture.isDone()) {
|
while (!responseFuture.isDone()) {
|
||||||
@@ -442,9 +396,8 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
requestHeaders.set("MyHeader", "MyValue");
|
requestHeaders.set("MyHeader", "MyValue");
|
||||||
requestHeaders.setContentType(MediaType.TEXT_PLAIN);
|
requestHeaders.setContentType(MediaType.TEXT_PLAIN);
|
||||||
HttpEntity<String> requestEntity = new HttpEntity<String>(helloWorld, requestHeaders);
|
HttpEntity<String> requestEntity = new HttpEntity<String>(helloWorld, requestHeaders);
|
||||||
Future<ResponseEntity<Void>>
|
Future<ResponseEntity<Void>> resultFuture =
|
||||||
resultFuture = template.exchange(baseUrl + "/{method}", HttpMethod.POST,
|
template.exchange(baseUrl + "/{method}", HttpMethod.POST, requestEntity, Void.class, "post");
|
||||||
requestEntity, Void.class, "post");
|
|
||||||
ResponseEntity<Void> result = resultFuture.get();
|
ResponseEntity<Void> result = resultFuture.get();
|
||||||
assertEquals("Invalid location", new URI(baseUrl + "/post/1"),
|
assertEquals("Invalid location", new URI(baseUrl + "/post/1"),
|
||||||
result.getHeaders().getLocation());
|
result.getHeaders().getLocation());
|
||||||
@@ -457,31 +410,26 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
requestHeaders.set("MyHeader", "MyValue");
|
requestHeaders.set("MyHeader", "MyValue");
|
||||||
requestHeaders.setContentType(MediaType.TEXT_PLAIN);
|
requestHeaders.setContentType(MediaType.TEXT_PLAIN);
|
||||||
HttpEntity<String> requestEntity = new HttpEntity<String>(helloWorld, requestHeaders);
|
HttpEntity<String> requestEntity = new HttpEntity<String>(helloWorld, requestHeaders);
|
||||||
ListenableFuture<ResponseEntity<Void>>
|
ListenableFuture<ResponseEntity<Void>> resultFuture =
|
||||||
resultFuture = template.exchange(baseUrl + "/{method}", HttpMethod.POST,
|
template.exchange(baseUrl + "/{method}", HttpMethod.POST, requestEntity, Void.class, "post");
|
||||||
requestEntity, Void.class, "post");
|
|
||||||
final URI expected =new URI(baseUrl + "/post/1");
|
final URI expected =new URI(baseUrl + "/post/1");
|
||||||
resultFuture.addCallback(new ListenableFutureCallback<ResponseEntity<Void>>() {
|
resultFuture.addCallback(new ListenableFutureCallback<ResponseEntity<Void>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(ResponseEntity<Void> result) {
|
public void onSuccess(ResponseEntity<Void> result) {
|
||||||
assertEquals("Invalid location", expected,
|
assertEquals("Invalid location", expected, result.getHeaders().getLocation());
|
||||||
result.getHeaders().getLocation());
|
|
||||||
assertFalse(result.hasBody());
|
assertFalse(result.hasBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
fail(t.getMessage());
|
fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
while (!resultFuture.isDone()) {
|
while (!resultFuture.isDone()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void multipart() throws UnsupportedEncodingException, ExecutionException,
|
public void multipart() throws Exception {
|
||||||
InterruptedException {
|
|
||||||
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();
|
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();
|
||||||
parts.add("name 1", "value 1");
|
parts.add("name 1", "value 1");
|
||||||
parts.add("name 2", "value 2+1");
|
parts.add("name 2", "value 2+1");
|
||||||
@@ -490,8 +438,7 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
|
|||||||
parts.add("logo", logo);
|
parts.add("logo", logo);
|
||||||
|
|
||||||
HttpEntity<MultiValueMap<String, Object>> requestBody = new HttpEntity<>(parts);
|
HttpEntity<MultiValueMap<String, Object>> requestBody = new HttpEntity<>(parts);
|
||||||
Future<URI> future =
|
Future<URI> future = template.postForLocation(baseUrl + "/multipart", requestBody);
|
||||||
template.postForLocation(baseUrl + "/multipart", requestBody);
|
|
||||||
future.get();
|
future.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -23,9 +23,9 @@ import org.springframework.http.HttpHeaders;
|
|||||||
import org.springframework.util.concurrent.ListenableFuture;
|
import org.springframework.util.concurrent.ListenableFuture;
|
||||||
import org.springframework.util.concurrent.ListenableFutureCallback;
|
import org.springframework.util.concurrent.ListenableFutureCallback;
|
||||||
import org.springframework.web.socket.WebSocketHandler;
|
import org.springframework.web.socket.WebSocketHandler;
|
||||||
|
import org.springframework.web.socket.WebSocketHttpHeaders;
|
||||||
import org.springframework.web.socket.WebSocketSession;
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
import org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator;
|
import org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator;
|
||||||
import org.springframework.web.socket.WebSocketHttpHeaders;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A WebSocket connection manager that is given a URI, a {@link WebSocketClient}, and a
|
* A WebSocket connection manager that is given a URI, a {@link WebSocketClient}, and a
|
||||||
@@ -55,7 +55,7 @@ public class WebSocketConnectionManager extends ConnectionManagerSupport {
|
|||||||
super(uriTemplate, uriVariables);
|
super(uriTemplate, uriVariables);
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.webSocketHandler = decorateWebSocketHandler(webSocketHandler);
|
this.webSocketHandler = decorateWebSocketHandler(webSocketHandler);
|
||||||
this.syncClientLifecycle = ((client instanceof SmartLifecycle) && !((SmartLifecycle) client).isRunning());
|
this.syncClientLifecycle = (client instanceof SmartLifecycle && !((SmartLifecycle) client).isRunning());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -132,8 +132,9 @@ public class WebSocketConnectionManager extends ConnectionManagerSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void openConnection() {
|
protected void openConnection() {
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
logger.info("Connecting to WebSocket at " + getUri());
|
logger.info("Connecting to WebSocket at " + getUri());
|
||||||
|
}
|
||||||
|
|
||||||
ListenableFuture<WebSocketSession> future =
|
ListenableFuture<WebSocketSession> future =
|
||||||
this.client.doHandshake(this.webSocketHandler, this.headers, getUri());
|
this.client.doHandshake(this.webSocketHandler, this.headers, getUri());
|
||||||
@@ -145,8 +146,8 @@ public class WebSocketConnectionManager extends ConnectionManagerSupport {
|
|||||||
logger.info("Successfully connected");
|
logger.info("Successfully connected");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable ex) {
|
||||||
logger.error("Failed to connect", t);
|
logger.error("Failed to connect", ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -158,7 +159,7 @@ public class WebSocketConnectionManager extends ConnectionManagerSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isConnected() {
|
protected boolean isConnected() {
|
||||||
return ((this.webSocketSession != null) && (this.webSocketSession.isOpen()));
|
return (this.webSocketSession != null && this.webSocketSession.isOpen());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user