package io.mangoo.managers;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import org.apache.commons.io.IOUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import io.mangoo.cache.Cache;
import io.mangoo.enums.CacheName;
import io.mangoo.enums.Default;
import io.mangoo.enums.Required;
import io.mangoo.helpers.RequestHelper;
import io.mangoo.providers.CacheProvider;
import io.undertow.websockets.core.WebSocketChannel;
/**
*
* @author svenkubiak
*
*/
@Singleton
public class WebSocketManager {
private final Cache cache;
private final RequestHelper requestHelper;
@Inject
private WebSocketManager(CacheProvider cacheProvider, RequestHelper requestHelper) {
Objects.requireNonNull(cacheProvider, Required.CACHE_PROVIDER.toString());
this.cache = cacheProvider.getCache(CacheName.WSS);
this.requestHelper = requestHelper;
}
/**
* Adds a new channel to the manager
*
* @param channel channel The channel to put
*/
@SuppressWarnings("all")
public void addChannel(WebSocketChannel channel) {
Objects.requireNonNull(channel, Required.CHANNEL.toString());
final String url = this.requestHelper.getWebSocketURL(channel);
Set<WebSocketChannel> channels = getChannels(url);
if (channels == null) {
channels = new HashSet<>();
channels.add(channel);
} else {
channels.add(channel);
}
setChannels(url, channels);
}
/**
* Sets the URI resources for a given URL
*
* @param uri The URI resource for the connection
* @param channels The channels for the URI resource
*/
public void setChannels(String uri, Set<WebSocketChannel> channels) {
Objects.requireNonNull(uri, Required.URI.toString());
Objects.requireNonNull(channels, Required.URI_CONNECTIONS.toString());
this.cache.put(Default.WSS_CACHE_PREFIX.toString() + uri, channels);
}
/**
* Retrieves all channels under a given URL
*
* @param uri The URI resource for the channels
*
* @return A Set of channels for the URI resource
*/
public Set<WebSocketChannel> getChannels(String uri) {
Objects.requireNonNull(uri, Required.URI.toString());
final Set<WebSocketChannel> channels = this.cache.get(Default.WSS_CACHE_PREFIX.toString() + uri);
return (channels == null) ? new HashSet<>() : channels;
}
/**
* Removes all URI resources for a given URL
*
* @param uri The URI resource for the connection
*/
public void removeChannels(String uri) {
Objects.requireNonNull(uri, Required.URI.toString());
this.cache.remove(Default.WSS_CACHE_PREFIX.toString() + uri);
}
/**
* Closes all connections for a given URI resource
*
* @param uri The URI resource for the connection
*/
public void close(String uri) {
Objects.requireNonNull(uri, Required.URI.toString());
final Set<WebSocketChannel> channels = getChannels(uri);
if (channels != null) {
channels.forEach(channel -> {
if (channel.isOpen()) {
IOUtils.closeQuietly(channel);
}
});
removeChannels(uri);
}
}
}