Browse Source

Optimize DefaultUserDestinationResolver.resolveDestination()

Issue: SPR-15602
pull/1290/merge
Christoph Dreis 9 years ago committed by Rossen Stoyanchev
parent
commit
6aeb8ef56d
  1. 127
      spring-messaging/src/main/java/org/springframework/messaging/simp/user/DefaultUserDestinationResolver.java

127
spring-messaging/src/main/java/org/springframework/messaging/simp/user/DefaultUserDestinationResolver.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 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.
@ -120,16 +120,17 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver {
@Override @Override
public UserDestinationResult resolveDestination(Message<?> message) { public UserDestinationResult resolveDestination(Message<?> message) {
String sourceDestination = SimpMessageHeaderAccessor.getDestination(message.getHeaders());
ParseResult parseResult = parse(message); ParseResult parseResult = parse(message);
if (parseResult == null) { if (parseResult == null) {
return null; return null;
} }
String user = parseResult.getUser(); String user = parseResult.getUser();
String sourceDestination = parseResult.getSourceDestination();
Set<String> targetSet = new HashSet<String>(); Set<String> targetSet = new HashSet<String>();
for (String sessionId : parseResult.getSessionIds()) { for (String sessionId : parseResult.getSessionIds()) {
String actualDestination = parseResult.getActualDestination(); String actualDestination = parseResult.getActualDestination();
String targetDestination = getTargetDestination(sourceDestination, actualDestination, sessionId, user); String targetDestination = getTargetDestination(
sourceDestination, actualDestination, sessionId, user);
if (targetDestination != null) { if (targetDestination != null) {
targetSet.add(targetDestination); targetSet.add(targetDestination);
} }
@ -140,65 +141,84 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver {
private ParseResult parse(Message<?> message) { private ParseResult parse(Message<?> message) {
MessageHeaders headers = message.getHeaders(); MessageHeaders headers = message.getHeaders();
String destination = SimpMessageHeaderAccessor.getDestination(headers); String sourceDestination = SimpMessageHeaderAccessor.getDestination(headers);
if (destination == null || !checkDestination(destination, this.prefix)) { if (sourceDestination == null || !checkDestination(sourceDestination, this.prefix)) {
return null; return null;
} }
SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(headers); SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(headers);
switch (messageType) {
case SUBSCRIBE:
case UNSUBSCRIBE:
return parseSubscriptionMessage(message, sourceDestination);
case MESSAGE:
return parseMessage(headers, sourceDestination);
default:
return null;
}
}
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 (!this.keepLeadingSlash) {
actualDestination = actualDestination.substring(1);
}
Principal principal = SimpMessageHeaderAccessor.getUser(headers); 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 ParseResult parseMessage(MessageHeaders headers, String sourceDestination) {
int prefixEnd = this.prefix.length();
int userEnd = sourceDestination.indexOf('/', prefixEnd);
Assert.isTrue(userEnd > 0, "Expected destination pattern \"/user/{userId}/**\"");
String actualDestination = sourceDestination.substring(userEnd);
String subscribeDestination = this.prefix.substring(0, prefixEnd - 1) + actualDestination;
String userName = sourceDestination.substring(prefixEnd, userEnd);
userName = StringUtils.replace(userName, "%2F", "/");
String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); String sessionId = SimpMessageHeaderAccessor.getSessionId(headers);
if (SimpMessageType.SUBSCRIBE.equals(messageType) || SimpMessageType.UNSUBSCRIBE.equals(messageType)) { Set<String> sessionIds;
if (sessionId == null) { if (userName.equals(sessionId)) {
logger.error("No session id. Ignoring " + message); userName = null;
return null; sessionIds = Collections.singleton(sessionId);
} }
int prefixEnd = this.prefix.length() - 1; else {
String actualDestination = destination.substring(prefixEnd); sessionIds = getSessionIdsByUser(userName, sessionId);
if (!this.keepLeadingSlash) { }
actualDestination = actualDestination.substring(1); if (!this.keepLeadingSlash) {
} actualDestination = actualDestination.substring(1);
String user = (principal != null ? principal.getName() : null);
return new ParseResult(actualDestination, destination, Collections.singleton(sessionId), user);
} }
else if (SimpMessageType.MESSAGE.equals(messageType)) { return new ParseResult(sourceDestination, actualDestination, subscribeDestination,
int prefixEnd = this.prefix.length(); sessionIds, userName);
int userEnd = destination.indexOf('/', prefixEnd); }
Assert.isTrue(userEnd > 0, "Expected destination pattern \"/user/{userId}/**\"");
String actualDestination = destination.substring(userEnd); private Set<String> getSessionIdsByUser(String userName, String sessionId) {
String subscribeDestination = this.prefix.substring(0, prefixEnd - 1) + actualDestination; Set<String> sessionIds;
String userName = destination.substring(prefixEnd, userEnd); SimpUser user = this.userRegistry.getUser(userName);
userName = StringUtils.replace(userName, "%2F", "/"); if (user != null) {
Set<String> sessionIds; if (user.getSession(sessionId) != null) {
if (userName.equals(sessionId)) {
userName = null;
sessionIds = Collections.singleton(sessionId); sessionIds = Collections.singleton(sessionId);
} }
else { else {
SimpUser user = this.userRegistry.getUser(userName); Set<SimpSession> sessions = user.getSessions();
if (user != null) { sessionIds = new HashSet<String>(sessions.size());
if (user.getSession(sessionId) != null) { for (SimpSession session : sessions) {
sessionIds = Collections.singleton(sessionId); sessionIds.add(session.getId());
}
else {
Set<SimpSession> sessions = user.getSessions();
sessionIds = new HashSet<String>(sessions.size());
for (SimpSession session : sessions) {
sessionIds.add(session.getId());
}
}
}
else {
sessionIds = Collections.<String>emptySet();
} }
} }
if (!this.keepLeadingSlash) {
actualDestination = actualDestination.substring(1);
}
return new ParseResult(actualDestination, subscribeDestination, sessionIds, userName);
} }
else { else {
return null; sessionIds = Collections.emptySet();
} }
return sessionIds;
} }
protected boolean checkDestination(String destination, String requiredPrefix) { protected boolean checkDestination(String destination, String requiredPrefix) {
@ -232,6 +252,8 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver {
*/ */
private static class ParseResult { private static class ParseResult {
private final String sourceDestination;
private final String actualDestination; private final String actualDestination;
private final String subscribeDestination; private final String subscribeDestination;
@ -241,7 +263,10 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver {
private final String user; private final String user;
public ParseResult(String actualDest, String subscribeDest, Set<String> sessionIds, String user) { public ParseResult(String sourceDest, String actualDest, String subscribeDest,
Set<String> sessionIds, String user) {
this.sourceDestination = sourceDest;
this.actualDestination = actualDest; this.actualDestination = actualDest;
this.subscribeDestination = subscribeDest; this.subscribeDestination = subscribeDest;
this.sessionIds = sessionIds; this.sessionIds = sessionIds;
@ -249,6 +274,10 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver {
} }
public String getSourceDestination() {
return this.sourceDestination;
}
public String getActualDestination() { public String getActualDestination() {
return this.actualDestination; return this.actualDestination;
} }

Loading…
Cancel
Save