Browse Source

Add config option for StompSubProtocolErrorHandler

Issue: SPR-13142
pull/824/head
Rossen Stoyanchev 10 years ago
parent
commit
d1cc8bac5c
  1. 6
      spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java
  2. 11
      spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/StompEndpointRegistry.java
  3. 7
      spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebMvcStompEndpointRegistry.java
  4. 6
      spring-websocket/src/main/java/org/springframework/web/socket/messaging/SubProtocolErrorHandler.java
  5. 16
      spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.2.xsd
  6. 6
      spring-websocket/src/test/java/org/springframework/web/socket/config/HandlersBeanDefinitionParserTests.java
  7. 7
      spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java
  8. 23
      spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompEndpointRegistryTests.java
  9. 3
      spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml

6
spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java

@ -271,6 +271,12 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { @@ -271,6 +271,12 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser {
RootBeanDefinition stompHandlerDef = new RootBeanDefinition(StompSubProtocolHandler.class);
registerBeanDef(stompHandlerDef, context, source);
Element errorHandlerElem = DomUtils.getChildElementByTagName(element, "stomp-error-handler");
if (errorHandlerElem != null) {
RuntimeBeanReference errorHandlerRef = new RuntimeBeanReference(errorHandlerElem.getAttribute("ref"));
stompHandlerDef.getPropertyValues().add("errorHandler", errorHandlerRef);
}
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
cavs.addIndexedArgumentValue(0, inChannel);
cavs.addIndexedArgumentValue(1, outChannel);

11
spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/StompEndpointRegistry.java

@ -1,5 +1,5 @@ @@ -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.
@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.web.socket.config.annotation;
import org.springframework.web.socket.messaging.StompSubProtocolErrorHandler;
/**
* A contract for registering STOMP over WebSocket endpoints.
*
@ -29,4 +31,11 @@ public interface StompEndpointRegistry { @@ -29,4 +31,11 @@ public interface StompEndpointRegistry {
*/
StompWebSocketEndpointRegistration addEndpoint(String... paths);
/**
* Configure a handler for customizing or handling STOMP ERROR frames to clients.
* @param errorHandler the error handler
* @since 4.2
*/
WebMvcStompEndpointRegistry setErrorHandler(StompSubProtocolErrorHandler errorHandler);
}

7
spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebMvcStompEndpointRegistry.java

@ -30,6 +30,7 @@ import org.springframework.web.servlet.handler.AbstractHandlerMapping; @@ -30,6 +30,7 @@ import org.springframework.web.servlet.handler.AbstractHandlerMapping;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
import org.springframework.web.socket.messaging.StompSubProtocolErrorHandler;
import org.springframework.web.socket.messaging.StompSubProtocolHandler;
import org.springframework.web.socket.messaging.SubProtocolWebSocketHandler;
import org.springframework.web.util.UrlPathHelper;
@ -134,6 +135,12 @@ public class WebMvcStompEndpointRegistry implements StompEndpointRegistry { @@ -134,6 +135,12 @@ public class WebMvcStompEndpointRegistry implements StompEndpointRegistry {
return this.urlPathHelper;
}
@Override
public WebMvcStompEndpointRegistry setErrorHandler(StompSubProtocolErrorHandler errorHandler) {
this.stompHandler.setErrorHandler(errorHandler);
return this;
}
/**
* Return a handler mapping with the mapped ViewControllers; or {@code null} in case of no registrations.
*/

6
spring-websocket/src/main/java/org/springframework/web/socket/messaging/SubProtocolErrorHandler.java

@ -30,9 +30,9 @@ public interface SubProtocolErrorHandler<P> { @@ -30,9 +30,9 @@ public interface SubProtocolErrorHandler<P> {
* 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 that, a handler could return
* {@code null} and send a message through the broker instead, e.g. via a
* user destination targeting the user.
* 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

16
spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.2.xsd

@ -727,6 +727,22 @@ @@ -727,6 +727,22 @@
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="stomp-error-handler" minOccurs="0">
<xsd:annotation>
<xsd:documentation><![CDATA[
Configures a StompSubProtocolErrorHandler to customize or handle STOMP ERROR to clients.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="ref" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.web.socket.messaging.StompSubProtocolErrorHandler"><![CDATA[
The bean name of a StompSubProtocolErrorHandler.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:choice>
<xsd:element name="simple-broker" type="simple-broker"/>
<xsd:element name="stomp-broker-relay" type="stomp-broker-relay"/>

6
spring-websocket/src/test/java/org/springframework/web/socket/config/HandlersBeanDefinitionParserTests.java

@ -16,6 +16,9 @@ @@ -16,6 +16,9 @@
package org.springframework.web.socket.config;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
@ -64,9 +67,6 @@ import org.springframework.web.socket.sockjs.transport.handler.XhrPollingTranspo @@ -64,9 +67,6 @@ import org.springframework.web.socket.sockjs.transport.handler.XhrPollingTranspo
import org.springframework.web.socket.sockjs.transport.handler.XhrReceivingTransportHandler;
import org.springframework.web.socket.sockjs.transport.handler.XhrStreamingTransportHandler;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
/**
* Test fixture for HandlersBeanDefinitionParser.
* See test configuration files websocket-config-handlers-*.xml.

7
spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java

@ -73,6 +73,7 @@ import org.springframework.web.socket.handler.TestWebSocketSession; @@ -73,6 +73,7 @@ import org.springframework.web.socket.handler.TestWebSocketSession;
import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory;
import org.springframework.web.socket.messaging.DefaultSimpUserRegistry;
import org.springframework.web.socket.messaging.StompSubProtocolErrorHandler;
import org.springframework.web.socket.messaging.StompSubProtocolHandler;
import org.springframework.web.socket.messaging.SubProtocolHandler;
import org.springframework.web.socket.messaging.SubProtocolWebSocketHandler;
@ -144,6 +145,8 @@ public class MessageBrokerBeanDefinitionParserTests { @@ -144,6 +145,8 @@ public class MessageBrokerBeanDefinitionParserTests {
StompSubProtocolHandler stompHandler = (StompSubProtocolHandler) handlerMap.get("v12.stomp");
assertNotNull(stompHandler);
assertEquals(128 * 1024, stompHandler.getMessageSizeLimit());
assertNotNull(stompHandler.getErrorHandler());
assertEquals(TestStompErrorHandler.class, stompHandler.getErrorHandler().getClass());
assertNotNull(new DirectFieldAccessor(stompHandler).getPropertyValue("eventPublisher"));
@ -498,4 +501,8 @@ class TestWebSocketHandlerDecoratorFactory implements WebSocketHandlerDecoratorF @@ -498,4 +501,8 @@ class TestWebSocketHandlerDecoratorFactory implements WebSocketHandlerDecoratorF
}
};
}
}
class TestStompErrorHandler extends StompSubProtocolErrorHandler {
}

23
spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompEndpointRegistryTests.java

@ -1,5 +1,5 @@ @@ -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.
@ -17,16 +17,18 @@ @@ -17,16 +17,18 @@
package org.springframework.web.socket.config.annotation;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.messaging.SubscribableChannel;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.socket.messaging.StompSubProtocolErrorHandler;
import org.springframework.web.socket.messaging.StompSubProtocolHandler;
import org.springframework.web.socket.messaging.SubProtocolHandler;
import org.springframework.web.socket.messaging.SubProtocolWebSocketHandler;
import org.springframework.web.util.UrlPathHelper;
@ -46,12 +48,12 @@ public class WebMvcStompEndpointRegistryTests { @@ -46,12 +48,12 @@ public class WebMvcStompEndpointRegistryTests {
@Before
public void setup() {
SubscribableChannel inChannel = Mockito.mock(SubscribableChannel.class);
SubscribableChannel outChannel = Mockito.mock(SubscribableChannel.class);
SubscribableChannel inChannel = mock(SubscribableChannel.class);
SubscribableChannel outChannel = mock(SubscribableChannel.class);
this.webSocketHandler = new SubProtocolWebSocketHandler(inChannel, outChannel);
WebSocketTransportRegistration transport = new WebSocketTransportRegistration();
TaskScheduler scheduler = Mockito.mock(TaskScheduler.class);
TaskScheduler scheduler = mock(TaskScheduler.class);
this.endpointRegistry = new WebMvcStompEndpointRegistry(this.webSocketHandler, transport, null, scheduler);
}
@ -87,4 +89,15 @@ public class WebMvcStompEndpointRegistryTests { @@ -87,4 +89,15 @@ public class WebMvcStompEndpointRegistryTests {
assertSame(pathHelper, hm.getUrlPathHelper());
}
@Test
public void errorHandler() throws Exception {
StompSubProtocolErrorHandler errorHandler = mock(StompSubProtocolErrorHandler.class);
this.endpointRegistry.setErrorHandler(errorHandler);
this.endpointRegistry.addEndpoint("/stompOverWebSocket");
Map<String, SubProtocolHandler> protocolHandlers = this.webSocketHandler.getProtocolHandlerMap();
StompSubProtocolHandler stompHandler = (StompSubProtocolHandler) protocolHandlers.get("v12.stomp");
assertSame(errorHandler, stompHandler.getErrorHandler());
}
}

3
spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml

@ -33,6 +33,8 @@ @@ -33,6 +33,8 @@
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:stomp-error-handler ref="errorHandler" />
<websocket:simple-broker prefix="/topic, /queue" heartbeat="15000,15000" scheduler="scheduler" />
</websocket:message-broker>
@ -47,6 +49,7 @@ @@ -47,6 +49,7 @@
<bean id="myHandler" class="org.springframework.web.socket.config.TestHandshakeHandler"/>
<bean id="barTestInterceptor" class="org.springframework.web.socket.config.BarTestInterceptor"/>
<bean id="errorHandler" class="org.springframework.web.socket.config.TestStompErrorHandler"/>
<bean id="scheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler"/>
</beans>

Loading…
Cancel
Save