Polish SimpUserRegistry related classes
Issue: SPR-13800
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -52,6 +52,7 @@ import org.springframework.messaging.support.ExecutorSubscribableChannel;
|
||||
import org.springframework.messaging.support.ImmutableMessageChannelInterceptor;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
import org.springframework.util.PathMatcher;
|
||||
@@ -315,8 +316,11 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
|
||||
if (getBrokerRegistry().getUserRegistryBroadcast() == null) {
|
||||
return new NoOpMessageHandler();
|
||||
}
|
||||
return new UserRegistryMessageHandler(userRegistry(), brokerMessagingTemplate(),
|
||||
getBrokerRegistry().getUserRegistryBroadcast(), messageBrokerTaskScheduler());
|
||||
SimpUserRegistry userRegistry = userRegistry();
|
||||
Assert.isInstanceOf(MultiServerUserRegistry.class, userRegistry);
|
||||
return new UserRegistryMessageHandler((MultiServerUserRegistry) userRegistry,
|
||||
brokerMessagingTemplate(), getBrokerRegistry().getUserRegistryBroadcast(),
|
||||
messageBrokerTaskScheduler());
|
||||
}
|
||||
|
||||
// Expose alias for 4.1 compatibility
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -35,10 +35,11 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* A user registry that is a composite of the "local" user registry as well as
|
||||
* snapshots of remote user registries. For use with
|
||||
* {@link UserRegistryMessageHandler} which broadcasts periodically the content
|
||||
* of the local registry and receives updates from other servers.
|
||||
* {@code SimpUserRegistry} that looks up users in a "local" user registry as
|
||||
* well as a set of "remote" user registries. The local registry is provided as
|
||||
* a constructor argument while remote registries are updated via broadcasts
|
||||
* handled by {@link UserRegistryMessageHandler} which in turn notifies this
|
||||
* registry when updates are received.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.2
|
||||
@@ -50,10 +51,9 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
|
||||
private final SimpUserRegistry localRegistry;
|
||||
|
||||
private final SmartApplicationListener listener;
|
||||
private final Map<String, UserRegistrySnapshot> remoteRegistries = new ConcurrentHashMap<String, UserRegistrySnapshot>();
|
||||
|
||||
private final Map<String, UserRegistryDto> remoteRegistries =
|
||||
new ConcurrentHashMap<String, UserRegistryDto>();
|
||||
private final boolean delegateApplicationEvents;
|
||||
|
||||
|
||||
/**
|
||||
@@ -61,13 +61,11 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
*/
|
||||
public MultiServerUserRegistry(SimpUserRegistry localRegistry) {
|
||||
Assert.notNull(localRegistry, "'localRegistry' is required.");
|
||||
this.localRegistry = localRegistry;
|
||||
this.listener = (this.localRegistry instanceof SmartApplicationListener ?
|
||||
(SmartApplicationListener) this.localRegistry : new NoOpSmartApplicationListener());
|
||||
this.id = generateId();
|
||||
this.localRegistry = localRegistry;
|
||||
this.delegateApplicationEvents = this.localRegistry instanceof SmartApplicationListener;
|
||||
}
|
||||
|
||||
|
||||
private static String generateId() {
|
||||
String host;
|
||||
try {
|
||||
@@ -80,14 +78,43 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return (this.delegateApplicationEvents ?
|
||||
((SmartApplicationListener) this.localRegistry).getOrder() : Ordered.LOWEST_PRECEDENCE);
|
||||
}
|
||||
|
||||
// SmartApplicationListener methods
|
||||
|
||||
@Override
|
||||
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
|
||||
return (this.delegateApplicationEvents &&
|
||||
((SmartApplicationListener) this.localRegistry).supportsEventType(eventType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSourceType(Class<?> sourceType) {
|
||||
return (this.delegateApplicationEvents &&
|
||||
((SmartApplicationListener) this.localRegistry).supportsSourceType(sourceType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (this.delegateApplicationEvents) {
|
||||
((SmartApplicationListener) this.localRegistry).onApplicationEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
// SimpUserRegistry methods
|
||||
|
||||
@Override
|
||||
public SimpUser getUser(String userName) {
|
||||
SimpUser user = this.localRegistry.getUser(userName);
|
||||
if (user != null) {
|
||||
return user;
|
||||
}
|
||||
for (UserRegistryDto registry : this.remoteRegistries.values()) {
|
||||
user = registry.getUsers().get(userName);
|
||||
for (UserRegistrySnapshot registry : this.remoteRegistries.values()) {
|
||||
user = registry.getUserMap().get(userName);
|
||||
if (user != null) {
|
||||
return user;
|
||||
}
|
||||
@@ -97,94 +124,89 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
|
||||
@Override
|
||||
public Set<SimpUser> getUsers() {
|
||||
Set<SimpUser> result = new HashSet<SimpUser>(this.localRegistry.getUsers());
|
||||
for (UserRegistryDto registry : this.remoteRegistries.values()) {
|
||||
result.addAll(registry.getUsers().values());
|
||||
Set<SimpUser> result = new HashSet<SimpUser>();
|
||||
result.addAll(this.localRegistry.getUsers());
|
||||
for (UserRegistrySnapshot registry : this.remoteRegistries.values()) {
|
||||
result.addAll(registry.getUserMap().values());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SimpSubscription> findSubscriptions(SimpSubscriptionMatcher matcher) {
|
||||
Set<SimpSubscription> result = new HashSet<SimpSubscription>(this.localRegistry.findSubscriptions(matcher));
|
||||
for (UserRegistryDto registry : this.remoteRegistries.values()) {
|
||||
Set<SimpSubscription> result = new HashSet<SimpSubscription>();
|
||||
result.addAll(this.localRegistry.findSubscriptions(matcher));
|
||||
for (UserRegistrySnapshot registry : this.remoteRegistries.values()) {
|
||||
result.addAll(registry.findSubscriptions(matcher));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
|
||||
return this.listener.supportsEventType(eventType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSourceType(Class<?> sourceType) {
|
||||
return this.listener.supportsSourceType(sourceType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
this.listener.onApplicationEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.listener.getOrder();
|
||||
}
|
||||
// Internal methods for UserRegistryMessageHandler to manage broadcasts
|
||||
|
||||
Object getLocalRegistryDto() {
|
||||
return new UserRegistryDto(this.id, this.localRegistry);
|
||||
return new UserRegistrySnapshot(this.id, this.localRegistry);
|
||||
}
|
||||
|
||||
void addRemoteRegistryDto(Message<?> message, MessageConverter converter, long expirationPeriod) {
|
||||
UserRegistryDto registryDto = (UserRegistryDto) converter.fromMessage(message, UserRegistryDto.class);
|
||||
if (registryDto != null && !registryDto.getId().equals(this.id)) {
|
||||
long expirationTime = System.currentTimeMillis() + expirationPeriod;
|
||||
registryDto.setExpirationTime(expirationTime);
|
||||
registryDto.restoreParentReferences();
|
||||
this.remoteRegistries.put(registryDto.getId(), registryDto);
|
||||
UserRegistrySnapshot registry = (UserRegistrySnapshot) converter.fromMessage(message, UserRegistrySnapshot.class);
|
||||
if (registry != null && !registry.getId().equals(this.id)) {
|
||||
registry.init(expirationPeriod);
|
||||
this.remoteRegistries.put(registry.getId(), registry);
|
||||
}
|
||||
}
|
||||
|
||||
void purgeExpiredRegistries() {
|
||||
long now = System.currentTimeMillis();
|
||||
Iterator<Map.Entry<String, UserRegistryDto>> iterator = this.remoteRegistries.entrySet().iterator();
|
||||
Iterator<Map.Entry<String, UserRegistrySnapshot>> iterator = this.remoteRegistries.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, UserRegistryDto> entry = iterator.next();
|
||||
if (now > entry.getValue().getExpirationTime()) {
|
||||
Map.Entry<String, UserRegistrySnapshot> entry = iterator.next();
|
||||
if (entry.getValue().isExpired(now)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "local=[" + this.localRegistry + "], remote=" + this.remoteRegistries + "]";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Holds a copy of a SimpUserRegistry for the purpose of broadcasting to and
|
||||
* receiving broadcasts from other application servers.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private static class UserRegistryDto {
|
||||
private static class UserRegistrySnapshot {
|
||||
|
||||
private String id;
|
||||
|
||||
private Map<String, SimpUserDto> users;
|
||||
private Map<String, TransferSimpUser> users;
|
||||
|
||||
private long expirationTime;
|
||||
|
||||
public UserRegistryDto() {
|
||||
|
||||
/**
|
||||
* Default constructor for JSON deserialization.
|
||||
*/
|
||||
public UserRegistrySnapshot() {
|
||||
}
|
||||
|
||||
public UserRegistryDto(String id, SimpUserRegistry registry) {
|
||||
/**
|
||||
* Constructor to create DTO from a local user registry.
|
||||
*/
|
||||
public UserRegistrySnapshot(String id, SimpUserRegistry registry) {
|
||||
this.id = id;
|
||||
Set<SimpUser> users = registry.getUsers();
|
||||
this.users = new HashMap<String, SimpUserDto>(users.size());
|
||||
this.users = new HashMap<String, TransferSimpUser>(users.size());
|
||||
for (SimpUser user : users) {
|
||||
this.users.put(user.getName(), new SimpUserDto(user));
|
||||
this.users.put(user.getName(), new TransferSimpUser(user));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
@@ -193,18 +215,31 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setUsers(Map<String, SimpUserDto> users) {
|
||||
public void setUserMap(Map<String, TransferSimpUser> users) {
|
||||
this.users = users;
|
||||
}
|
||||
|
||||
public Map<String, SimpUserDto> getUsers() {
|
||||
public Map<String, TransferSimpUser> getUserMap() {
|
||||
return this.users;
|
||||
}
|
||||
|
||||
public boolean isExpired(long now) {
|
||||
return (now > this.expirationTime);
|
||||
}
|
||||
|
||||
|
||||
public void init(long expirationPeriod) {
|
||||
this.expirationTime = System.currentTimeMillis() + expirationPeriod;
|
||||
for (TransferSimpUser user : this.users.values()) {
|
||||
user.afterDeserialization();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Set<SimpSubscription> findSubscriptions(SimpSubscriptionMatcher matcher) {
|
||||
Set<SimpSubscription> result = new HashSet<SimpSubscription>();
|
||||
for (SimpUserDto user : this.users.values()) {
|
||||
for (SimpSessionDto session : user.sessions) {
|
||||
for (TransferSimpUser user : this.users.values()) {
|
||||
for (TransferSimpSession session : user.sessions) {
|
||||
for (SimpSubscription subscription : session.subscriptions) {
|
||||
if (matcher.match(subscription)) {
|
||||
result.add(subscription);
|
||||
@@ -215,46 +250,46 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setExpirationTime(long expirationTime) {
|
||||
this.expirationTime = expirationTime;
|
||||
}
|
||||
|
||||
public long getExpirationTime() {
|
||||
return this.expirationTime;
|
||||
}
|
||||
|
||||
private void restoreParentReferences() {
|
||||
for (SimpUserDto user : this.users.values()) {
|
||||
user.restoreParentReferences();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "id=" + this.id + ", users=" + this.users;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SimpUser that can be (de)serialized and broadcast to other servers.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private static class SimpUserDto implements SimpUser {
|
||||
private static class TransferSimpUser implements SimpUser {
|
||||
|
||||
private String name;
|
||||
|
||||
private Set<SimpSessionDto> sessions;
|
||||
private Set<TransferSimpSession> sessions;
|
||||
|
||||
public SimpUserDto() {
|
||||
this.sessions = new HashSet<SimpSessionDto>(1);
|
||||
|
||||
/**
|
||||
* Default constructor for JSON deserialization.
|
||||
*/
|
||||
public TransferSimpUser() {
|
||||
this.sessions = new HashSet<TransferSimpSession>(1);
|
||||
}
|
||||
|
||||
public SimpUserDto(SimpUser user) {
|
||||
/**
|
||||
* Constructor to create user from a local user.
|
||||
*/
|
||||
public TransferSimpUser(SimpUser user) {
|
||||
this.name = user.getName();
|
||||
Set<SimpSession> sessions = user.getSessions();
|
||||
this.sessions = new HashSet<SimpSessionDto>(sessions.size());
|
||||
this.sessions = new HashSet<TransferSimpSession>(sessions.size());
|
||||
for (SimpSession session : sessions) {
|
||||
this.sessions.add(new SimpSessionDto(session));
|
||||
this.sessions.add(new TransferSimpSession(session));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
@@ -270,8 +305,8 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpSessionDto getSession(String sessionId) {
|
||||
for (SimpSessionDto session : this.sessions) {
|
||||
public SimpSession getSession(String sessionId) {
|
||||
for (TransferSimpSession session : this.sessions) {
|
||||
if (session.getId().equals(sessionId)) {
|
||||
return session;
|
||||
}
|
||||
@@ -279,7 +314,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setSessions(Set<SimpSessionDto> sessions) {
|
||||
public void setSessions(Set<TransferSimpSession> sessions) {
|
||||
this.sessions.addAll(sessions);
|
||||
}
|
||||
|
||||
@@ -288,10 +323,10 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
return new HashSet<SimpSession>(this.sessions);
|
||||
}
|
||||
|
||||
private void restoreParentReferences() {
|
||||
for (SimpSessionDto session : this.sessions) {
|
||||
private void afterDeserialization() {
|
||||
for (TransferSimpSession session : this.sessions) {
|
||||
session.setUser(this);
|
||||
session.restoreParentReferences();
|
||||
session.afterDeserialization();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,26 +346,35 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SimpSession that can be (de)serialized and broadcast to other servers.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private static class SimpSessionDto implements SimpSession {
|
||||
private static class TransferSimpSession implements SimpSession {
|
||||
|
||||
private String id;
|
||||
|
||||
private SimpUserDto user;
|
||||
private TransferSimpUser user;
|
||||
|
||||
private final Set<SimpSubscriptionDto> subscriptions;
|
||||
private final Set<TransferSimpSubscription> subscriptions;
|
||||
|
||||
public SimpSessionDto() {
|
||||
this.subscriptions = new HashSet<SimpSubscriptionDto>(4);
|
||||
|
||||
/**
|
||||
* Default constructor for JSON deserialization.
|
||||
*/
|
||||
public TransferSimpSession() {
|
||||
this.subscriptions = new HashSet<TransferSimpSubscription>(4);
|
||||
}
|
||||
|
||||
public SimpSessionDto(SimpSession session) {
|
||||
/**
|
||||
* Constructor to create DTO from the local user session.
|
||||
*/
|
||||
public TransferSimpSession(SimpSession session) {
|
||||
this.id = session.getId();
|
||||
Set<SimpSubscription> subscriptions = session.getSubscriptions();
|
||||
this.subscriptions = new HashSet<SimpSubscriptionDto>(subscriptions.size());
|
||||
this.subscriptions = new HashSet<TransferSimpSubscription>(subscriptions.size());
|
||||
for (SimpSubscription subscription : subscriptions) {
|
||||
this.subscriptions.add(new SimpSubscriptionDto(subscription));
|
||||
this.subscriptions.add(new TransferSimpSubscription(subscription));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,16 +387,16 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setUser(SimpUserDto user) {
|
||||
public void setUser(TransferSimpUser user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpUserDto getUser() {
|
||||
public TransferSimpUser getUser() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
public void setSubscriptions(Set<SimpSubscriptionDto> subscriptions) {
|
||||
public void setSubscriptions(Set<TransferSimpSubscription> subscriptions) {
|
||||
this.subscriptions.addAll(subscriptions);
|
||||
}
|
||||
|
||||
@@ -361,8 +405,8 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
return new HashSet<SimpSubscription>(this.subscriptions);
|
||||
}
|
||||
|
||||
private void restoreParentReferences() {
|
||||
for (SimpSubscriptionDto subscription : this.subscriptions) {
|
||||
private void afterDeserialization() {
|
||||
for (TransferSimpSubscription subscription : this.subscriptions) {
|
||||
subscription.setSession(this);
|
||||
}
|
||||
}
|
||||
@@ -383,24 +427,34 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SimpSubscription that can be (de)serialized and broadcast to other servers.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private static class SimpSubscriptionDto implements SimpSubscription {
|
||||
private static class TransferSimpSubscription implements SimpSubscription {
|
||||
|
||||
private String id;
|
||||
|
||||
private SimpSessionDto session;
|
||||
private TransferSimpSession session;
|
||||
|
||||
private String destination;
|
||||
|
||||
public SimpSubscriptionDto() {
|
||||
|
||||
/**
|
||||
* Default constructor for JSON deserialization.
|
||||
*/
|
||||
public TransferSimpSubscription() {
|
||||
}
|
||||
|
||||
public SimpSubscriptionDto(SimpSubscription subscription) {
|
||||
/**
|
||||
* Constructor to create DTO from a local user subscription.
|
||||
*/
|
||||
public TransferSimpSubscription(SimpSubscription subscription) {
|
||||
this.id = subscription.getId();
|
||||
this.destination = subscription.getDestination();
|
||||
}
|
||||
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
@@ -410,12 +464,12 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setSession(SimpSessionDto session) {
|
||||
public void setSession(TransferSimpSession session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpSessionDto getSession() {
|
||||
public TransferSimpSession getSession() {
|
||||
return this.session;
|
||||
}
|
||||
|
||||
@@ -452,27 +506,4 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class NoOpSmartApplicationListener implements SmartApplicationListener {
|
||||
|
||||
@Override
|
||||
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSourceType(Class<?> sourceType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -31,9 +31,11 @@ import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A MessageHandler that is subscribed to listen to broadcasts of user registry
|
||||
* information from other application servers as well as to periodically
|
||||
* broadcast the content of the local user registry. The aggregated information
|
||||
* {@code MessageHandler} that handles user registry broadcasts from other
|
||||
* application servers and periodically broadcasts the content of the local
|
||||
* user registry.
|
||||
*
|
||||
* The aggregated information
|
||||
* is maintained in a {@link MultiServerUserRegistry}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
@@ -56,16 +58,22 @@ public class UserRegistryMessageHandler implements MessageHandler, ApplicationLi
|
||||
private long registryExpirationPeriod = 20 * 1000;
|
||||
|
||||
|
||||
public UserRegistryMessageHandler(SimpUserRegistry userRegistry, SimpMessagingTemplate brokerTemplate,
|
||||
String broadcastDestination, TaskScheduler scheduler) {
|
||||
/**
|
||||
* Constructor.
|
||||
* @param userRegistry the registry with local and remote user registry information
|
||||
* @param brokerTemplate template for broadcasting local registry information
|
||||
* @param broadcastDestination the destination to broadcast to
|
||||
* @param scheduler
|
||||
*/
|
||||
public UserRegistryMessageHandler(MultiServerUserRegistry userRegistry,
|
||||
SimpMessagingTemplate brokerTemplate, String broadcastDestination, TaskScheduler scheduler) {
|
||||
|
||||
Assert.notNull(userRegistry, "'userRegistry' is required");
|
||||
Assert.isInstanceOf(MultiServerUserRegistry.class, userRegistry);
|
||||
Assert.notNull(brokerTemplate, "'brokerTemplate' is required");
|
||||
Assert.hasText(broadcastDestination, "'broadcastDestination' is required");
|
||||
Assert.notNull(scheduler, "'scheduler' is required");
|
||||
|
||||
this.userRegistry = (MultiServerUserRegistry) userRegistry;
|
||||
this.userRegistry = userRegistry;
|
||||
this.brokerTemplate = brokerTemplate;
|
||||
this.broadcastDestination = broadcastDestination;
|
||||
this.scheduler = scheduler;
|
||||
@@ -73,20 +81,21 @@ public class UserRegistryMessageHandler implements MessageHandler, ApplicationLi
|
||||
|
||||
|
||||
/**
|
||||
* Return the destination for broadcasting user registry information to.
|
||||
* Return the configured destination for broadcasting UserRegistry information.
|
||||
*/
|
||||
public String getBroadcastDestination() {
|
||||
return this.broadcastDestination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure how long before a remote registry snapshot expires.
|
||||
* <p>By default this is set to 20000 (20 seconds).
|
||||
* @param expirationPeriod the expiration period in milliseconds
|
||||
* Configure the amount of time (in milliseconds) before a remote user
|
||||
* registry snapshot is considered expired.
|
||||
* <p>By default this is set to 20 seconds (value of 20000).
|
||||
* @param milliseconds the expiration period in milliseconds
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public void setRegistryExpirationPeriod(long expirationPeriod) {
|
||||
this.registryExpirationPeriod = expirationPeriod;
|
||||
public void setRegistryExpirationPeriod(long milliseconds) {
|
||||
this.registryExpirationPeriod = milliseconds;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -22,10 +22,18 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.messaging.simp.config.AbstractMessageBrokerConfiguration;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* A temporary adapter to allow use of deprecated {@link UserSessionRegistry}.
|
||||
* An adapter that allows a {@code UserSessionRegistry}, which is deprecated in
|
||||
* favor of {@code SimpUserRegistry}, to be used as a {@code SimpUserRegistry}.
|
||||
* Due to the more limited information available, methods such as
|
||||
* {@link #getUsers()} and {@link #findSubscriptions} are not supported.
|
||||
*
|
||||
* <p>As of 4.2 this adapter is used only in applications that explicitly
|
||||
* register a custom {@code UserSessionRegistry} bean by overriding
|
||||
* {@link AbstractMessageBrokerConfiguration#userSessionRegistry()}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.2
|
||||
@@ -33,18 +41,18 @@ import org.springframework.util.CollectionUtils;
|
||||
@SuppressWarnings("deprecation")
|
||||
public class UserSessionRegistryAdapter implements SimpUserRegistry {
|
||||
|
||||
private final UserSessionRegistry delegate;
|
||||
private final UserSessionRegistry userSessionRegistry;
|
||||
|
||||
|
||||
public UserSessionRegistryAdapter(UserSessionRegistry delegate) {
|
||||
this.delegate = delegate;
|
||||
public UserSessionRegistryAdapter(UserSessionRegistry registry) {
|
||||
this.userSessionRegistry = registry;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SimpUser getUser(String userName) {
|
||||
Set<String> sessionIds = this.delegate.getSessionIds(userName);
|
||||
return (!CollectionUtils.isEmpty(sessionIds) ? new SimpleSimpUser(userName, sessionIds) : null);
|
||||
Set<String> sessionIds = this.userSessionRegistry.getSessionIds(userName);
|
||||
return (!CollectionUtils.isEmpty(sessionIds) ? new SimpUserAdapter(userName, sessionIds) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,17 +66,21 @@ public class UserSessionRegistryAdapter implements SimpUserRegistry {
|
||||
}
|
||||
|
||||
|
||||
private static class SimpleSimpUser implements SimpUser {
|
||||
/**
|
||||
* Expose the only information available from a UserSessionRegistry (name
|
||||
* and session id's) as a {@code SimpUser}.
|
||||
*/
|
||||
private static class SimpUserAdapter implements SimpUser {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final Map<String, SimpSession> sessions;
|
||||
|
||||
public SimpleSimpUser(String name, Set<String> sessionIds) {
|
||||
public SimpUserAdapter(String name, Set<String> sessionIds) {
|
||||
this.name = name;
|
||||
this.sessions = new HashMap<String, SimpSession>(sessionIds.size());
|
||||
for (String sessionId : sessionIds) {
|
||||
this.sessions.put(sessionId, new SimpleSimpSession(sessionId));
|
||||
this.sessions.put(sessionId, new SimpSessionAdapter(sessionId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,12 +105,15 @@ public class UserSessionRegistryAdapter implements SimpUserRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class SimpleSimpSession implements SimpSession {
|
||||
/**
|
||||
* Expose the only information available from a UserSessionRegistry (session
|
||||
* id's but no subscriptions) as a {@code SimpSession}.
|
||||
*/
|
||||
private static class SimpSessionAdapter implements SimpSession {
|
||||
|
||||
private final String id;
|
||||
|
||||
public SimpleSimpSession(String id) {
|
||||
public SimpSessionAdapter(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user