package com.eucalyptus.context; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.log4j.Logger; import org.jboss.netty.channel.Channel; import org.mule.RequestContext; import org.mule.api.MuleMessage; import com.eucalyptus.http.MappingHttpRequest; import edu.ucsb.eucalyptus.msgs.BaseMessage; public class Contexts { private static Logger LOG = Logger.getLogger( Contexts.class ); private static int MAX = 8192; private static int CONCUR = MAX / ( Runtime.getRuntime( ).availableProcessors( ) * 2 + 1 ); private static float THRESHOLD = 1.0f; private static ConcurrentMap<String, Context> uuidContexts = new ConcurrentHashMap<String, Context>( MAX, THRESHOLD, CONCUR ); private static ConcurrentMap<Channel, Context> channelContexts = new ConcurrentHashMap<Channel, Context>( MAX, THRESHOLD, CONCUR ); public static Context create( MappingHttpRequest request, Channel channel ) { Context ctx = new Context( request, channel ); request.setCorrelationId( ctx.getCorrelationId( ) ); uuidContexts.put( ctx.getCorrelationId( ), ctx ); channelContexts.put( channel, ctx ); return ctx; } public static Context lookup( Channel channel ) throws NoSuchContextException { if ( !channelContexts.containsKey( channel ) ) { throw new NoSuchContextException( "Found channel context " + channel + " but no corresponding context." ); } else { Context ctx = channelContexts.get( channel ); ctx.setMuleEvent( RequestContext.getEvent( ) ); return ctx; } } public static Context lookup( String correlationId ) throws NoSuchContextException { if ( !uuidContexts.containsKey( correlationId ) ) { throw new NoSuchContextException( "Found correlation id " + correlationId + " but no corresponding context." ); } else { Context ctx = uuidContexts.get( correlationId ); ctx.setMuleEvent( RequestContext.getEvent( ) ); return ctx; } } public static Context lookup( ) { BaseMessage parent = null; MuleMessage muleMsg = null; if ( RequestContext.getEvent( ) != null && RequestContext.getEvent( ).getMessage( ) != null ) { muleMsg = RequestContext.getEvent( ).getMessage( ); } else if ( RequestContext.getEventContext( ) != null && RequestContext.getEventContext( ).getMessage( ) != null ) { muleMsg = RequestContext.getEventContext( ).getMessage( ); } else { throw new IllegalContextAccessException( "Cannot access context implicitly using lookup(V) outside of a service." ); } Object o = muleMsg.getPayload( ); if ( o != null && o instanceof BaseMessage ) { String correlationId = ( ( BaseMessage ) o ).getCorrelationId( ); try { return Contexts.lookup( correlationId ); } catch ( NoSuchContextException e ) { LOG.error( e, e ); throw new IllegalContextAccessException( "Cannot access context implicitly using lookup(V) when not handling a request.", e ); } } else { throw new IllegalContextAccessException( "Cannot access context implicitly using lookup(V) when not handling a request." ); } } public static void clear( Context context ) { Context ctx = uuidContexts.remove( context.getCorrelationId( ) ); Channel channel = null; if ( ctx != null && ( channel = ctx.getChannel( ) ) != null ) { channelContexts.remove( channel ); } else { throw new RuntimeException( "Missing reference to channel for the request." ); } ctx.clear( ); } public static void clear( String correlationId ) { try { clear( lookup( correlationId ) ); } catch ( NoSuchContextException e ) { LOG.error( e, e ); } } }