Polishing
This commit is contained in:
parent
1a636b1023
commit
edd6e76b9f
|
|
@ -43,7 +43,7 @@ import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
|||
* meaningful validation. All exposed Commons Pool properties use the
|
||||
* corresponding Commons Pool defaults.
|
||||
*
|
||||
* <p>Compatible with Apache Commons Pool 2.4
|
||||
* <p>Compatible with Apache Commons Pool 2.4, as of Spring 4.2.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
|
|
@ -90,6 +90,7 @@ public class CommonsPool2TargetSource extends AbstractPoolingTargetSource implem
|
|||
setMaxSize(GenericObjectPoolConfig.DEFAULT_MAX_TOTAL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the maximum number of idle objects in the pool.
|
||||
* Default is 8.
|
||||
|
|
@ -185,9 +186,10 @@ public class CommonsPool2TargetSource extends AbstractPoolingTargetSource implem
|
|||
* Specify if the call should block when the pool is exhausted.
|
||||
*/
|
||||
public boolean isBlockWhenExhausted() {
|
||||
return blockWhenExhausted;
|
||||
return this.blockWhenExhausted;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates and holds an ObjectPool instance.
|
||||
* @see #createObjectPool()
|
||||
|
|
@ -220,7 +222,7 @@ public class CommonsPool2TargetSource extends AbstractPoolingTargetSource implem
|
|||
|
||||
|
||||
/**
|
||||
* Borrow an object from the {@code ObjectPool}.
|
||||
* Borrows an object from the {@code ObjectPool}.
|
||||
*/
|
||||
@Override
|
||||
public Object getTarget() throws Exception {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -20,7 +20,8 @@ import org.springframework.transaction.annotation.AnnotationTransactionAttribute
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Concrete AspectJ transaction aspect using Spring's @Transactional annotation.
|
||||
* Concrete AspectJ transaction aspect using Spring's
|
||||
* {@link org.springframework.transaction.annotation.Transactional} annotation.
|
||||
*
|
||||
* <p>When using this aspect, you <i>must</i> annotate the implementation class
|
||||
* (and/or methods within that class), <i>not</i> the interface (if any) that
|
||||
|
|
@ -66,8 +67,6 @@ public aspect AnnotationTransactionAspect extends AbstractTransactionAspect {
|
|||
* will have Spring transaction management applied.
|
||||
*/
|
||||
protected pointcut transactionalMethodExecution(Object txObject) :
|
||||
(executionOfAnyPublicMethodInAtTransactionalType()
|
||||
|| executionOfTransactionalMethod() )
|
||||
&& this(txObject);
|
||||
(executionOfAnyPublicMethodInAtTransactionalType() || executionOfTransactionalMethod() ) && this(txObject);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -23,7 +23,8 @@ import org.aspectj.lang.annotation.RequiredTypes;
|
|||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||
|
||||
/**
|
||||
* Concrete AspectJ transaction aspect using {@code javax.transaction.Transactional} annotation.
|
||||
* Concrete AspectJ transaction aspect using the JTA 1.2
|
||||
* {@link javax.transaction.Transactional} annotation.
|
||||
*
|
||||
* <p>When using this aspect, you <i>must</i> annotate the implementation class
|
||||
* (and/or methods within that class), <i>not</i> the interface (if any) that
|
||||
|
|
@ -41,7 +42,7 @@ import org.springframework.transaction.annotation.AnnotationTransactionAttribute
|
|||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.2
|
||||
* @see Transactional
|
||||
* @see javax.transaction.Transactional
|
||||
* @see AnnotationTransactionAspect
|
||||
*/
|
||||
@RequiredTypes({"javax.transaction.Transactional"})
|
||||
|
|
@ -69,8 +70,6 @@ public aspect JtaAnnotationTransactionAspect extends AbstractTransactionAspect {
|
|||
* will have Spring transaction management applied.
|
||||
*/
|
||||
protected pointcut transactionalMethodExecution(Object txObject) :
|
||||
(executionOfAnyPublicMethodInAtTransactionalType()
|
||||
|| executionOfTransactionalMethod() )
|
||||
&& this(txObject);
|
||||
(executionOfAnyPublicMethodInAtTransactionalType() || executionOfTransactionalMethod() ) && this(txObject);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
|||
*/
|
||||
private Map<String, AbstractNestablePropertyAccessor> nestedPropertyAccessors;
|
||||
|
||||
|
||||
/**
|
||||
* Create new empty accessor. Wrapped instance needs to be set afterwards.
|
||||
* Registers default editors.
|
||||
|
|
@ -168,6 +169,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
|||
setConversionService(parent.getConversionService());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify a limit for array and collection auto-growing.
|
||||
* <p>Default is unlimited on a plain accessor.
|
||||
|
|
@ -758,7 +760,6 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
|||
for (int i = length; i < Array.getLength(newArray); i++) {
|
||||
Array.set(newArray, i, newValue(componentType, null, name));
|
||||
}
|
||||
// TODO this is not efficient because conversion may create a copy ... set directly because we know it is assignable.
|
||||
setPropertyValue(name, newArray);
|
||||
return getPropertyValue(name);
|
||||
}
|
||||
|
|
@ -802,7 +803,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
|||
* @param propertyPath property property path, which may be nested
|
||||
* @return a property accessor for the target bean
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // avoid nested generic
|
||||
@SuppressWarnings("unchecked") // avoid nested generic
|
||||
protected AbstractNestablePropertyAccessor getPropertyAccessorForPropertyPath(String propertyPath) {
|
||||
int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(propertyPath);
|
||||
// Handle nested properties recursively.
|
||||
|
|
@ -1024,9 +1025,9 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
|||
public abstract Object getValue() throws Exception;
|
||||
|
||||
public abstract void setValue(Object object, Object value) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected static class PropertyTokenHolder {
|
||||
|
||||
public String canonicalName;
|
||||
|
|
@ -1055,4 +1056,5 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
|||
return !((Optional<?>) optionalObject).isPresent();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,10 +46,10 @@ public class PayloadApplicationEvent<T> extends ApplicationEvent implements Reso
|
|||
this.payload = payload;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResolvableType getResolvableType() {
|
||||
return ResolvableType.forClassWithGenerics(getClass(),
|
||||
ResolvableType.forInstance(getPayload()));
|
||||
return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getPayload()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -334,11 +334,26 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
publishEvent(event, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish the given event to all listeners.
|
||||
* <p>Note: Listeners get initialized after the MessageSource, to be able
|
||||
* to access it within listener implementations. Thus, MessageSource
|
||||
* implementations cannot publish events.
|
||||
* @param event the event to publish (may be an {@link ApplicationEvent}
|
||||
* or a payload object to be turned into a {@link PayloadApplicationEvent})
|
||||
*/
|
||||
@Override
|
||||
public void publishEvent(Object event) {
|
||||
publishEvent(event, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish the given event to all listeners.
|
||||
* @param event the event to publish (may be an {@link ApplicationEvent}
|
||||
* or a payload object to be turned into a {@link PayloadApplicationEvent})
|
||||
* @param eventType the resolved event type, if known
|
||||
* @since 4.2
|
||||
*/
|
||||
protected void publishEvent(Object event, ResolvableType eventType) {
|
||||
Assert.notNull(event, "Event must not be null");
|
||||
if (logger.isTraceEnabled()) {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public class ScriptStatementFailedException extends ScriptException {
|
|||
super(buildErrorMessage(stmt, stmtNumber, encodedResource), cause);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build an error message for an SQL script execution failure,
|
||||
* based on the supplied arguments.
|
||||
|
|
@ -53,8 +54,7 @@ public class ScriptStatementFailedException extends ScriptException {
|
|||
* @since 4.2
|
||||
*/
|
||||
public static String buildErrorMessage(String stmt, int stmtNumber, EncodedResource encodedResource) {
|
||||
return String.format("Failed to execute SQL script statement #%s of %s: %s",
|
||||
stmtNumber, encodedResource, stmt);
|
||||
return String.format("Failed to execute SQL script statement #%s of %s: %s", stmtNumber, encodedResource, stmt);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ import org.springframework.jms.support.destination.DestinationResolver;
|
|||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Return type of any JMS listener method used to indicate the actual response destination
|
||||
* alongside the response itself. Typically used when said destination needs to be
|
||||
* computed at runtime.
|
||||
* <p>
|
||||
* The example below sends a response with the content of the {@code result} argument to
|
||||
* the {@code queueOut Queue}:
|
||||
* Return type of any JMS listener method used to indicate the actual response
|
||||
* destination alongside the response itself. Typically used when said destination
|
||||
* needs to be computed at runtime.
|
||||
*
|
||||
* <p>The example below sends a response with the content of the {@code result}
|
||||
* argument to the {@code queueOut Queue}:
|
||||
*
|
||||
* <pre class="code">
|
||||
* package com.acme.foo;
|
||||
|
|
@ -43,8 +43,8 @@ import org.springframework.util.Assert;
|
|||
* }</pre>
|
||||
*
|
||||
* If the destination does not need to be computed at runtime,
|
||||
* {@link org.springframework.messaging.handler.annotation.SendTo @SendTo} is the
|
||||
* recommended declarative approach.
|
||||
* {@link org.springframework.messaging.handler.annotation.SendTo @SendTo}
|
||||
* is the recommended declarative approach.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.2
|
||||
|
|
@ -58,6 +58,7 @@ public class JmsResponse<T> {
|
|||
|
||||
private final Object destination;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance
|
||||
* @param response the content of the result
|
||||
|
|
@ -69,29 +70,6 @@ public class JmsResponse<T> {
|
|||
this.destination = destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link JmsResponse} targeting the queue with the specified name.
|
||||
*/
|
||||
public static <T> JmsResponse<T> forQueue(T result, String queueName) {
|
||||
Assert.notNull(queueName, "Queue name must not be null");
|
||||
return new JmsResponse<T>(result, new DestinationNameHolder(queueName, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link JmsResponse} targeting the topic with the specified name.
|
||||
*/
|
||||
public static <T> JmsResponse<T> forTopic(T result, String topicName) {
|
||||
Assert.notNull(topicName, "Topic name must not be null");
|
||||
return new JmsResponse<T>(result, new DestinationNameHolder(topicName, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link JmsResponse} targeting the specified {@link Destination}.
|
||||
*/
|
||||
public static <T> JmsResponse<T> forDestination(T result, Destination destination) {
|
||||
Assert.notNull(destination, "Destination must not be null");
|
||||
return new JmsResponse<T>(result, destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the content of the response.
|
||||
|
|
@ -124,7 +102,32 @@ public class JmsResponse<T> {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JmsResponse{" + "response=" + this.response + ", destination=" + this.destination + '}';
|
||||
return "JmsResponse [" + "response=" + this.response + ", destination=" + this.destination + ']';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a {@link JmsResponse} targeting the queue with the specified name.
|
||||
*/
|
||||
public static <T> JmsResponse<T> forQueue(T result, String queueName) {
|
||||
Assert.notNull(queueName, "Queue name must not be null");
|
||||
return new JmsResponse<T>(result, new DestinationNameHolder(queueName, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link JmsResponse} targeting the topic with the specified name.
|
||||
*/
|
||||
public static <T> JmsResponse<T> forTopic(T result, String topicName) {
|
||||
Assert.notNull(topicName, "Topic name must not be null");
|
||||
return new JmsResponse<T>(result, new DestinationNameHolder(topicName, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link JmsResponse} targeting the specified {@link Destination}.
|
||||
*/
|
||||
public static <T> JmsResponse<T> forDestination(T result, Destination destination) {
|
||||
Assert.notNull(destination, "Destination must not be null");
|
||||
return new JmsResponse<T>(result, destination);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -132,7 +135,8 @@ public class JmsResponse<T> {
|
|||
* Internal class combining a destination name
|
||||
* and its target destination type (queue or topic).
|
||||
*/
|
||||
protected static class DestinationNameHolder {
|
||||
private static class DestinationNameHolder {
|
||||
|
||||
private final String destinationName;
|
||||
|
||||
private final boolean pubSubDomain;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package org.springframework.messaging.converter;
|
|||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
|
|
@ -32,9 +31,7 @@ import org.springframework.beans.TypeMismatchException;
|
|||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.MarshallingFailureException;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.oxm.UnmarshallingFailureException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
|
|
@ -61,8 +58,7 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
|
|||
* {@link #setUnmarshaller(Unmarshaller)} to be invoked separately.
|
||||
*/
|
||||
public MarshallingMessageConverter() {
|
||||
this(new MimeType("application", "xml"), new MimeType("text", "xml"),
|
||||
new MimeType("application", "*+xml"));
|
||||
this(new MimeType("application", "xml"), new MimeType("text", "xml"), new MimeType("application", "*+xml"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -76,10 +72,8 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
|
|||
/**
|
||||
* Constructor with {@link Marshaller}. If the given {@link Marshaller} also
|
||||
* implements {@link Unmarshaller}, it is also used for unmarshalling.
|
||||
*
|
||||
* <p>Note that all {@code Marshaller} implementations in Spring also implement
|
||||
* {@code Unmarshaller} so that you can safely use this constructor.
|
||||
*
|
||||
* @param marshaller object used as marshaller and unmarshaller
|
||||
*/
|
||||
public MarshallingMessageConverter(Marshaller marshaller) {
|
||||
|
|
@ -144,17 +138,13 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
|
|||
Assert.notNull(this.unmarshaller, "Property 'unmarshaller' is required");
|
||||
try {
|
||||
Source source = getSource(message.getPayload());
|
||||
|
||||
Object result = this.unmarshaller.unmarshal(source);
|
||||
if (!targetClass.isInstance(result)) {
|
||||
throw new TypeMismatchException(result, targetClass);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (UnmarshallingFailureException ex) {
|
||||
throw new MessageConversionException(message, "Could not unmarshal XML: " + ex.getMessage(), ex);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
catch (Exception ex) {
|
||||
throw new MessageConversionException(message, "Could not unmarshal XML: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
|
@ -175,26 +165,20 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
|
|||
if (byte[].class == getSerializedPayloadClass()) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
Result result = new StreamResult(out);
|
||||
|
||||
this.marshaller.marshal(payload, result);
|
||||
|
||||
payload = out.toByteArray();
|
||||
}
|
||||
else {
|
||||
Writer writer = new StringWriter();
|
||||
Result result = new StreamResult(writer);
|
||||
|
||||
this.marshaller.marshal(payload, result);
|
||||
|
||||
payload = writer.toString();
|
||||
}
|
||||
}
|
||||
catch (MarshallingFailureException ex) {
|
||||
throw new MessageConversionException("Could not marshal XML: " + ex.getMessage(), ex);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
catch (Exception ex) {
|
||||
throw new MessageConversionException("Could not marshal XML: " + ex.getMessage(), ex);
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.handler;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import org.springframework.messaging.Message;
|
|||
|
||||
/**
|
||||
* Convenient base class for {@link AsyncHandlerMethodReturnValueHandler}
|
||||
* implementations that support only asynchronous (Future-like) return values a
|
||||
* implementations that support only asynchronous (Future-like) return values
|
||||
* and merely serve as adapters of such types to Spring's
|
||||
* {@link org.springframework.util.concurrent.ListenableFuture ListenableFuture}.
|
||||
*
|
||||
|
|
@ -38,7 +38,7 @@ public abstract class AbstractAsyncReturnValueHandler implements AsyncHandlerMet
|
|||
@Override
|
||||
public void handleReturnValue(Object returnValue, MethodParameter returnType, Message<?> message) {
|
||||
// Should never be called since we return "true" from isAsyncReturnValue
|
||||
throw new IllegalStateException("Unexpected invocation.");
|
||||
throw new IllegalStateException("Unexpected invocation");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.handler.invocation;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
|
|
@ -38,11 +39,9 @@ public interface AsyncHandlerMethodReturnValueHandler extends HandlerMethodRetur
|
|||
* with success and error callbacks. If this method returns {@code true},
|
||||
* then {@link #toListenableFuture} is invoked next. If it returns
|
||||
* {@code false}, then {@link #handleReturnValue} is called.
|
||||
*
|
||||
* <p><strong>Note:</strong> this method will only be invoked after
|
||||
* {@link #supportsReturnType(org.springframework.core.MethodParameter)}
|
||||
* is called and it returns {@code true}.
|
||||
*
|
||||
* @param returnValue the value returned from the handler method
|
||||
* @param returnType the type of the return value.
|
||||
* @return true if the return value type represents an async value.
|
||||
|
|
@ -55,11 +54,9 @@ public interface AsyncHandlerMethodReturnValueHandler extends HandlerMethodRetur
|
|||
* {@link org.springframework.util.concurrent.SettableListenableFuture
|
||||
* SettableListenableFuture}. Return value handling will then continue when
|
||||
* the ListenableFuture is completed with either success or error.
|
||||
*
|
||||
* <p><strong>Note:</strong> this method will only be invoked after
|
||||
* {@link #supportsReturnType(org.springframework.core.MethodParameter)}
|
||||
* is called and it returns {@code true}.
|
||||
*
|
||||
* @param returnValue the value returned from the handler method
|
||||
* @param returnType the type of the return value.
|
||||
* @return the resulting ListenableFuture or {@code null} in which case no
|
||||
|
|
@ -67,4 +64,4 @@ public interface AsyncHandlerMethodReturnValueHandler extends HandlerMethodRetur
|
|||
*/
|
||||
ListenableFuture<?> toListenableFuture(Object returnValue, MethodParameter returnType);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,4 +43,4 @@ public class CompletableFutureReturnValueHandler extends AbstractAsyncReturnValu
|
|||
return new CompletableToListenableFutureAdapter<Object>((CompletableFuture<Object>) returnValue);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
|
|||
* @since 4.2
|
||||
*/
|
||||
public void setTaskScheduler(TaskScheduler taskScheduler) {
|
||||
Assert.notNull(taskScheduler);
|
||||
Assert.notNull(taskScheduler, "TaskScheduler must not be null");
|
||||
this.taskScheduler = taskScheduler;
|
||||
if (this.heartbeatValue == null) {
|
||||
this.heartbeatValue = new long[] {10000, 10000};
|
||||
|
|
@ -185,7 +185,7 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
|
|||
else {
|
||||
Assert.isTrue(getHeartbeatValue() == null ||
|
||||
(getHeartbeatValue()[0] == 0 && getHeartbeatValue()[1] == 0),
|
||||
"Heartbeat values configured but no TaskScheduler is provided.");
|
||||
"Heartbeat values configured but no TaskScheduler provided");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -328,7 +328,7 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SimpleBroker[" + this.subscriptionRegistry + "]";
|
||||
return "SimpleBrokerMessageHandler [" + this.subscriptionRegistry + "]";
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -337,7 +337,6 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
|
|||
/* STOMP spec: receiver SHOULD take into account an error margin */
|
||||
private static final long HEARTBEAT_MULTIPLIER = 3;
|
||||
|
||||
|
||||
private final String sessiondId;
|
||||
|
||||
private final Principal user;
|
||||
|
|
@ -350,7 +349,6 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
|
|||
|
||||
private volatile long lastWriteTime;
|
||||
|
||||
|
||||
public SessionInfo(String sessiondId, Principal user, long[] clientHeartbeat, long[] serverHeartbeat) {
|
||||
this.sessiondId = sessiondId;
|
||||
this.user = user;
|
||||
|
|
@ -400,6 +398,7 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private class HeartbeatTask implements Runnable {
|
||||
|
||||
@Override
|
||||
|
|
@ -420,4 +419,5 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
import org.springframework.messaging.tcp.TcpConnectionHandler;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link StompSession} that implements
|
||||
* {@link org.springframework.messaging.tcp.TcpConnectionHandler
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
/**
|
||||
* Raised when the connection for a STOMP session is lost rather than closed.
|
||||
|
|
@ -25,7 +25,6 @@ package org.springframework.messaging.simp.stomp;
|
|||
@SuppressWarnings("serial")
|
||||
public class ConnectionLostException extends Exception {
|
||||
|
||||
|
||||
public ConnectionLostException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
|
@ -47,7 +48,6 @@ import org.springframework.util.concurrent.ListenableFuture;
|
|||
import org.springframework.util.concurrent.ListenableFutureCallback;
|
||||
import org.springframework.util.concurrent.SettableListenableFuture;
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ConnectionHandlingStompSession}.
|
||||
*
|
||||
|
|
@ -56,7 +56,7 @@ import org.springframework.util.concurrent.SettableListenableFuture;
|
|||
*/
|
||||
public class DefaultStompSession implements ConnectionHandlingStompSession {
|
||||
|
||||
private static Log logger = LogFactory.getLog(DefaultStompSession.class);
|
||||
private static final Log logger = LogFactory.getLog(DefaultStompSession.class);
|
||||
|
||||
private static final IdGenerator idGenerator = new AlternativeJdkIdGenerator();
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
|
|||
|
||||
private long receiptTimeLimit = 15 * 1000;
|
||||
|
||||
private volatile boolean autoReceiptEnabled;
|
||||
private volatile boolean autoReceiptEnabled;
|
||||
|
||||
|
||||
private volatile TcpConnection<byte[]> connection;
|
||||
|
|
@ -107,7 +107,6 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
|
|||
|
||||
/**
|
||||
* Create a new session.
|
||||
*
|
||||
* @param sessionHandler the application handler for the session
|
||||
* @param connectHeaders headers for the STOMP CONNECT frame
|
||||
*/
|
||||
|
|
@ -201,7 +200,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
|
|||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return this.connection != null;
|
||||
return (this.connection != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -331,6 +330,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// TcpConnectionHandler
|
||||
|
||||
@Override
|
||||
|
|
@ -475,7 +475,6 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
|
|||
}
|
||||
|
||||
|
||||
|
||||
private class ReceiptHandler implements Receiptable {
|
||||
|
||||
private final String receiptId;
|
||||
|
|
@ -488,7 +487,6 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
|
|||
|
||||
private Boolean result;
|
||||
|
||||
|
||||
public ReceiptHandler(String receiptId) {
|
||||
this.receiptId = receiptId;
|
||||
if (this.receiptId != null) {
|
||||
|
|
@ -574,6 +572,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private class DefaultSubscription extends ReceiptHandler implements Subscription {
|
||||
|
||||
private final String id;
|
||||
|
|
@ -582,7 +581,6 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
|
|||
|
||||
private final StompFrameHandler handler;
|
||||
|
||||
|
||||
public DefaultSubscription(String id, String destination, String receiptId, StompFrameHandler handler) {
|
||||
super(receiptId);
|
||||
Assert.notNull(destination, "'destination' is required");
|
||||
|
|
@ -620,6 +618,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private class WriteInactivityTask implements Runnable {
|
||||
|
||||
@Override
|
||||
|
|
@ -638,6 +637,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private class ReadInactivityTask implements Runnable {
|
||||
|
||||
@Override
|
||||
|
|
@ -652,4 +652,4 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,13 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.tcp.TcpOperations;
|
||||
import org.springframework.messaging.tcp.reactor.Reactor2TcpClient;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import reactor.Environment;
|
||||
import reactor.core.config.ConfigurationReader;
|
||||
import reactor.core.config.DispatcherConfiguration;
|
||||
|
|
@ -27,9 +28,10 @@ import reactor.core.config.ReactorConfiguration;
|
|||
import reactor.io.net.NetStreams;
|
||||
import reactor.io.net.Spec.TcpClientSpec;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.tcp.TcpOperations;
|
||||
import org.springframework.messaging.tcp.reactor.Reactor2TcpClient;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* A STOMP over TCP client that uses
|
||||
|
|
@ -73,8 +75,7 @@ public class Reactor2TcpStompClient extends StompClientSupport {
|
|||
|
||||
/**
|
||||
* Connect and notify the given {@link StompSessionHandler} when connected
|
||||
* on the STOMP level,
|
||||
*
|
||||
* on the STOMP level.
|
||||
* @param handler the handler for the STOMP session
|
||||
* @return ListenableFuture for access to the session when ready for use
|
||||
*/
|
||||
|
|
@ -85,9 +86,8 @@ public class Reactor2TcpStompClient extends StompClientSupport {
|
|||
/**
|
||||
* An overloaded version of {@link #connect(StompSessionHandler)} that
|
||||
* accepts headers to use for the STOMP CONNECT frame.
|
||||
*
|
||||
* @param connectHeaders headers to add to the CONNECT frame
|
||||
* @param handler the handler for the STOMP session
|
||||
* @param handler the handler for the STOMP session
|
||||
* @return ListenableFuture for access to the session when ready for use
|
||||
*/
|
||||
public ListenableFuture<StompSession> connect(StompHeaders connectHeaders, StompSessionHandler handler) {
|
||||
|
|
@ -119,6 +119,7 @@ public class Reactor2TcpStompClient extends StompClientSupport {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class StompTcpClientSpecFactory
|
||||
implements NetStreams.TcpClientFactory<Message<byte[]>, Message<byte[]>> {
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
|
@ -22,11 +23,10 @@ import org.springframework.messaging.converter.SimpleMessageConverter;
|
|||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Base class for STOMP client implementations.
|
||||
*
|
||||
* <p>Sub-classes can connect over WebSocket or TCP using any library.
|
||||
* <p>Subclasses can connect over WebSocket or TCP using any library.
|
||||
* When creating a new connection a sub-class can create an instance of
|
||||
* {@link DefaultStompSession} which extends
|
||||
* {@link org.springframework.messaging.tcp.TcpConnectionHandler
|
||||
|
|
@ -71,12 +71,10 @@ public abstract class StompClientSupport {
|
|||
|
||||
/**
|
||||
* Configure a scheduler to use for heartbeats and for receipt tracking.
|
||||
*
|
||||
* <p><strong>Note:</strong> some transports have built-in support to work
|
||||
* with heartbeats and therefore do not require a TaskScheduler.
|
||||
* Receipts however, if needed, do require a TaskScheduler to be configured.
|
||||
*
|
||||
* <p>By default this is not set.
|
||||
* <p>By default, this is not set.
|
||||
*/
|
||||
public void setTaskScheduler(TaskScheduler taskScheduler) {
|
||||
this.taskScheduler = taskScheduler;
|
||||
|
|
@ -99,7 +97,7 @@ public abstract class StompClientSupport {
|
|||
* TaskScheduler to be configured first.
|
||||
* @param heartbeat the value for the CONNECT "heart-beat" header
|
||||
* @see <a href="http://stomp.github.io/stomp-specification-1.2.html#Heart-beating">
|
||||
* http://stomp.github.io/stomp-specification-1.2.html#Heart-beating</a>
|
||||
* http://stomp.github.io/stomp-specification-1.2.html#Heart-beating</a>
|
||||
*/
|
||||
public void setDefaultHeartbeat(long[] heartbeat) {
|
||||
Assert.notNull(heartbeat);
|
||||
|
|
@ -136,7 +134,7 @@ public abstract class StompClientSupport {
|
|||
* Return the configured receipt time limit.
|
||||
*/
|
||||
public long getReceiptTimeLimit() {
|
||||
return receiptTimeLimit;
|
||||
return this.receiptTimeLimit;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
|
||||
/**
|
||||
* Contract to handle a STOMP frame.
|
||||
*
|
||||
|
|
@ -36,7 +36,6 @@ public interface StompFrameHandler {
|
|||
/**
|
||||
* Handle a STOMP frame with the payload converted to the target type returned
|
||||
* from {@link #getPayloadType(StompHeaders)}.
|
||||
*
|
||||
* @param headers the headers of the frame
|
||||
* @param payload the payload or {@code null} if there was no payload
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
|
@ -45,7 +46,7 @@ import org.springframework.util.StringUtils;
|
|||
* @author Rossen Stoyanchev
|
||||
* @since 4.2
|
||||
* @see <a href="http://stomp.github.io/stomp-specification-1.2.html#Frames_and_Headers">
|
||||
* http://stomp.github.io/stomp-specification-1.2.html#Frames_and_Headers</a>
|
||||
* http://stomp.github.io/stomp-specification-1.2.html#Frames_and_Headers</a>
|
||||
*/
|
||||
public class StompHeaders implements MultiValueMap<String, String>, Serializable {
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
/**
|
||||
* Represents a STOMP session with operations to send messages, create
|
||||
|
|
@ -41,7 +41,6 @@ public interface StompSession {
|
|||
* the server to return a RECEIPT. An application can then use the
|
||||
* {@link StompSession.Receiptable
|
||||
* Receiptable} returned from the operation to track the receipt.
|
||||
*
|
||||
* <p>A receipt header can also be added manually through the overloaded
|
||||
* methods that accept {@code StompHeaders}.
|
||||
*/
|
||||
|
|
@ -117,7 +116,6 @@ public interface StompSession {
|
|||
* @see org.springframework.messaging.simp.stomp.StompClientSupport#setReceiptTimeLimit(long)
|
||||
*/
|
||||
void addReceiptLostTask(Runnable runnable);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -134,7 +132,6 @@ public interface StompSession {
|
|||
* Remove the subscription by sending an UNSUBSCRIBE frame.
|
||||
*/
|
||||
void unsubscribe();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
/**
|
||||
* A contract for client STOMP session lifecycle events including a callback
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.user;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
|
@ -66,6 +67,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
this.id = generateId();
|
||||
}
|
||||
|
||||
|
||||
private static String generateId() {
|
||||
String host;
|
||||
try {
|
||||
|
|
@ -171,7 +173,6 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
|
||||
private long expirationTime;
|
||||
|
||||
|
||||
public UserRegistryDto() {
|
||||
}
|
||||
|
||||
|
|
@ -233,6 +234,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class SimpUserDto implements SimpUser {
|
||||
|
||||
|
|
@ -240,7 +242,6 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
|
||||
private Set<SimpSessionDto> sessions;
|
||||
|
||||
|
||||
public SimpUserDto() {
|
||||
this.sessions = new HashSet<SimpSessionDto>(1);
|
||||
}
|
||||
|
|
@ -254,27 +255,18 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSessions() {
|
||||
return !this.sessions.isEmpty();
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SimpSession> getSessions() {
|
||||
return new HashSet<SimpSession>(this.sessions);
|
||||
}
|
||||
|
||||
public void setSessions(Set<SimpSessionDto> sessions) {
|
||||
this.sessions.addAll(sessions);
|
||||
public boolean hasSessions() {
|
||||
return !this.sessions.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -287,6 +279,15 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
return null;
|
||||
}
|
||||
|
||||
public void setSessions(Set<SimpSessionDto> sessions) {
|
||||
this.sessions.addAll(sessions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SimpSession> getSessions() {
|
||||
return new HashSet<SimpSession>(this.sessions);
|
||||
}
|
||||
|
||||
private void restoreParentReferences() {
|
||||
for (SimpSessionDto session : this.sessions) {
|
||||
session.setUser(this);
|
||||
|
|
@ -296,13 +297,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (other == null || !(other instanceof SimpUser)) {
|
||||
return false;
|
||||
}
|
||||
return this.name.equals(((SimpUser) other).getName());
|
||||
return (this == other || (other instanceof SimpUser && this.name.equals(((SimpUser) other).getName())));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -316,6 +311,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class SimpSessionDto implements SimpSession {
|
||||
|
||||
|
|
@ -323,8 +319,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
|
||||
private SimpUserDto user;
|
||||
|
||||
private Set<SimpSubscriptionDto> subscriptions;
|
||||
|
||||
private final Set<SimpSubscriptionDto> subscriptions;
|
||||
|
||||
public SimpSessionDto() {
|
||||
this.subscriptions = new HashSet<SimpSubscriptionDto>(4);
|
||||
|
|
@ -339,18 +334,13 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpUserDto getUser() {
|
||||
return this.user;
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setUser(SimpUserDto user) {
|
||||
|
|
@ -358,14 +348,19 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<SimpSubscription> getSubscriptions() {
|
||||
return new HashSet<SimpSubscription>(this.subscriptions);
|
||||
public SimpUserDto getUser() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
public void setSubscriptions(Set<SimpSubscriptionDto> subscriptions) {
|
||||
this.subscriptions.addAll(subscriptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SimpSubscription> getSubscriptions() {
|
||||
return new HashSet<SimpSubscription>(this.subscriptions);
|
||||
}
|
||||
|
||||
private void restoreParentReferences() {
|
||||
for (SimpSubscriptionDto subscription : this.subscriptions) {
|
||||
subscription.setSession(this);
|
||||
|
|
@ -373,19 +368,13 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.id.hashCode();
|
||||
public boolean equals(Object other) {
|
||||
return (this == other || (other instanceof SimpSession && this.id.equals(((SimpSession) other).getId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (other == null || !(other instanceof SimpSession)) {
|
||||
return false;
|
||||
}
|
||||
return this.id.equals(((SimpSession) other).getId());
|
||||
public int hashCode() {
|
||||
return this.id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -394,6 +383,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class SimpSubscriptionDto implements SimpSubscription {
|
||||
|
||||
|
|
@ -403,7 +393,6 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
|
||||
private String destination;
|
||||
|
||||
|
||||
public SimpSubscriptionDto() {
|
||||
}
|
||||
|
||||
|
|
@ -412,18 +401,13 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
this.destination = subscription.getDestination();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpSessionDto getSession() {
|
||||
return this.session;
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setSession(SimpSessionDto session) {
|
||||
|
|
@ -431,8 +415,8 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getDestination() {
|
||||
return this.destination;
|
||||
public SimpSessionDto getSession() {
|
||||
return this.session;
|
||||
}
|
||||
|
||||
public void setDestination(String destination) {
|
||||
|
|
@ -440,8 +424,8 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * this.id.hashCode() + ObjectUtils.nullSafeHashCode(getSession());
|
||||
public String getDestination() {
|
||||
return this.destination;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -449,7 +433,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (other == null || !(other instanceof SimpSubscription)) {
|
||||
if (!(other instanceof SimpSubscription)) {
|
||||
return false;
|
||||
}
|
||||
SimpSubscription otherSubscription = (SimpSubscription) other;
|
||||
|
|
@ -457,12 +441,18 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
|||
this.id.equals(otherSubscription.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.id.hashCode() * 31 + ObjectUtils.nullSafeHashCode(getSession());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "destination=" + this.destination;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class NoOpSmartApplicationListener implements SmartApplicationListener {
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.user;
|
||||
|
||||
import java.util.Set;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.user;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.user;
|
||||
|
||||
/**
|
||||
|
|
@ -26,7 +27,7 @@ public interface SimpSubscriptionMatcher {
|
|||
/**
|
||||
* Match the given subscription.
|
||||
* @param subscription the subscription to match
|
||||
* @return {@code true} in case of match, {@code false} otherwise.
|
||||
* @return {@code true} in case of a match, {@code false} otherwise
|
||||
*/
|
||||
boolean match(SimpSubscription subscription);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.user;
|
||||
|
||||
import java.util.Set;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.user;
|
||||
|
||||
import java.util.Set;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.user;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
|
@ -64,7 +65,6 @@ public class UserRegistryMessageHandler implements MessageHandler, ApplicationLi
|
|||
Assert.hasText(broadcastDestination, "'broadcastDestination' is required");
|
||||
Assert.notNull(scheduler, "'scheduler' is required");
|
||||
|
||||
|
||||
this.userRegistry = (MultiServerUserRegistry) userRegistry;
|
||||
this.brokerTemplate = brokerTemplate;
|
||||
this.broadcastDestination = broadcastDestination;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.messaging.simp.user;
|
||||
|
||||
import java.util.Collections;
|
||||
|
|
@ -48,12 +49,12 @@ public class UserSessionRegistryAdapter implements SimpUserRegistry {
|
|||
|
||||
@Override
|
||||
public Set<SimpUser> getUsers() {
|
||||
throw new UnsupportedOperationException("UserSessionRegistry does not expose a listing of users.");
|
||||
throw new UnsupportedOperationException("UserSessionRegistry does not expose a listing of users");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SimpSubscription> findSubscriptions(SimpSubscriptionMatcher matcher) {
|
||||
throw new UnsupportedOperationException("UserSessionRegistry does not support operations across users.");
|
||||
throw new UnsupportedOperationException("UserSessionRegistry does not support operations across users");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -63,7 +64,6 @@ public class UserSessionRegistryAdapter implements SimpUserRegistry {
|
|||
|
||||
private final Map<String, SimpSession> sessions;
|
||||
|
||||
|
||||
public SimpleSimpUser(String name, Set<String> sessionIds) {
|
||||
this.name = name;
|
||||
this.sessions = new HashMap<String, SimpSession>(sessionIds.size());
|
||||
|
|
@ -93,11 +93,11 @@ public class UserSessionRegistryAdapter implements SimpUserRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class SimpleSimpSession implements SimpSession {
|
||||
|
||||
private final String id;
|
||||
|
||||
|
||||
public SimpleSimpSession(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,11 +59,10 @@ import org.springframework.messaging.tcp.TcpOperations;
|
|||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
|
||||
/**
|
||||
* An implementation of {@link org.springframework.messaging.tcp.TcpOperations}
|
||||
* based on the TCP client support of the Reactor project.
|
||||
* <p>
|
||||
*
|
||||
* <p>This implementation wraps N (Reactor) clients for N {@link #connect} calls,
|
||||
* i.e. a separate (Reactor) client instance for each connection.
|
||||
*
|
||||
|
|
@ -76,13 +75,14 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
|||
@SuppressWarnings("rawtypes")
|
||||
public static final Class<NettyTcpClient> REACTOR_TCP_CLIENT_TYPE = NettyTcpClient.class;
|
||||
|
||||
|
||||
private final NioEventLoopGroup eventLoopGroup;
|
||||
|
||||
private final TcpClientFactory<Message<P>, Message<P>> tcpClientSpecFactory;
|
||||
|
||||
private final List<TcpClient<Message<P>, Message<P>>> tcpClients =
|
||||
new ArrayList<TcpClient<Message<P>, Message<P>>>();
|
||||
|
||||
private final NioEventLoopGroup eventLoopGroup;
|
||||
|
||||
private boolean stopping;
|
||||
|
||||
|
||||
|
|
@ -94,17 +94,14 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
|||
* threads will be shared amongst the active clients.
|
||||
* <p>Also see the constructor accepting a ready Reactor
|
||||
* {@link TcpClientSpec} {@link Function} factory.
|
||||
*
|
||||
* @param host the host to connect to
|
||||
* @param port the port to connect to
|
||||
* @param host the host to connect to
|
||||
* @param port the port to connect to
|
||||
* @param codec the codec to use for encoding and decoding the TCP stream
|
||||
*/
|
||||
public Reactor2TcpClient(final String host, final int port, final Codec<Buffer, Message<P>, Message<P>> codec) {
|
||||
|
||||
this.eventLoopGroup = initEventLoopGroup();
|
||||
|
||||
this.tcpClientSpecFactory = new TcpClientFactory<Message<P>, Message<P>>() {
|
||||
|
||||
@Override
|
||||
public TcpClientSpec<Message<P>, Message<P>> apply(TcpClientSpec<Message<P>, Message<P>> spec) {
|
||||
return spec
|
||||
|
|
@ -116,12 +113,28 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor with a pre-configured {@link TcpClientSpec} {@link Function}
|
||||
* factory. This might be used to add SSL or specific network parameters to
|
||||
* the generated client configuration.
|
||||
* <p><strong>NOTE:</strong> if the client is configured with a thread-creating
|
||||
* dispatcher, you are responsible for cleaning them, e.g. using
|
||||
* {@link reactor.core.Dispatcher#shutdown}.
|
||||
* @param tcpClientSpecFactory the TcpClientSpec {@link Function} to use for each client creation
|
||||
*/
|
||||
public Reactor2TcpClient(TcpClientFactory<Message<P>, Message<P>> tcpClientSpecFactory) {
|
||||
Assert.notNull(tcpClientSpecFactory, "'tcpClientClientFactory' must not be null");
|
||||
this.tcpClientSpecFactory = tcpClientSpecFactory;
|
||||
this.eventLoopGroup = null;
|
||||
}
|
||||
|
||||
|
||||
private static NioEventLoopGroup initEventLoopGroup() {
|
||||
int ioThreadCount;
|
||||
try {
|
||||
ioThreadCount = Integer.parseInt(System.getProperty("reactor.tcp.ioThreadCount"));
|
||||
}
|
||||
catch (Exception i) {
|
||||
catch (Exception ex) {
|
||||
ioThreadCount = -1;
|
||||
}
|
||||
if (ioThreadCount <= 0l) {
|
||||
|
|
@ -132,26 +145,10 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
|||
new NamedDaemonThreadFactory("reactor-tcp-io"));
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor with a pre-configured {@link TcpClientSpec} {@link Function}
|
||||
* factory. This might be used to add SSL or specific network parameters to
|
||||
* the generated client configuration.
|
||||
* <p><strong>NOTE:</strong> if the client is configured with a thread-creating
|
||||
* dispatcher, you are responsible for cleaning them, e.g. using
|
||||
* {@link reactor.core.Dispatcher#shutdown}.
|
||||
*
|
||||
* @param tcpClientSpecFactory the TcpClientSpec {@link Function} to use for each client creation.
|
||||
*/
|
||||
public Reactor2TcpClient(TcpClientFactory<Message<P>, Message<P>> tcpClientSpecFactory) {
|
||||
Assert.notNull(tcpClientSpecFactory, "'tcpClientClientFactory' must not be null");
|
||||
this.tcpClientSpecFactory = tcpClientSpecFactory;
|
||||
this.eventLoopGroup = null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ListenableFuture<Void> connect(final TcpConnectionHandler<P> connectionHandler) {
|
||||
Assert.notNull(connectionHandler, "'connectionHandler' must not be null");
|
||||
Assert.notNull(connectionHandler, "TcpConnectionHandler must not be null");
|
||||
|
||||
TcpClient<Message<P>, Message<P>> tcpClient;
|
||||
synchronized (this.tcpClients) {
|
||||
|
|
@ -178,8 +175,8 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
|||
|
||||
@Override
|
||||
public ListenableFuture<Void> connect(TcpConnectionHandler<P> connectionHandler, ReconnectStrategy strategy) {
|
||||
Assert.notNull(connectionHandler, "'connectionHandler' must not be null");
|
||||
Assert.notNull(strategy, "'reconnectStrategy' must not be null");
|
||||
Assert.notNull(connectionHandler, "TcpConnectionHandler must not be null");
|
||||
Assert.notNull(strategy, "ReconnectStrategy must not be null");
|
||||
|
||||
TcpClient<Message<P>, Message<P>> tcpClient;
|
||||
synchronized (this.tcpClients) {
|
||||
|
|
@ -204,6 +201,7 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
|||
synchronized (this.tcpClients) {
|
||||
this.stopping = true;
|
||||
}
|
||||
|
||||
Promise<Void> promise = Streams.from(this.tcpClients)
|
||||
.flatMap(new Function<TcpClient<Message<P>, Message<P>>, Promise<Void>>() {
|
||||
@Override
|
||||
|
|
@ -217,6 +215,7 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
|||
}
|
||||
})
|
||||
.next();
|
||||
|
||||
if (this.eventLoopGroup != null) {
|
||||
final Promise<Void> eventLoopPromise = Promises.prepare();
|
||||
promise.onComplete(new Consumer<Promise<Void>>() {
|
||||
|
|
@ -249,6 +248,7 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class MessageChannelStreamHandler<P>
|
||||
implements ReactorChannelHandler<Message<P>, Message<P>, ChannelStream<Message<P>, Message<P>>> {
|
||||
|
||||
|
|
@ -260,14 +260,10 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
|||
|
||||
@Override
|
||||
public Publisher<Void> apply(ChannelStream<Message<P>, Message<P>> channelStream) {
|
||||
|
||||
Promise<Void> closePromise = Promises.prepare();
|
||||
|
||||
this.connectionHandler.afterConnected(new Reactor2TcpConnection<P>(channelStream, closePromise));
|
||||
|
||||
channelStream
|
||||
.finallyDo(new Consumer<Signal<Message<P>>>() {
|
||||
|
||||
@Override
|
||||
public void accept(Signal<Message<P>> signal) {
|
||||
if (signal.isOnError()) {
|
||||
|
|
@ -279,7 +275,6 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
|||
}
|
||||
})
|
||||
.consume(new Consumer<Message<P>>() {
|
||||
|
||||
@Override
|
||||
public void accept(Message<P> message) {
|
||||
connectionHandler.handleMessage(message);
|
||||
|
|
@ -290,6 +285,7 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class ReactorReconnectAdapter implements Reconnect {
|
||||
|
||||
private final ReconnectStrategy strategy;
|
||||
|
|
@ -300,7 +296,7 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
|||
|
||||
@Override
|
||||
public Tuple2<InetSocketAddress, Long> reconnect(InetSocketAddress address, int attempt) {
|
||||
return Tuple.of(address, strategy.getTimeToNextAttempt(attempt));
|
||||
return Tuple.of(address, this.strategy.getTimeToNextAttempt(attempt));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,19 +51,21 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
|
|||
|
||||
private final TransactionalEventListener annotation;
|
||||
|
||||
|
||||
public ApplicationListenerMethodTransactionalAdapter(String beanName, Class<?> targetClass, Method method) {
|
||||
super(beanName, targetClass, method);
|
||||
this.annotation = findAnnotation(method);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
TransactionSynchronization transactionSynchronization = createTransactionSynchronization(event);
|
||||
TransactionSynchronizationManager.registerSynchronization(transactionSynchronization);
|
||||
}
|
||||
else if (annotation.fallbackExecution()) {
|
||||
if (annotation.phase() == TransactionPhase.AFTER_ROLLBACK) {
|
||||
else if (this.annotation.fallbackExecution()) {
|
||||
if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK) {
|
||||
logger.warn("Processing '" + event + "' as a fallback execution on AFTER_ROLLBACK phase.");
|
||||
}
|
||||
processEvent(event);
|
||||
|
|
@ -80,8 +82,8 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
|
|||
}
|
||||
|
||||
static TransactionalEventListener findAnnotation(Method method) {
|
||||
TransactionalEventListener annotation = AnnotatedElementUtils
|
||||
.findMergedAnnotation(method, TransactionalEventListener.class);
|
||||
TransactionalEventListener annotation =
|
||||
AnnotatedElementUtils.findMergedAnnotation(method, TransactionalEventListener.class);
|
||||
if (annotation == null) {
|
||||
throw new IllegalStateException("No TransactionalEventListener annotation found on '" + method + "'");
|
||||
}
|
||||
|
|
@ -97,7 +99,7 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
|
|||
|
||||
private final TransactionPhase phase;
|
||||
|
||||
protected TransactionSynchronizationEventAdapter(ApplicationListenerMethodAdapter listener,
|
||||
public TransactionSynchronizationEventAdapter(ApplicationListenerMethodAdapter listener,
|
||||
ApplicationEvent event, TransactionPhase phase) {
|
||||
|
||||
this.listener = listener;
|
||||
|
|
@ -107,20 +109,20 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
|
|||
|
||||
@Override
|
||||
public void beforeCommit(boolean readOnly) {
|
||||
if (phase == TransactionPhase.BEFORE_COMMIT) {
|
||||
if (this.phase == TransactionPhase.BEFORE_COMMIT) {
|
||||
processEvent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(int status) {
|
||||
if (phase == TransactionPhase.AFTER_COMPLETION) {
|
||||
if (this.phase == TransactionPhase.AFTER_COMPLETION) {
|
||||
processEvent();
|
||||
}
|
||||
else if (phase == TransactionPhase.AFTER_COMMIT && status == STATUS_COMMITTED) {
|
||||
else if (this.phase == TransactionPhase.AFTER_COMMIT && status == STATUS_COMMITTED) {
|
||||
processEvent();
|
||||
}
|
||||
else if (phase == TransactionPhase.AFTER_ROLLBACK && status == STATUS_ROLLED_BACK) {
|
||||
else if (this.phase == TransactionPhase.AFTER_ROLLBACK && status == STATUS_ROLLED_BACK) {
|
||||
processEvent();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,18 +34,20 @@ public class TransactionalEventListenerFactory implements EventListenerFactory,
|
|||
|
||||
private int order = 50;
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supportsMethod(Method method) {
|
||||
return AnnotationUtils.findAnnotation(method, TransactionalEventListener.class) != null;
|
||||
return (AnnotationUtils.findAnnotation(method, TransactionalEventListener.class) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -158,7 +158,6 @@ public class FacesWebRequest extends FacesRequestAttributes implements NativeWeb
|
|||
/**
|
||||
* Last-modified handling not supported for portlet requests:
|
||||
* As a consequence, this method always returns {@code false}.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -165,7 +165,6 @@ public class PortletWebRequest extends PortletRequestAttributes implements Nativ
|
|||
/**
|
||||
* Last-modified handling not supported for portlet requests:
|
||||
* As a consequence, this method always returns {@code false}.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.socket.messaging;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
|
|
@ -35,7 +36,6 @@ public class StompSubProtocolErrorHandler implements SubProtocolErrorHandler<byt
|
|||
|
||||
@Override
|
||||
public Message<byte[]> handleClientMessageProcessingError(Message<byte[]> clientMessage, Throwable ex) {
|
||||
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.ERROR);
|
||||
accessor.setMessage(ex.getMessage());
|
||||
accessor.setLeaveMutable(true);
|
||||
|
|
@ -54,14 +54,11 @@ public class StompSubProtocolErrorHandler implements SubProtocolErrorHandler<byt
|
|||
|
||||
@Override
|
||||
public Message<byte[]> handleErrorMessageToClient(Message<byte[]> errorMessage) {
|
||||
|
||||
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(errorMessage, StompHeaderAccessor.class);
|
||||
Assert.notNull(accessor, "Expected STOMP headers.");
|
||||
|
||||
Assert.notNull(accessor, "Expected STOMP headers");
|
||||
if (!accessor.isMutable()) {
|
||||
accessor = StompHeaderAccessor.wrap(errorMessage);
|
||||
}
|
||||
|
||||
return handleInternal(accessor, errorMessage.getPayload(), null, null);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.socket.messaging;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
|
|
@ -28,12 +29,10 @@ public interface SubProtocolErrorHandler<P> {
|
|||
/**
|
||||
* Handle errors thrown while processing client messages providing an
|
||||
* opportunity to prepare the error message or to prevent one from being sent.
|
||||
*
|
||||
* <p>Note that the STOMP protocol requires a server to close the connection
|
||||
* after sending an ERROR frame. To prevent an ERROR frame from being sent,
|
||||
* a handler could return {@code null} and send a notification message
|
||||
* through the broker instead, e.g. via a user destination.
|
||||
*
|
||||
* @param clientMessage the client message related to the error, possibly
|
||||
* {@code null} if error occurred while parsing a WebSocket message
|
||||
* @param ex the cause for the error, never {@code null}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.socket.messaging;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -87,7 +88,6 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif
|
|||
* Class constructor. Sets {@link #setDefaultHeartbeat} to "0,0" but will
|
||||
* reset it back to the preferred "10000,10000" when a
|
||||
* {@link #setTaskScheduler} is configured.
|
||||
*
|
||||
* @param webSocketClient the WebSocket client to connect with
|
||||
*/
|
||||
public WebSocketStompClient(WebSocketClient webSocketClient) {
|
||||
|
|
@ -302,13 +302,11 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif
|
|||
|
||||
private final List<ScheduledFuture<?>> inactivityTasks = new ArrayList<ScheduledFuture<?>>(2);
|
||||
|
||||
|
||||
public WebSocketTcpConnectionHandlerAdapter(TcpConnectionHandler<byte[]> connectionHandler) {
|
||||
Assert.notNull(connectionHandler);
|
||||
this.connectionHandler = connectionHandler;
|
||||
}
|
||||
|
||||
|
||||
// ListenableFutureCallback implementation: handshake outcome
|
||||
|
||||
@Override
|
||||
|
|
@ -320,7 +318,6 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif
|
|||
this.connectionHandler.afterConnectFailure(ex);
|
||||
}
|
||||
|
||||
|
||||
// WebSocketHandler implementation
|
||||
|
||||
@Override
|
||||
|
|
@ -375,7 +372,6 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
// TcpConnection implementation
|
||||
|
||||
@Override
|
||||
|
|
@ -466,12 +462,10 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif
|
|||
|
||||
private final BufferingStompDecoder bufferingDecoder;
|
||||
|
||||
|
||||
public StompWebSocketMessageCodec(int messageSizeLimit) {
|
||||
this.bufferingDecoder = new BufferingStompDecoder(DECODER, messageSizeLimit);
|
||||
}
|
||||
|
||||
|
||||
public List<Message<byte[]>> decode(WebSocketMessage<?> webSocketMessage) {
|
||||
List<Message<byte[]>> result = Collections.<Message<byte[]>>emptyList();
|
||||
ByteBuffer byteBuffer;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.socket.server.support;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ public abstract class AbstractHttpSockJsSession extends AbstractSockJsSession {
|
|||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of 4.2 this method is no longer used.
|
||||
* @deprecated as of 4.2, since this method is no longer used.
|
||||
*/
|
||||
@Deprecated
|
||||
protected abstract boolean isStreaming();
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public abstract class StreamingSockJsSession extends AbstractHttpSockJsSession {
|
|||
|
||||
|
||||
/**
|
||||
* @deprecated as of 4.2 this method is no longer used.
|
||||
* @deprecated as of 4.2, since this method is no longer used.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
|
|
@ -61,6 +61,7 @@ public abstract class StreamingSockJsSession extends AbstractHttpSockJsSession {
|
|||
*/
|
||||
protected abstract byte[] getPrelude(ServerHttpRequest request);
|
||||
|
||||
|
||||
@Override
|
||||
protected void handleRequestInternal(ServerHttpRequest request, ServerHttpResponse response,
|
||||
boolean initialRequest) throws IOException {
|
||||
|
|
@ -84,15 +85,13 @@ public abstract class StreamingSockJsSession extends AbstractHttpSockJsSession {
|
|||
SockJsFrame frame = SockJsFrame.messageFrame(messageCodec, message);
|
||||
writeFrame(frame);
|
||||
|
||||
this.byteCount += frame.getContentBytes().length + 1;
|
||||
this.byteCount += (frame.getContentBytes().length + 1);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(this.byteCount + " bytes written so far, "
|
||||
+ getMessageCache().size() + " more messages not flushed");
|
||||
logger.trace(this.byteCount + " bytes written so far, " +
|
||||
getMessageCache().size() + " more messages not flushed");
|
||||
}
|
||||
if (this.byteCount >= getSockJsServiceConfig().getStreamBytesLimit()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Streamed bytes limit reached. Recycling current request");
|
||||
}
|
||||
logger.trace("Streamed bytes limit reached, recycling current request");
|
||||
resetRequest();
|
||||
this.byteCount = 0;
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in New Issue