package com.eucalyptus.ws.client; import java.net.URI; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.log4j.Logger; import org.mule.module.client.MuleClient; import com.eucalyptus.bootstrap.Component; import com.eucalyptus.component.Dispatcher; import com.eucalyptus.util.EucalyptusCloudException; import com.eucalyptus.util.LogUtil; import com.eucalyptus.ws.client.pipeline.InternalClientPipeline; import com.eucalyptus.ws.handlers.NioResponseHandler; import com.google.common.collect.Lists; import edu.ucsb.eucalyptus.msgs.BaseMessage; public abstract class ServiceDispatcher implements Dispatcher { private static Logger LOG = Logger.getLogger( ServiceDispatcher.class ); private static ConcurrentMap<String,Dispatcher> proxies = new ConcurrentHashMap<String,Dispatcher>(); public static Dispatcher lookupSingle( Component c ) throws NoSuchElementException { List<Dispatcher> dispatcherList = lookupMany( c ); if( dispatcherList.size( ) < 1 ) { LOG.error( "Failed to find service dispatcher for component=" + c ); throw new NoSuchElementException("Failed to find service dispatcher for component=" + c); } return dispatcherList.get(0); } public static List<Dispatcher> lookupMany( Component c ) { List<Dispatcher> dispatcherList = Lists.newArrayList( ); for( String key : proxies.keySet( ) ) { if( key.startsWith( c.name() )) { dispatcherList.add( proxies.get( key ) ); } } return dispatcherList; } public static Dispatcher lookup( Component c, String hostName ) { return proxies.get( c.getRegistryKey( hostName ) ); } public static Dispatcher register( String registryKey, Dispatcher proxy ) { LOG.info( "Registering "+ registryKey + " as " + proxy ); return proxies.put( registryKey, proxy ); } public static Dispatcher deregister( String name ) { LOG.info( "Deregistering "+ name ); return proxies.remove( name ); } public static Dispatcher deregister( Component c, String hostName ) { LOG.info( "Deregistering "+ c.getRegistryKey( hostName ) ); return proxies.remove( c.getRegistryKey( hostName ) ); } public static Collection<Dispatcher> values( ) { return proxies.values( ); } private Component component; private String name; private URI address; private boolean isLocal = false; public ServiceDispatcher( Component component, String name, URI address, boolean isLocal ) { super( ); this.component = component; this.name = name; this.address = address; this.isLocal = isLocal; } /** * @see com.eucalyptus.component.Dispatcher#dispatch(edu.ucsb.eucalyptus.msgs.BaseMessage) * @param msg */ public abstract void dispatch( BaseMessage msg ); /** * @see com.eucalyptus.component.Dispatcher#send(edu.ucsb.eucalyptus.msgs.BaseMessage) * @param msg * @return * @throws EucalyptusCloudException */ public abstract BaseMessage send( BaseMessage msg ) throws EucalyptusCloudException; /** * @see com.eucalyptus.component.Dispatcher#send(edu.ucsb.eucalyptus.msgs.BaseMessage, java.lang.Class) * @param <REPLY> * @param message * @param replyType * @return * @throws EucalyptusCloudException */ @SuppressWarnings( "unchecked" ) public <REPLY> REPLY send( BaseMessage message, Class<REPLY> replyType ) throws EucalyptusCloudException { return (REPLY) this.send( message ); } /** * @see com.eucalyptus.component.Dispatcher#getComponent() * @return */ public Component getComponent( ) { return component; } /** * @see com.eucalyptus.component.Dispatcher#getName() * @return */ public String getName( ) { return name; } /** * @see com.eucalyptus.component.Dispatcher#getAddress() * @return */ public URI getAddress( ) { return address; } /** * @see com.eucalyptus.component.Dispatcher#isLocal() * @return */ public boolean isLocal( ) { return isLocal; } protected MuleClient getMuleClient( ) throws Exception { return new MuleClient( ); } protected NioClient getNioClient( ) throws Exception { return new NioClient( this.address.getHost( ), this.address.getPort( ), this.address.getPath( ), new InternalClientPipeline( new NioResponseHandler( ) ) ); } /** * @see com.eucalyptus.component.Dispatcher#toString() * @return */ @Override public String toString( ) { return LogUtil.dumpObject( this ); } }