Polishing
This commit is contained in:
parent
5b471a5349
commit
e8ab53e76d
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
STOMP over WebSocket support is available in the `spring-messaging` and
|
STOMP over WebSocket support is available in the `spring-messaging` and
|
||||||
`spring-websocket` modules. Once you have those dependencies, you can expose a STOMP
|
`spring-websocket` modules. Once you have those dependencies, you can expose a STOMP
|
||||||
endpoints, over WebSocket with xref:web/websocket/fallback.adoc[SockJS Fallback], as the following example shows:
|
endpoint over WebSocket with xref:web/websocket/fallback.adoc[SockJS Fallback], as the following example shows:
|
||||||
|
|
||||||
[source,java,indent=0,subs="verbatim,quotes"]
|
[source,java,indent=0,subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -32,7 +32,7 @@ client needs to connect for the WebSocket handshake.
|
||||||
<2> STOMP messages whose destination header begins with `/app` are routed to
|
<2> STOMP messages whose destination header begins with `/app` are routed to
|
||||||
`@MessageMapping` methods in `@Controller` classes.
|
`@MessageMapping` methods in `@Controller` classes.
|
||||||
<3> Use the built-in message broker for subscriptions and broadcasting and
|
<3> Use the built-in message broker for subscriptions and broadcasting and
|
||||||
route messages whose destination header begins with `/topic `or `/queue` to the broker.
|
route messages whose destination header begins with `/topic` or `/queue` to the broker.
|
||||||
|
|
||||||
|
|
||||||
The following example shows the XML configuration equivalent of the preceding example:
|
The following example shows the XML configuration equivalent of the preceding example:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 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.
|
||||||
|
|
@ -22,7 +22,7 @@ import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represent predefined {@linkplain Member members} groups.
|
* Predefined {@link Member} categories.
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
* @author Sebastien Deleuze
|
* @author Sebastien Deleuze
|
||||||
|
|
@ -39,14 +39,14 @@ public enum MemberCategory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A category that represents {@linkplain Class#getDeclaredFields() declared
|
* A category that represents {@linkplain Class#getDeclaredFields() declared
|
||||||
* fields}, that is all fields defined by the class, but not inherited ones.
|
* fields}: all fields defined by the class but not inherited fields.
|
||||||
* @see Class#getDeclaredFields()
|
* @see Class#getDeclaredFields()
|
||||||
*/
|
*/
|
||||||
DECLARED_FIELDS,
|
DECLARED_FIELDS,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A category that defines public {@linkplain Constructor constructors} can
|
* A category that defines public {@linkplain Constructor constructors} can
|
||||||
* be introspected, but not invoked.
|
* be introspected but not invoked.
|
||||||
* @see Class#getConstructors()
|
* @see Class#getConstructors()
|
||||||
* @see ExecutableMode#INTROSPECT
|
* @see ExecutableMode#INTROSPECT
|
||||||
*/
|
*/
|
||||||
|
|
@ -54,7 +54,7 @@ public enum MemberCategory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A category that defines {@linkplain Class#getDeclaredConstructors() all
|
* A category that defines {@linkplain Class#getDeclaredConstructors() all
|
||||||
* constructors} can be introspected, but not invoked.
|
* constructors} can be introspected but not invoked.
|
||||||
* @see Class#getDeclaredConstructors()
|
* @see Class#getDeclaredConstructors()
|
||||||
* @see ExecutableMode#INTROSPECT
|
* @see ExecutableMode#INTROSPECT
|
||||||
*/
|
*/
|
||||||
|
|
@ -78,7 +78,7 @@ public enum MemberCategory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A category that defines public {@linkplain Method methods}, including
|
* A category that defines public {@linkplain Method methods}, including
|
||||||
* inherited ones can be introspect, but not invoked.
|
* inherited ones, can be introspected but not invoked.
|
||||||
* @see Class#getMethods()
|
* @see Class#getMethods()
|
||||||
* @see ExecutableMode#INTROSPECT
|
* @see ExecutableMode#INTROSPECT
|
||||||
*/
|
*/
|
||||||
|
|
@ -86,7 +86,7 @@ public enum MemberCategory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A category that defines {@linkplain Class#getDeclaredMethods() all
|
* A category that defines {@linkplain Class#getDeclaredMethods() all
|
||||||
* methods}, excluding inherited ones can be introspected, but not invoked.
|
* methods}, excluding inherited ones, can be introspected but not invoked.
|
||||||
* @see Class#getDeclaredMethods()
|
* @see Class#getDeclaredMethods()
|
||||||
* @see ExecutableMode#INTROSPECT
|
* @see ExecutableMode#INTROSPECT
|
||||||
*/
|
*/
|
||||||
|
|
@ -94,7 +94,7 @@ public enum MemberCategory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A category that defines public {@linkplain Method methods}, including
|
* A category that defines public {@linkplain Method methods}, including
|
||||||
* inherited ones can be invoked.
|
* inherited ones, can be invoked.
|
||||||
* @see Class#getMethods()
|
* @see Class#getMethods()
|
||||||
* @see ExecutableMode#INVOKE
|
* @see ExecutableMode#INVOKE
|
||||||
*/
|
*/
|
||||||
|
|
@ -102,7 +102,7 @@ public enum MemberCategory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A category that defines {@linkplain Class#getDeclaredMethods() all
|
* A category that defines {@linkplain Class#getDeclaredMethods() all
|
||||||
* methods}, excluding inherited ones can be invoked.
|
* methods}, excluding inherited ones, can be invoked.
|
||||||
* @see Class#getDeclaredMethods()
|
* @see Class#getDeclaredMethods()
|
||||||
* @see ExecutableMode#INVOKE
|
* @see ExecutableMode#INVOKE
|
||||||
*/
|
*/
|
||||||
|
|
@ -110,16 +110,18 @@ public enum MemberCategory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A category that represents public {@linkplain Class#getClasses() inner
|
* A category that represents public {@linkplain Class#getClasses() inner
|
||||||
* classes}. Contrary to other categories, this does not register any
|
* classes}.
|
||||||
* particular reflection for them but rather make sure they are available
|
* <p>Contrary to other categories, this does not register any particular
|
||||||
|
* reflection for inner classes but rather makes sure they are available
|
||||||
* via a call to {@link Class#getClasses}.
|
* via a call to {@link Class#getClasses}.
|
||||||
*/
|
*/
|
||||||
PUBLIC_CLASSES,
|
PUBLIC_CLASSES,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A category that represents all {@linkplain Class#getDeclaredClasses()
|
* A category that represents all {@linkplain Class#getDeclaredClasses()
|
||||||
* inner classes}. Contrary to other categories, this does not register any
|
* inner classes}.
|
||||||
* particular reflection for them but rather make sure they are available
|
* <p>Contrary to other categories, this does not register any particular
|
||||||
|
* reflection for inner classes but rather makes sure they are available
|
||||||
* via a call to {@link Class#getDeclaredClasses}.
|
* via a call to {@link Class#getDeclaredClasses}.
|
||||||
*/
|
*/
|
||||||
DECLARED_CLASSES;
|
DECLARED_CLASSES;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2023 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,15 +33,16 @@ public abstract class NativeDetector {
|
||||||
private static final boolean inNativeImage = (imageCode != null);
|
private static final boolean inNativeImage = (imageCode != null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if running in a native image context (for example {@code buildtime}, {@code runtime} or
|
* Returns {@code true} if running in a native image context (for example
|
||||||
* {@code agent}) expressed by setting {@code org.graalvm.nativeimage.imagecode} system property to any value, else {@code false}.
|
* {@code buildtime}, {@code runtime}, or {@code agent}) expressed by setting the
|
||||||
|
* {@code org.graalvm.nativeimage.imagecode} system property to any value.
|
||||||
*/
|
*/
|
||||||
public static boolean inNativeImage() {
|
public static boolean inNativeImage() {
|
||||||
return inNativeImage;
|
return inNativeImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if running in any of the specified native image context(s), else {@code false}.
|
* Returns {@code true} if running in any of the specified native image context(s).
|
||||||
* @param contexts the native image context(s)
|
* @param contexts the native image context(s)
|
||||||
* @since 6.0.10
|
* @since 6.0.10
|
||||||
*/
|
*/
|
||||||
|
|
@ -55,8 +56,8 @@ public abstract class NativeDetector {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Native image context as defined in
|
* Native image context as defined in GraalVM's
|
||||||
* <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>.
|
* <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo</a>.
|
||||||
*
|
*
|
||||||
* @since 6.0.10
|
* @since 6.0.10
|
||||||
*/
|
*/
|
||||||
|
|
@ -82,6 +83,7 @@ public abstract class NativeDetector {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return this.key;
|
return this.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.messaging.simp.broker;
|
package org.springframework.messaging.simp.broker;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -33,41 +32,38 @@ import org.springframework.util.MultiValueMap;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test fixture for
|
* Tests for {@link DefaultSubscriptionRegistry}.
|
||||||
* {@link org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry}.
|
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @author Sebastien Deleuze
|
* @author Sebastien Deleuze
|
||||||
|
* @author Sam Brannen
|
||||||
*/
|
*/
|
||||||
public class DefaultSubscriptionRegistryTests {
|
class DefaultSubscriptionRegistryTests {
|
||||||
|
|
||||||
private final DefaultSubscriptionRegistry registry = new DefaultSubscriptionRegistry();
|
private final DefaultSubscriptionRegistry registry = new DefaultSubscriptionRegistry();
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerSubscriptionInvalidInput() {
|
void registerSubscriptionInvalidInput() {
|
||||||
String sessId = "sess01";
|
String sessId = "sess01";
|
||||||
String subsId = "subs01";
|
String subsId = "subs01";
|
||||||
String dest = "/foo";
|
String dest = "/foo";
|
||||||
|
|
||||||
this.registry.registerSubscription(subscribeMessage(null, subsId, dest));
|
this.registry.registerSubscription(subscribeMessage(null, subsId, dest));
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).isEmpty();
|
assertThat(actual).isEmpty();
|
||||||
|
|
||||||
this.registry.registerSubscription(subscribeMessage(sessId, null, dest));
|
this.registry.registerSubscription(subscribeMessage(sessId, null, dest));
|
||||||
actual = this.registry.findSubscriptions(createMessage(dest));
|
actual = this.registry.findSubscriptions(createMessage(dest));
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).isEmpty();
|
assertThat(actual).isEmpty();
|
||||||
|
|
||||||
this.registry.registerSubscription(subscribeMessage(sessId, subsId, null));
|
this.registry.registerSubscription(subscribeMessage(sessId, subsId, null));
|
||||||
actual = this.registry.findSubscriptions(createMessage(dest));
|
actual = this.registry.findSubscriptions(createMessage(dest));
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).isEmpty();
|
assertThat(actual).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerSubscription() {
|
void registerSubscription() {
|
||||||
String sessId = "sess01";
|
String sessId = "sess01";
|
||||||
String subsId = "subs01";
|
String subsId = "subs01";
|
||||||
String dest = "/foo";
|
String dest = "/foo";
|
||||||
|
|
@ -75,15 +71,14 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
this.registry.registerSubscription(subscribeMessage(sessId, subsId, dest));
|
this.registry.registerSubscription(subscribeMessage(sessId, subsId, dest));
|
||||||
|
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
||||||
assertThat(actual).isNotNull();
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual).as("Expected one element " + actual).hasSize(1);
|
assertThat(actual.get(sessId)).containsExactly(subsId);
|
||||||
assertThat(actual.get(sessId)).isEqualTo(Collections.singletonList(subsId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerSubscriptionOneSession() {
|
void registerSubscriptionOneSession() {
|
||||||
String sessId = "sess01";
|
String sessId = "sess01";
|
||||||
List<String> subscriptionIds = Arrays.asList("subs01", "subs02", "subs03");
|
List<String> subscriptionIds = List.of("subs01", "subs02", "subs03");
|
||||||
String dest = "/foo";
|
String dest = "/foo";
|
||||||
|
|
||||||
for (String subId : subscriptionIds) {
|
for (String subId : subscriptionIds) {
|
||||||
|
|
@ -91,13 +86,12 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).hasSize(1);
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(sort(actual.get(sessId))).isEqualTo(subscriptionIds);
|
assertThat(sort(actual.get(sessId))).isEqualTo(subscriptionIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerSameSubscriptionTwice() {
|
void registerSameSubscriptionTwice() {
|
||||||
String sessId = "sess01";
|
String sessId = "sess01";
|
||||||
String subId = "subs01";
|
String subId = "subs01";
|
||||||
String dest = "/foo";
|
String dest = "/foo";
|
||||||
|
|
@ -106,15 +100,14 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
this.registry.registerSubscription(subscribeMessage(sessId, subId, dest));
|
this.registry.registerSubscription(subscribeMessage(sessId, subId, dest));
|
||||||
|
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).hasSize(1);
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual.get(sessId)).containsExactly(subId);
|
assertThat(actual.get(sessId)).containsExactly(subId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerSubscriptionMultipleSessions() {
|
void registerSubscriptionMultipleSessions() {
|
||||||
List<String> sessIds = Arrays.asList("sess01", "sess02", "sess03");
|
List<String> sessIds = List.of("sess01", "sess02", "sess03");
|
||||||
List<String> subscriptionIds = Arrays.asList("subs01", "subs02", "subs03");
|
List<String> subscriptionIds = List.of("subs01", "subs02", "subs03");
|
||||||
String dest = "/foo";
|
String dest = "/foo";
|
||||||
|
|
||||||
for (String sessId : sessIds) {
|
for (String sessId : sessIds) {
|
||||||
|
|
@ -124,7 +117,6 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).hasSize(3);
|
assertThat(actual).hasSize(3);
|
||||||
assertThat(sort(actual.get(sessIds.get(0)))).isEqualTo(subscriptionIds);
|
assertThat(sort(actual.get(sessIds.get(0)))).isEqualTo(subscriptionIds);
|
||||||
assertThat(sort(actual.get(sessIds.get(1)))).isEqualTo(subscriptionIds);
|
assertThat(sort(actual.get(sessIds.get(1)))).isEqualTo(subscriptionIds);
|
||||||
|
|
@ -132,7 +124,7 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerSubscriptionWithDestinationPattern() {
|
void registerSubscriptionWithDestinationPattern() {
|
||||||
String sessId = "sess01";
|
String sessId = "sess01";
|
||||||
String subsId = "subs01";
|
String subsId = "subs01";
|
||||||
String destPattern = "/topic/PRICE.STOCK.*.IBM";
|
String destPattern = "/topic/PRICE.STOCK.*.IBM";
|
||||||
|
|
@ -140,13 +132,12 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
this.registry.registerSubscription(subscribeMessage(sessId, subsId, destPattern));
|
this.registry.registerSubscription(subscribeMessage(sessId, subsId, destPattern));
|
||||||
|
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
||||||
assertThat(actual).isNotNull();
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual).as("Expected one element " + actual).hasSize(1);
|
assertThat(actual.get(sessId)).containsExactly(subsId);
|
||||||
assertThat(actual.get(sessId)).isEqualTo(Collections.singletonList(subsId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // SPR-11657
|
@Test // SPR-11657
|
||||||
public void registerSubscriptionsWithSimpleAndPatternDestinations() {
|
void registerSubscriptionsWithSimpleAndPatternDestinations() {
|
||||||
String sess1 = "sess01";
|
String sess1 = "sess01";
|
||||||
String sess2 = "sess02";
|
String sess2 = "sess02";
|
||||||
|
|
||||||
|
|
@ -161,7 +152,6 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
this.registry.registerSubscription(subscribeMessage(sess1, subs1, "/topic/PRICE.STOCK.*.IBM"));
|
this.registry.registerSubscription(subscribeMessage(sess1, subs1, "/topic/PRICE.STOCK.*.IBM"));
|
||||||
|
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).hasSize(1);
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual.get(sess1)).containsExactlyInAnyOrder(subs2, subs1);
|
assertThat(actual.get(sess1)).containsExactlyInAnyOrder(subs2, subs1);
|
||||||
|
|
||||||
|
|
@ -170,51 +160,45 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
this.registry.registerSubscription(subscribeMessage(sess2, subs3, "/topic/PRICE.STOCK.NASDAQ.GOOG"));
|
this.registry.registerSubscription(subscribeMessage(sess2, subs3, "/topic/PRICE.STOCK.NASDAQ.GOOG"));
|
||||||
|
|
||||||
actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).hasSize(2);
|
assertThat(actual).hasSize(2);
|
||||||
assertThat(actual.get(sess1)).containsExactlyInAnyOrder(subs2, subs1);
|
assertThat(actual.get(sess1)).containsExactlyInAnyOrder(subs2, subs1);
|
||||||
assertThat(actual.get(sess2)).isEqualTo(Collections.singletonList(subs1));
|
assertThat(actual.get(sess2)).containsExactly(subs1);
|
||||||
|
|
||||||
this.registry.unregisterAllSubscriptions(sess1);
|
this.registry.unregisterAllSubscriptions(sess1);
|
||||||
|
|
||||||
actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).hasSize(1);
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual.get(sess2)).isEqualTo(Collections.singletonList(subs1));
|
assertThat(actual.get(sess2)).containsExactly(subs1);
|
||||||
|
|
||||||
this.registry.registerSubscription(subscribeMessage(sess1, subs1, "/topic/PRICE.STOCK.*.IBM"));
|
this.registry.registerSubscription(subscribeMessage(sess1, subs1, "/topic/PRICE.STOCK.*.IBM"));
|
||||||
this.registry.registerSubscription(subscribeMessage(sess1, subs2, destNasdaqIbm));
|
this.registry.registerSubscription(subscribeMessage(sess1, subs2, destNasdaqIbm));
|
||||||
|
|
||||||
actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).hasSize(2);
|
assertThat(actual).hasSize(2);
|
||||||
assertThat(actual.get(sess1)).containsExactlyInAnyOrder(subs1, subs2);
|
assertThat(actual.get(sess1)).containsExactlyInAnyOrder(subs1, subs2);
|
||||||
assertThat(actual.get(sess2)).isEqualTo(Collections.singletonList(subs1));
|
assertThat(actual.get(sess2)).containsExactly(subs1);
|
||||||
|
|
||||||
this.registry.unregisterSubscription(unsubscribeMessage(sess1, subs2));
|
this.registry.unregisterSubscription(unsubscribeMessage(sess1, subs2));
|
||||||
|
|
||||||
actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).hasSize(2);
|
assertThat(actual).hasSize(2);
|
||||||
assertThat(actual.get(sess1)).isEqualTo(Collections.singletonList(subs1));
|
assertThat(actual.get(sess1)).containsExactly(subs1);
|
||||||
assertThat(actual.get(sess2)).isEqualTo(Collections.singletonList(subs1));
|
assertThat(actual.get(sess2)).containsExactly(subs1);
|
||||||
|
|
||||||
this.registry.unregisterSubscription(unsubscribeMessage(sess1, subs1));
|
this.registry.unregisterSubscription(unsubscribeMessage(sess1, subs1));
|
||||||
|
|
||||||
actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).hasSize(1);
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual.get(sess2)).isEqualTo(Collections.singletonList(subs1));
|
assertThat(actual.get(sess2)).containsExactly(subs1);
|
||||||
|
|
||||||
this.registry.unregisterSubscription(unsubscribeMessage(sess2, subs1));
|
this.registry.unregisterSubscription(unsubscribeMessage(sess2, subs1));
|
||||||
|
|
||||||
actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
actual = this.registry.findSubscriptions(destNasdaqIbmMessage);
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).isEmpty();
|
assertThat(actual).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // SPR-11755
|
@Test // SPR-11755
|
||||||
public void registerAndUnregisterMultipleDestinations() {
|
void registerAndUnregisterMultipleDestinations() {
|
||||||
String sess1 = "sess01";
|
String sess1 = "sess01";
|
||||||
String sess2 = "sess02";
|
String sess2 = "sess02";
|
||||||
|
|
||||||
|
|
@ -247,7 +231,7 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerSubscriptionWithDestinationPatternRegex() {
|
void registerSubscriptionWithDestinationPatternRegex() {
|
||||||
String sessId = "sess01";
|
String sessId = "sess01";
|
||||||
String subsId = "subs01";
|
String subsId = "subs01";
|
||||||
String destPattern = "/topic/PRICE.STOCK.*.{ticker:(IBM|MSFT)}";
|
String destPattern = "/topic/PRICE.STOCK.*.{ticker:(IBM|MSFT)}";
|
||||||
|
|
@ -255,24 +239,21 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
this.registry.registerSubscription(subscribeMessage(sessId, subsId, destPattern));
|
this.registry.registerSubscription(subscribeMessage(sessId, subsId, destPattern));
|
||||||
Message<?> message = createMessage("/topic/PRICE.STOCK.NASDAQ.IBM");
|
Message<?> message = createMessage("/topic/PRICE.STOCK.NASDAQ.IBM");
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(message);
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(message);
|
||||||
assertThat(actual).isNotNull();
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual).as("Expected one element " + actual).hasSize(1);
|
assertThat(actual.get(sessId)).containsExactly(subsId);
|
||||||
assertThat(actual.get(sessId)).isEqualTo(Collections.singletonList(subsId));
|
|
||||||
|
|
||||||
message = createMessage("/topic/PRICE.STOCK.NASDAQ.MSFT");
|
message = createMessage("/topic/PRICE.STOCK.NASDAQ.MSFT");
|
||||||
actual = this.registry.findSubscriptions(message);
|
actual = this.registry.findSubscriptions(message);
|
||||||
assertThat(actual).isNotNull();
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual).as("Expected one element " + actual).hasSize(1);
|
assertThat(actual.get(sessId)).containsExactly(subsId);
|
||||||
assertThat(actual.get(sessId)).isEqualTo(Collections.singletonList(subsId));
|
|
||||||
|
|
||||||
message = createMessage("/topic/PRICE.STOCK.NASDAQ.VMW");
|
message = createMessage("/topic/PRICE.STOCK.NASDAQ.VMW");
|
||||||
actual = this.registry.findSubscriptions(message);
|
actual = this.registry.findSubscriptions(message);
|
||||||
assertThat(actual).isNotNull();
|
assertThat(actual).isEmpty();
|
||||||
assertThat(actual).as("Expected no elements " + actual).isEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerSubscriptionWithSelector() {
|
void registerSubscriptionWithSelector() {
|
||||||
String sessionId = "sess01";
|
String sessionId = "sess01";
|
||||||
String subscriptionId = "subs01";
|
String subscriptionId = "subs01";
|
||||||
String destination = "/foo";
|
String destination = "/foo";
|
||||||
|
|
@ -288,19 +269,17 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
Message<?> message = MessageBuilder.createMessage("", accessor.getMessageHeaders());
|
Message<?> message = MessageBuilder.createMessage("", accessor.getMessageHeaders());
|
||||||
|
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(message);
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(message);
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).hasSize(1);
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual.get(sessionId)).isEqualTo(Collections.singletonList(subscriptionId));
|
assertThat(actual.get(sessionId)).containsExactly(subscriptionId);
|
||||||
|
|
||||||
// Then without
|
// Then without selector header
|
||||||
|
|
||||||
actual = this.registry.findSubscriptions(createMessage(destination));
|
actual = this.registry.findSubscriptions(createMessage(destination));
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).isEmpty();
|
assertThat(actual).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerSubscriptionWithSelectorNotSupported() {
|
void registerSubscriptionWithSelectorNotSupported() {
|
||||||
String sessionId = "sess01";
|
String sessionId = "sess01";
|
||||||
String subscriptionId = "subs01";
|
String subscriptionId = "subs01";
|
||||||
String destination = "/foo";
|
String destination = "/foo";
|
||||||
|
|
@ -315,39 +294,35 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
Message<?> message = MessageBuilder.createMessage("", accessor.getMessageHeaders());
|
Message<?> message = MessageBuilder.createMessage("", accessor.getMessageHeaders());
|
||||||
|
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(message);
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(message);
|
||||||
assertThat(actual).isNotNull();
|
|
||||||
assertThat(actual).hasSize(1);
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual.get(sessionId)).isEqualTo(Collections.singletonList(subscriptionId));
|
assertThat(actual.get(sessionId)).containsExactly(subscriptionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // SPR-11931
|
@Test // SPR-11931
|
||||||
public void registerSubscriptionTwiceAndUnregister() {
|
void registerSubscriptionTwiceAndUnregister() {
|
||||||
this.registry.registerSubscription(subscribeMessage("sess01", "subs01", "/foo"));
|
this.registry.registerSubscription(subscribeMessage("sess01", "subs01", "/foo"));
|
||||||
this.registry.registerSubscription(subscribeMessage("sess01", "subs02", "/foo"));
|
this.registry.registerSubscription(subscribeMessage("sess01", "subs02", "/foo"));
|
||||||
|
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage("/foo"));
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage("/foo"));
|
||||||
assertThat(actual).isNotNull();
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual).as("Expected 1 element").hasSize(1);
|
assertThat(actual.get("sess01")).containsExactly("subs01", "subs02");
|
||||||
assertThat(actual.get("sess01")).isEqualTo(Arrays.asList("subs01", "subs02"));
|
|
||||||
|
|
||||||
this.registry.unregisterSubscription(unsubscribeMessage("sess01", "subs01"));
|
this.registry.unregisterSubscription(unsubscribeMessage("sess01", "subs01"));
|
||||||
|
|
||||||
actual = this.registry.findSubscriptions(createMessage("/foo"));
|
actual = this.registry.findSubscriptions(createMessage("/foo"));
|
||||||
assertThat(actual).isNotNull();
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual).as("Expected 1 element").hasSize(1);
|
assertThat(actual.get("sess01")).containsExactly("subs02");
|
||||||
assertThat(actual.get("sess01")).isEqualTo(Collections.singletonList("subs02"));
|
|
||||||
|
|
||||||
this.registry.unregisterSubscription(unsubscribeMessage("sess01", "subs02"));
|
this.registry.unregisterSubscription(unsubscribeMessage("sess01", "subs02"));
|
||||||
|
|
||||||
actual = this.registry.findSubscriptions(createMessage("/foo"));
|
actual = this.registry.findSubscriptions(createMessage("/foo"));
|
||||||
assertThat(actual).isNotNull();
|
assertThat(actual).isEmpty();
|
||||||
assertThat(actual).as("Expected no element").isEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unregisterSubscription() {
|
void unregisterSubscription() {
|
||||||
List<String> sessIds = Arrays.asList("sess01", "sess02", "sess03");
|
List<String> sessIds = List.of("sess01", "sess02", "sess03");
|
||||||
List<String> subscriptionIds = Arrays.asList("subs01", "subs02", "subs03");
|
List<String> subscriptionIds = List.of("subs01", "subs02", "subs03");
|
||||||
String dest = "/foo";
|
String dest = "/foo";
|
||||||
|
|
||||||
for (String sessId : sessIds) {
|
for (String sessId : sessIds) {
|
||||||
|
|
@ -361,16 +336,15 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
this.registry.unregisterSubscription(unsubscribeMessage(sessIds.get(0), subscriptionIds.get(2)));
|
this.registry.unregisterSubscription(unsubscribeMessage(sessIds.get(0), subscriptionIds.get(2)));
|
||||||
|
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
||||||
assertThat(actual).isNotNull();
|
assertThat(actual).hasSize(2);
|
||||||
assertThat(actual).as("Expected two elements: " + actual).hasSize(2);
|
|
||||||
assertThat(sort(actual.get(sessIds.get(1)))).isEqualTo(subscriptionIds);
|
assertThat(sort(actual.get(sessIds.get(1)))).isEqualTo(subscriptionIds);
|
||||||
assertThat(sort(actual.get(sessIds.get(2)))).isEqualTo(subscriptionIds);
|
assertThat(sort(actual.get(sessIds.get(2)))).isEqualTo(subscriptionIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unregisterAllSubscriptions() {
|
void unregisterAllSubscriptions() {
|
||||||
List<String> sessIds = Arrays.asList("sess01", "sess02", "sess03");
|
List<String> sessIds = List.of("sess01", "sess02", "sess03");
|
||||||
List<String> subscriptionIds = Arrays.asList("subs01", "subs02", "subs03");
|
List<String> subscriptionIds = List.of("subs01", "subs02", "subs03");
|
||||||
String dest = "/foo";
|
String dest = "/foo";
|
||||||
|
|
||||||
for (String sessId : sessIds) {
|
for (String sessId : sessIds) {
|
||||||
|
|
@ -383,31 +357,28 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
this.registry.unregisterAllSubscriptions(sessIds.get(1));
|
this.registry.unregisterAllSubscriptions(sessIds.get(1));
|
||||||
|
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage(dest));
|
||||||
assertThat(actual).isNotNull();
|
assertThat(actual).hasSize(1);
|
||||||
assertThat(actual).as("Expected one element: " + actual).hasSize(1);
|
|
||||||
assertThat(sort(actual.get(sessIds.get(2)))).isEqualTo(subscriptionIds);
|
assertThat(sort(actual.get(sessIds.get(2)))).isEqualTo(subscriptionIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unregisterAllSubscriptionsNoMatch() {
|
void unregisterAllSubscriptionsNoMatch() {
|
||||||
this.registry.unregisterAllSubscriptions("bogus");
|
this.registry.unregisterAllSubscriptions("bogus");
|
||||||
// no exceptions
|
// no exceptions
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findSubscriptionsNoMatches() {
|
void findSubscriptionsNoMatches() {
|
||||||
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage("/foo"));
|
MultiValueMap<String, String> actual = this.registry.findSubscriptions(createMessage("/foo"));
|
||||||
assertThat(actual).isNotNull();
|
assertThat(actual).isEmpty();
|
||||||
assertThat(actual).as("Expected no elements " + actual).isEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // SPR-12665
|
@Test // SPR-12665
|
||||||
public void findSubscriptionsReturnsMapSafeToIterate() throws Exception {
|
void findSubscriptionsReturnsMapSafeToIterate() throws Exception {
|
||||||
this.registry.registerSubscription(subscribeMessage("sess1", "1", "/foo"));
|
this.registry.registerSubscription(subscribeMessage("sess1", "1", "/foo"));
|
||||||
this.registry.registerSubscription(subscribeMessage("sess2", "1", "/foo"));
|
this.registry.registerSubscription(subscribeMessage("sess2", "1", "/foo"));
|
||||||
|
|
||||||
MultiValueMap<String, String> subscriptions = this.registry.findSubscriptions(createMessage("/foo"));
|
MultiValueMap<String, String> subscriptions = this.registry.findSubscriptions(createMessage("/foo"));
|
||||||
assertThat(subscriptions).isNotNull();
|
|
||||||
assertThat(subscriptions).hasSize(2);
|
assertThat(subscriptions).hasSize(2);
|
||||||
|
|
||||||
Iterator<Map.Entry<String, List<String>>> iterator = subscriptions.entrySet().iterator();
|
Iterator<Map.Entry<String, List<String>>> iterator = subscriptions.entrySet().iterator();
|
||||||
|
|
@ -420,12 +391,11 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // SPR-13185
|
@Test // SPR-13185
|
||||||
public void findSubscriptionsReturnsMapSafeToIterateIncludingValues() throws Exception {
|
void findSubscriptionsReturnsMapSafeToIterateIncludingValues() throws Exception {
|
||||||
this.registry.registerSubscription(subscribeMessage("sess1", "1", "/foo"));
|
this.registry.registerSubscription(subscribeMessage("sess1", "1", "/foo"));
|
||||||
this.registry.registerSubscription(subscribeMessage("sess1", "2", "/foo"));
|
this.registry.registerSubscription(subscribeMessage("sess1", "2", "/foo"));
|
||||||
|
|
||||||
MultiValueMap<String, String> allSubscriptions = this.registry.findSubscriptions(createMessage("/foo"));
|
MultiValueMap<String, String> allSubscriptions = this.registry.findSubscriptions(createMessage("/foo"));
|
||||||
assertThat(allSubscriptions).isNotNull();
|
|
||||||
assertThat(allSubscriptions).hasSize(1);
|
assertThat(allSubscriptions).hasSize(1);
|
||||||
|
|
||||||
Iterator<String> iteratorValues = allSubscriptions.get("sess1").iterator();
|
Iterator<String> iteratorValues = allSubscriptions.get("sess1").iterator();
|
||||||
|
|
@ -438,7 +408,7 @@ public class DefaultSubscriptionRegistryTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // SPR-13555
|
@Test // SPR-13555
|
||||||
public void cacheLimitExceeded() throws Exception {
|
void cacheLimitExceeded() throws Exception {
|
||||||
this.registry.setCacheLimit(1);
|
this.registry.setCacheLimit(1);
|
||||||
this.registry.registerSubscription(subscribeMessage("sess1", "1", "/foo"));
|
this.registry.registerSubscription(subscribeMessage("sess1", "1", "/foo"));
|
||||||
this.registry.registerSubscription(subscribeMessage("sess1", "2", "/bar"));
|
this.registry.registerSubscription(subscribeMessage("sess1", "2", "/bar"));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue