package org.distributeme.registry.esregistry;
import org.distributeme.core.ServiceDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* Implementation of the event service registry.
* @author lrosenberg
*
*/
public class EventServiceRegistryImpl implements EventServiceRegistry{
/**
* Singleton instance.
*/
private static final EventServiceRegistry instance = new EventServiceRegistryImpl();
public static final EventServiceRegistry getInstance(){
return instance;
}
/**
* Targets of the operations.
* @author another
*
*/
private static enum Target{
/**
* This target is a supplier.
*/
SUPPLIER,
/**
* This target is a consumer.
*/
CONSUMER;
}
/**
* Logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(EventServiceRegistryImpl.class);
/**
* Registered channels.
*/
private ConcurrentMap<String, ChannelDescriptor> channels;
/**
* Creates a new registry.
*/
EventServiceRegistryImpl() {
channels = new ConcurrentHashMap<String, ChannelDescriptor>();
}
@Override
public void reset(){
LOG.warn("reset called!");
channels.clear();
}
@Override
public List<ServiceDescriptor> addConsumer(String channelName,
ServiceDescriptor descriptor) {
ChannelDescriptor channel = addDescriptorToChannel(channelName, descriptor, Target.CONSUMER);
return channel.getSuppliers();
}
@Override
public List<ServiceDescriptor> addSupplier(String channelName,
ServiceDescriptor descriptor) {
ChannelDescriptor channel = addDescriptorToChannel(channelName, descriptor, Target.SUPPLIER);
return channel.getConsumers();
}
@Override
public List<String> getChannelNames() {
ArrayList<String> ret = new ArrayList<String>(channels.size());
ret.addAll(channels.keySet());
return ret;
}
@Override
public List<ChannelDescriptor> getChannels() {
ArrayList<ChannelDescriptor> ret = new ArrayList<ChannelDescriptor>(channels.size());
ret.addAll(channels.values());
return ret;
}
@Override public ChannelDescriptor getChannel(String channelName){
return channels.get(channelName);
}
@Override
public void notifyConsumerUnavailable(ServiceDescriptor descriptor) {
removeDescriptorFromAllChannels(descriptor, Target.CONSUMER);
}
@Override
public void notifySupplierUnavailable(ServiceDescriptor descriptor) {
removeDescriptorFromAllChannels(descriptor, Target.SUPPLIER);
}
/**
* Adds a service descriptor to the channel.
* @param channelName name of the channel.
* @param descriptor newly added service descriptor.
* @param target target to add as - consumer or supplier.
* @return
*/
private ChannelDescriptor addDescriptorToChannel(String channelName, ServiceDescriptor descriptor, Target target){
ChannelDescriptor channel = channels.get(channelName);
if (channel==null){
channel = new ChannelDescriptor(channelName);
ChannelDescriptor oldchannel = channels.putIfAbsent(channelName, channel);
if (oldchannel!=null)
channel = oldchannel;
}
if (target == Target.CONSUMER)
channel.addConsumer(descriptor);
else
channel.addSupplier(descriptor);
return channel;
}
private void removeDescriptorFromAllChannels(ServiceDescriptor descriptor, Target target){
int total = 0;
for (ChannelDescriptor channel : channels.values()){
boolean result = target == Target.CONSUMER ?
channel.removeConsumer(descriptor) : channel.removeSupplier(descriptor);
if (result)
total++;
}
LOG.debug("Removed "+descriptor+" as "+target+" from "+total+" channels");
}
}