package com.eucalyptus.ws.server; import java.net.InetSocketAddress; import java.util.List; import org.apache.log4j.Logger; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.ChannelUpstreamHandler; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.handler.codec.http.DefaultHttpResponse; import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.handler.codec.http.HttpRequest; import org.jboss.netty.handler.codec.http.HttpResponse; import org.jboss.netty.handler.codec.http.HttpResponseStatus; import org.mule.transport.NullPayload; import com.eucalyptus.context.Contexts; import com.eucalyptus.context.NoSuchContextException; import com.eucalyptus.context.ServiceContext; import com.eucalyptus.http.MappingHttpRequest; import com.eucalyptus.ws.stages.UnrollableStage; import com.eucalyptus.ws.util.Messaging; @ChannelPipelineCoverage( "one" ) public class MetadataPipeline extends FilteredPipeline implements UnrollableStage, ChannelUpstreamHandler { private static Logger LOG = Logger.getLogger( MetadataPipeline.class ); @Override protected void addStages( List<UnrollableStage> stages ) { stages.add( this ); } @Override protected boolean checkAccepts( HttpRequest message ) { return message.getUri( ).matches("/latest(/.*)*") || message.getUri( ).matches("/\\d\\d\\d\\d-\\d\\d-\\d\\d/.*"); } @Override public String getPipelineName( ) { return "instance-metadata"; } @Override public String getStageName( ) { return "instance-metadata"; } @Override public void unrollStage( ChannelPipeline pipeline ) { pipeline.addLast( "instance-metadata", this ); } @Override public void handleUpstream( ChannelHandlerContext ctx, ChannelEvent e ) throws Exception { if( e instanceof MessageEvent && ( (MessageEvent ) e).getMessage( ) instanceof MappingHttpRequest ) { MappingHttpRequest request = ( MappingHttpRequest ) ((MessageEvent) e).getMessage( ); String newUri = null; String uri = request.getUri( ); InetSocketAddress remoteAddr = ((InetSocketAddress) ctx.getChannel( ).getRemoteAddress( ) ); String remoteHost = remoteAddr.getAddress( ).getHostAddress( );//"10.1.1.2";// if( uri.startsWith( "/latest/" ) ) newUri = uri.replaceAll( "/latest/", remoteHost + ":" ); else newUri = uri.replaceAll( "/\\d\\d\\d\\d-\\d\\d-\\d\\d/", remoteHost + ":" ); HttpResponse response = null; LOG.info( "Trying to get metadata: " + newUri ); Object reply = null; try { reply = ServiceContext.send( "VmMetadata", newUri ); } catch ( Exception e1 ) { LOG.debug( e1, e1 ); } finally { Contexts.clear( request.getCorrelationId( ) ); } if ( reply != null && !( reply instanceof NullPayload ) ) { response = new DefaultHttpResponse(request.getProtocolVersion( ),HttpResponseStatus.OK); response.setHeader( HttpHeaders.Names.CONTENT_TYPE, "text/html" ); ChannelBuffer buffer = ChannelBuffers.wrappedBuffer( ( byte[] ) reply ); response.setContent( buffer ); response.addHeader( HttpHeaders.Names.CONTENT_LENGTH, Integer.toString( buffer.readableBytes( ) ) ); } else response = new DefaultHttpResponse(request.getProtocolVersion( ),HttpResponseStatus.NOT_FOUND); ctx.getChannel( ).write( response ).addListener( ChannelFutureListener.CLOSE ); } else { ctx.sendUpstream( e ); } } }