@Bean public UserDestinationResolver userDestinationResolver() { DefaultUserDestinationResolver resolver = new DefaultUserDestinationResolver(userRegistry()); String prefix = getBrokerRegistry().getUserDestinationPrefix(); if (prefix != null) { resolver.setUserDestinationPrefix(prefix); } return resolver; }
private ParseResult parseMessage(MessageHeaders headers, String sourceDest) { int prefixEnd = this.prefix.length(); int userEnd = sourceDest.indexOf('/', prefixEnd); Assert.isTrue(userEnd > 0, "Expected destination pattern \"/user/{userId}/**\""); String actualDest = sourceDest.substring(userEnd); String subscribeDest = this.prefix.substring(0, prefixEnd - 1) + actualDest; String userName = sourceDest.substring(prefixEnd, userEnd); userName = StringUtils.replace(userName, "%2F", "/"); String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); Set<String> sessionIds; if (userName.equals(sessionId)) { userName = null; sessionIds = Collections.singleton(sessionId); } else { sessionIds = getSessionIdsByUser(userName, sessionId); } if (isRemoveLeadingSlash()) { actualDest = actualDest.substring(1); } return new ParseResult(sourceDest, actualDest, subscribeDest, sessionIds, userName); }
private void updateUserDestinationResolver(AbstractBrokerMessageHandler handler) { Collection<String> prefixes = handler.getDestinationPrefixes(); if (!prefixes.isEmpty() && !prefixes.iterator().next().startsWith("/")) { ((DefaultUserDestinationResolver) userDestinationResolver()).setRemoveLeadingSlash(true); } }
@Nullable private ParseResult parse(Message<?> message) { MessageHeaders headers = message.getHeaders(); String sourceDestination = SimpMessageHeaderAccessor.getDestination(headers); if (sourceDestination == null || !checkDestination(sourceDestination, this.prefix)) { return null; } SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(headers); if (messageType != null) { switch (messageType) { case SUBSCRIBE: case UNSUBSCRIBE: return parseSubscriptionMessage(message, sourceDestination); case MESSAGE: return parseMessage(headers, sourceDestination); } } return null; }
@Override @Nullable public UserDestinationResult resolveDestination(Message<?> message) { ParseResult parseResult = parse(message); if (parseResult == null) { return null; } String user = parseResult.getUser(); String sourceDestination = parseResult.getSourceDestination(); Set<String> targetSet = new HashSet<>(); for (String sessionId : parseResult.getSessionIds()) { String actualDestination = parseResult.getActualDestination(); String targetDestination = getTargetDestination( sourceDestination, actualDestination, sessionId, user); if (targetDestination != null) { targetSet.add(targetDestination); } } String subscribeDestination = parseResult.getSubscribeDestination(); return new UserDestinationResult(sourceDestination, targetSet, subscribeDestination, user); }
@Nullable private ParseResult parseSubscriptionMessage(Message<?> message, String sourceDestination) { MessageHeaders headers = message.getHeaders(); String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); if (sessionId == null) { logger.error("No session id. Ignoring " + message); return null; } int prefixEnd = this.prefix.length() - 1; String actualDestination = sourceDestination.substring(prefixEnd); if (isRemoveLeadingSlash()) { actualDestination = actualDestination.substring(1); } Principal principal = SimpMessageHeaderAccessor.getUser(headers); String user = (principal != null ? principal.getName() : null); Set<String> sessionIds = Collections.singleton(sessionId); return new ParseResult(sourceDestination, actualDestination, sourceDestination, sessionIds, user); }
@Test // SPR-14044 public void handleMessageForDestinationWithDotSeparator() { this.resolver.setRemoveLeadingSlash(true); TestPrincipal user = new TestPrincipal("joe"); String destination = "/user/joe/jms.queue.call"; Message<?> message = createMessage(SimpMessageType.MESSAGE, user, "123", destination); UserDestinationResult actual = this.resolver.resolveDestination(message); assertEquals(1, actual.getTargetDestinations().size()); assertEquals("jms.queue.call-user123", actual.getTargetDestinations().iterator().next()); assertEquals("/user/jms.queue.call", actual.getSubscribeDestination()); }
@Before public void setup() { TestSimpUser simpUser = new TestSimpUser("joe"); simpUser.addSessions(new TestSimpSession("123")); this.registry = mock(SimpUserRegistry.class); when(this.registry.getUser("joe")).thenReturn(simpUser); this.resolver = new DefaultUserDestinationResolver(this.registry); }
@Nullable private ParseResult parse(Message<?> message) { MessageHeaders headers = message.getHeaders(); String sourceDestination = SimpMessageHeaderAccessor.getDestination(headers); if (sourceDestination == null || !checkDestination(sourceDestination, this.prefix)) { return null; } SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(headers); if (messageType != null) { switch (messageType) { case SUBSCRIBE: case UNSUBSCRIBE: return parseSubscriptionMessage(message, sourceDestination); case MESSAGE: return parseMessage(headers, sourceDestination); } } return null; }
@Override @Nullable public UserDestinationResult resolveDestination(Message<?> message) { ParseResult parseResult = parse(message); if (parseResult == null) { return null; } String user = parseResult.getUser(); String sourceDestination = parseResult.getSourceDestination(); Set<String> targetSet = new HashSet<>(); for (String sessionId : parseResult.getSessionIds()) { String actualDestination = parseResult.getActualDestination(); String targetDestination = getTargetDestination( sourceDestination, actualDestination, sessionId, user); if (targetDestination != null) { targetSet.add(targetDestination); } } String subscribeDestination = parseResult.getSubscribeDestination(); return new UserDestinationResult(sourceDestination, targetSet, subscribeDestination, user); }
@Test public void customPathMatcher() { ApplicationContext context = loadConfig(CustomConfig.class); SimpleBrokerMessageHandler broker = context.getBean(SimpleBrokerMessageHandler.class); DefaultSubscriptionRegistry registry = (DefaultSubscriptionRegistry) broker.getSubscriptionRegistry(); assertEquals("a.a", registry.getPathMatcher().combine("a", "a")); PathMatcher pathMatcher = context.getBean(SimpAnnotationMethodMessageHandler.class).getPathMatcher(); assertEquals("a.a", pathMatcher.combine("a", "a")); DefaultUserDestinationResolver resolver = context.getBean(DefaultUserDestinationResolver.class); assertNotNull(resolver); assertEquals(false, resolver.isRemoveLeadingSlash()); }
@Test // SPR-14044 public void handleSubscribeForDestinationWithoutLeadingSlash() { this.resolver.setRemoveLeadingSlash(true); TestPrincipal user = new TestPrincipal("joe"); String destination = "/user/jms.queue.call"; Message<?> message = createMessage(SimpMessageType.SUBSCRIBE, user, "123", destination); UserDestinationResult actual = this.resolver.resolveDestination(message); assertEquals(1, actual.getTargetDestinations().size()); assertEquals("jms.queue.call-user123", actual.getTargetDestinations().iterator().next()); assertEquals(destination, actual.getSubscribeDestination()); }
@Before public void setup() { this.registry = mock(SimpUserRegistry.class); this.brokerChannel = mock(SubscribableChannel.class); UserDestinationResolver resolver = new DefaultUserDestinationResolver(this.registry); this.handler = new UserDestinationMessageHandler(new StubMessageChannel(), this.brokerChannel, resolver); }
@Nullable private ParseResult parse(Message<?> message) { MessageHeaders headers = message.getHeaders(); String sourceDestination = SimpMessageHeaderAccessor.getDestination(headers); if (sourceDestination == null || !checkDestination(sourceDestination, this.prefix)) { return null; } SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(headers); if (messageType != null) { switch (messageType) { case SUBSCRIBE: case UNSUBSCRIBE: return parseSubscriptionMessage(message, sourceDestination); case MESSAGE: return parseMessage(headers, sourceDestination); } } return null; }
@Bean public UserDestinationResolver userDestinationResolver() { DefaultUserDestinationResolver resolver = new DefaultUserDestinationResolver(userRegistry()); String prefix = getBrokerRegistry().getUserDestinationPrefix(); if (prefix != null) { resolver.setUserDestinationPrefix(prefix); } return resolver; }
private ParseResult parseMessage(MessageHeaders headers, String sourceDest) { int prefixEnd = this.prefix.length(); int userEnd = sourceDest.indexOf('/', prefixEnd); Assert.isTrue(userEnd > 0, "Expected destination pattern \"/user/{userId}/**\""); String actualDest = sourceDest.substring(userEnd); String subscribeDest = this.prefix.substring(0, prefixEnd - 1) + actualDest; String userName = sourceDest.substring(prefixEnd, userEnd); userName = StringUtils.replace(userName, "%2F", "/"); String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); Set<String> sessionIds; if (userName.equals(sessionId)) { userName = null; sessionIds = Collections.singleton(sessionId); } else { sessionIds = getSessionIdsByUser(userName, sessionId); } if (isRemoveLeadingSlash()) { actualDest = actualDest.substring(1); } return new ParseResult(sourceDest, actualDest, subscribeDest, sessionIds, userName); }
@Override @Nullable public UserDestinationResult resolveDestination(Message<?> message) { ParseResult parseResult = parse(message); if (parseResult == null) { return null; } String user = parseResult.getUser(); String sourceDestination = parseResult.getSourceDestination(); Set<String> targetSet = new HashSet<>(); for (String sessionId : parseResult.getSessionIds()) { String actualDestination = parseResult.getActualDestination(); String targetDestination = getTargetDestination( sourceDestination, actualDestination, sessionId, user); if (targetDestination != null) { targetSet.add(targetDestination); } } String subscribeDestination = parseResult.getSubscribeDestination(); return new UserDestinationResult(sourceDestination, targetSet, subscribeDestination, user); }
@Nullable private ParseResult parseSubscriptionMessage(Message<?> message, String sourceDestination) { MessageHeaders headers = message.getHeaders(); String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); if (sessionId == null) { logger.error("No session id. Ignoring " + message); return null; } int prefixEnd = this.prefix.length() - 1; String actualDestination = sourceDestination.substring(prefixEnd); if (isRemoveLeadingSlash()) { actualDestination = actualDestination.substring(1); } Principal principal = SimpMessageHeaderAccessor.getUser(headers); String user = (principal != null ? principal.getName() : null); Set<String> sessionIds = Collections.singleton(sessionId); return new ParseResult(sourceDestination, actualDestination, sourceDestination, sessionIds, user); }
private void updateUserDestinationResolver(AbstractBrokerMessageHandler handler) { Collection<String> prefixes = handler.getDestinationPrefixes(); if (!prefixes.isEmpty() && !prefixes.iterator().next().startsWith("/")) { ((DefaultUserDestinationResolver) userDestinationResolver()).setRemoveLeadingSlash(true); } }
@Nullable private ParseResult parse(Message<?> message) { MessageHeaders headers = message.getHeaders(); String sourceDestination = SimpMessageHeaderAccessor.getDestination(headers); if (sourceDestination == null || !checkDestination(sourceDestination, this.prefix)) { return null; } SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(headers); if (messageType != null) { switch (messageType) { case SUBSCRIBE: case UNSUBSCRIBE: return parseSubscriptionMessage(message, sourceDestination); case MESSAGE: return parseMessage(headers, sourceDestination); } } return null; }