Optimize DefaultUserDestinationResolver.resolveDestination()
Issue: SPR-15602
This commit is contained in:
		
							parent
							
								
									1412c2c577
								
							
						
					
					
						commit
						0ef1623643
					
				|  | @ -121,12 +121,12 @@ 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<>(); | 		Set<String> targetSet = new HashSet<>(); | ||||||
| 		for (String sessionId : parseResult.getSessionIds()) { | 		for (String sessionId : parseResult.getSessionIds()) { | ||||||
| 			String actualDestination = parseResult.getActualDestination(); | 			String actualDestination = parseResult.getActualDestination(); | ||||||
|  | @ -142,65 +142,81 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver { | ||||||
| 	@Nullable | 	@Nullable | ||||||
| 	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); | ||||||
| 		Principal principal = SimpMessageHeaderAccessor.getUser(headers); | 		switch (messageType) { | ||||||
| 		String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); | 			case SUBSCRIBE: | ||||||
| 		if (SimpMessageType.SUBSCRIBE.equals(messageType) || SimpMessageType.UNSUBSCRIBE.equals(messageType)) { | 			case UNSUBSCRIBE: | ||||||
| 			if (sessionId == null) { | 				return parseSubscriptionMessage(message, headers, sourceDestination); | ||||||
| 				logger.error("No session id. Ignoring " + message); | 			case MESSAGE: | ||||||
|  | 				return parseMessage(headers, sourceDestination); | ||||||
|  | 			default: | ||||||
| 				return null; | 				return null; | ||||||
| 			} |  | ||||||
| 			int prefixEnd = this.prefix.length() - 1; |  | ||||||
| 			String actualDestination = destination.substring(prefixEnd); |  | ||||||
| 			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)) { | 	} | ||||||
| 			int prefixEnd = this.prefix.length(); | 
 | ||||||
| 			int userEnd = destination.indexOf('/', prefixEnd); | 	private ParseResult parseSubscriptionMessage(Message<?> message, MessageHeaders headers, String sourceDestination) { | ||||||
| 			Assert.isTrue(userEnd > 0, "Expected destination pattern \"/user/{userId}/**\""); | 		String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); | ||||||
| 			String actualDestination = destination.substring(userEnd); | 		if (sessionId == null) { | ||||||
| 			String subscribeDestination = this.prefix.substring(0, prefixEnd - 1) + actualDestination; | 			logger.error("No session id. Ignoring " + message); | ||||||
| 			String userName = destination.substring(prefixEnd, userEnd); | 			return null; | ||||||
| 			userName = StringUtils.replace(userName, "%2F", "/"); | 		} | ||||||
| 			Set<String> sessionIds; | 		int prefixEnd = this.prefix.length() - 1; | ||||||
| 			if (userName.equals(sessionId)) { | 		String actualDestination = sourceDestination.substring(prefixEnd); | ||||||
| 				userName = null; | 		if (!this.keepLeadingSlash) { | ||||||
|  | 			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 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); | ||||||
|  | 		Set<String> sessionIds; | ||||||
|  | 		if (userName.equals(sessionId)) { | ||||||
|  | 			userName = null; | ||||||
|  | 			sessionIds = Collections.singleton(sessionId); | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			sessionIds = getSessionIdsByUser(userName, sessionId); | ||||||
|  | 		} | ||||||
|  | 		if (!this.keepLeadingSlash) { | ||||||
|  | 			actualDestination = actualDestination.substring(1); | ||||||
|  | 		} | ||||||
|  | 		return new ParseResult(sourceDestination, actualDestination, subscribeDestination, sessionIds, userName); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private Set<String> getSessionIdsByUser(String userName, String sessionId) { | ||||||
|  | 		Set<String> sessionIds; | ||||||
|  | 		SimpUser user = this.userRegistry.getUser(userName); | ||||||
|  | 		if (user != null) { | ||||||
|  | 			if (user.getSession(sessionId) != 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<>(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<>(sessions.size()); |  | ||||||
| 						for (SimpSession session : sessions) { |  | ||||||
| 							sessionIds.add(session.getId()); |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				else { |  | ||||||
| 					sessionIds = Collections.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) { | ||||||
|  | @ -243,8 +259,11 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver { | ||||||
| 
 | 
 | ||||||
| 		private final String user; | 		private final String user; | ||||||
| 
 | 
 | ||||||
|  | 		private final String sourceDestination; | ||||||
| 
 | 
 | ||||||
| 		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; | ||||||
|  | @ -267,6 +286,10 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver { | ||||||
| 		public String getUser() { | 		public String getUser() { | ||||||
| 			return this.user; | 			return this.user; | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		public String getSourceDestination() { | ||||||
|  | 			return this.sourceDestination; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue