Package org.objectweb.celtix.bus.transports.http

Source Code of org.objectweb.celtix.bus.transports.http.JettyHTTPServerTransport$HTTPServerRebasedOutputStreamContext

package org.objectweb.celtix.bus.transports.http;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

import javax.wsdl.Definition;
import javax.wsdl.WSDLException;
import javax.xml.ws.handler.MessageContext;

import org.mortbay.http.HttpRequest;
import org.mortbay.http.HttpResponse;
import org.mortbay.http.handler.AbstractHttpHandler;
import org.objectweb.celtix.Bus;
import org.objectweb.celtix.BusEvent;
import org.objectweb.celtix.BusEventListener;
import org.objectweb.celtix.BusException;
import org.objectweb.celtix.bindings.BindingContextUtils;
import org.objectweb.celtix.bus.busimpl.ComponentCreatedEvent;
import org.objectweb.celtix.bus.busimpl.ComponentRemovedEvent;
import org.objectweb.celtix.bus.configuration.ConfigurationEvent;
import org.objectweb.celtix.bus.configuration.ConfigurationEventFilter;
import org.objectweb.celtix.bus.management.counters.TransportServerCounters;
import org.objectweb.celtix.bus.ws.addressing.ContextUtils;
import org.objectweb.celtix.context.OutputStreamMessageContext;
import org.objectweb.celtix.transports.ServerTransportCallback;
import org.objectweb.celtix.ws.addressing.EndpointReferenceType;
import org.objectweb.celtix.wsdl.EndpointReferenceUtils;

public class JettyHTTPServerTransport extends AbstractHTTPServerTransport
    implements BusEventListener {
   
    private static final long serialVersionUID = 1L;
    JettyHTTPServerEngine engine;
    TransportServerCounters counters;
   
    public JettyHTTPServerTransport(Bus b, EndpointReferenceType ref) throws WSDLException, IOException {
        super(b, ref);
        counters = new TransportServerCounters("JettyHTTPServerTransport");
        engine = JettyHTTPServerEngine.getForPort(bus, nurl.getProtocol(), nurl.getPort());
        //register the configuration event
        ConfigurationEventFilter configurationEventFilter = new ConfigurationEventFilter();
        try {
            bus.addListener((BusEventListener)this, configurationEventFilter);
        } catch (BusException ex) {           
            LOG.log(Level.SEVERE, "REMOVE_LISTENER_FAILURE_MSG", ex);           
        }
       
        bus.sendEvent(new ComponentCreatedEvent(this));
    }
   
    public void shutdown() { 
        try {
            bus.removeListener((BusEventListener)this);
        } catch (BusException ex) {           
            LOG.log(Level.SEVERE, "REMOVE_LISTENER_FAILURE_MSG", ex);           
        }
        bus.sendEvent(new ComponentRemovedEvent(this));
    }
   
   
    public synchronized void activate(ServerTransportCallback cb) throws IOException {
        callback = cb;
        engine.addServant(url, new AbstractHttpHandler() {
            public void handle(String pathInContext, String pathParams,
                               HttpRequest req, HttpResponse resp)
                throws IOException {
                if (pathInContext.equals(getName())) {
                    doService(req, resp);                   
                }
            }
        });
    }

    public void deactivate() throws IOException {
        engine.removeServant(url);
    }
   
    public OutputStreamMessageContext rebase(MessageContext context,
                                             EndpointReferenceType decoupledResponseEndpoint)
        throws IOException {
        OutputStreamMessageContext outputContext = null;
        HttpRequest request =
            (HttpRequest)context.get(HTTPServerInputStreamContext.HTTP_REQUEST);
        HttpResponse response =
            (HttpResponse)context.get(HTTPServerInputStreamContext.HTTP_RESPONSE);
        if (response != null) {
            outputContext = new HTTPServerRebasedOutputStreamContext(context, request, response);
            context.put(HTTPServerInputStreamContext.HTTP_RESPONSE, decoupledResponseEndpoint);
        }
        return outputContext;
    }
   
    public void postDispatch(MessageContext bindingContext, OutputStreamMessageContext context) {
        Object responseObj =
            bindingContext.get(HTTPServerInputStreamContext.HTTP_RESPONSE);
       
        if (context.isOneWay()) {
            counters.getRequestOneWay().increase();           
        }      
        counters.getRequestTotal().increase();

        if (responseObj instanceof HttpResponse) {
            HttpResponse response = (HttpResponse)responseObj;
           
            if (response.getStatus() == 500) {
                counters.getTotalError().increase();
            }
           
            try {
                response.commit();
            } catch (IOException e) {
                e.printStackTrace();
            }
           
        } else if (responseObj instanceof URLConnection) {
            try {
                URLConnection connection = (URLConnection)responseObj;
                connection.getOutputStream().close();
                connection.getInputStream().close();
            } catch (IOException ioe) {
                LOG.log(Level.WARNING, "DECOUPLED_RESPONSE_FAILED_MSG", ioe);
            }
        }
       
    }
   
    protected void copyRequestHeaders(MessageContext ctx, Map<String, List<String>> headers) {
        HttpRequest req = (HttpRequest)ctx.get(HTTPServerInputStreamContext.HTTP_REQUEST);
        for (Enumeration e = req.getFieldNames(); e.hasMoreElements();) {
            String fname = (String)e.nextElement();
            List<String> values;
            if (headers.containsKey(fname)) {
                values = headers.get(fname);
            } else {
                values = new ArrayList<String>();
                headers.put(fname, values);
            }
            for (Enumeration e2 = req.getFieldValues(fname); e2.hasMoreElements();) {
                String val = (String)e2.nextElement();
                values.add(val);
            }
        }       
    }
   
    // REVISIT factor out to common shared with HTTPClientTransport
    protected URLConnection getConnection(URL url) throws IOException {
        URLConnection connection = url.openConnection();
        connection.setDoOutput(true);
        connection.setUseCaches(false);
        if (connection instanceof HttpURLConnection) {
            HttpURLConnection hc = (HttpURLConnection)connection;
            hc.setRequestMethod("POST");
        }
        connection.setRequestProperty("Content-Type", "text/xml");
        return connection;
    }

    protected void setPolicies(MessageContext ctx, Map<String, List<String>> headers) {
        super.setPolicies(ctx, headers);
        if (policy.isSetReceiveTimeout()) {
            HttpRequest req = (HttpRequest)ctx.get(HTTPServerInputStreamContext.HTTP_REQUEST);
            Object connection = req.getHttpConnection().getConnection();
            if (connection instanceof Socket) {
                Socket sock = (Socket)connection;
                try {
                    sock.setSoTimeout((int)policy.getReceiveTimeout());
                } catch (SocketException ex) {
                    LOG.log(Level.INFO, "Could not set SoTimeout", ex);
                }
            }               
        }
    }   

    protected void copyHeaders(MessageContext context, HttpResponse response) {
        Map<?, ?> headers = (Map<?, ?>)context.get(MessageContext.HTTP_RESPONSE_HEADERS);
        if (null != headers) {
            for (Iterator<?> iter = headers.keySet().iterator(); iter.hasNext();) {
                String header = (String)iter.next();
                List<?> headerList = (List<?>)headers.get(header);
                for (Object string : headerList) {
                    response.addField(header, (String)string);
                }
            }
        }
       
    }
   
    /**
     * @param context The associated MessageContext.
     * @return the context that will be used to obtain the OutputStream
     */
    public OutputStreamMessageContext createOutputStreamContext(MessageContext context)
        throws IOException {
        OutputStreamMessageContext ret = null;
        // REVISIT: move isRequestor to BindingContextUtils
        if (ContextUtils.isRequestor(context)) {
            // create client output stream context
            ret = new AbstractHTTPRequestorOutputStreamContext(context) {
                protected URLConnection getConnection(URL url) throws IOException {
                    return url.openConnection();
                }
            };
        } else {
            ret = new HTTPServerOutputStreamContext(context);
        }
        return ret;
    }

    void doService(HttpRequest req, HttpResponse resp) throws IOException {
       
        if (policy.isSetRedirectURL()) {
            resp.sendRedirect(policy.getRedirectURL());
            resp.commit();
            req.setHandled(true);
            return;
        }   

       
       
        if ("GET".equals(req.getMethod()) && req.getURI().toString().toLowerCase().endsWith("?wsdl")) {
            try {
               
                Definition def = EndpointReferenceUtils.getWSDLDefinition(bus.getWSDLManager(), reference);
                resp.addField("Content-Type", "text/xml");
                bus.getWSDLManager().getWSDLFactory().newWSDLWriter().writeWSDL(def, resp.getOutputStream());
                resp.getOutputStream().flush();
                resp.commit();
                req.setHandled(true);
                return;
            } catch (WSDLException ex) {
                // TODO Auto-generated catch block
                ex.printStackTrace();
            }
        }
               
        final class Servicer implements Runnable {
            private boolean complete;
            private final HttpRequest request;
            private final HttpResponse response;
           
            Servicer(HttpRequest reqs, HttpResponse resps) {
                request = reqs;
                response = resps;
            }
            public void run() {
                try {
                    serviceRequest(request, response);                       
                } catch (IOException ex) {                       
                    // TODO handle exception
                    LOG.log(Level.SEVERE, "DISPATCH_FAILURE_MSG", ex);
                } finally {
                    complete = true;
                    synchronized (this) {
                        notifyAll();
                    }
                }
            }
           
            public synchronized void waitForCompletion() {
                while (!complete) {
                    try {
                        wait();
                    } catch (InterruptedException ex) {
                        // ignore
                    }
                }
            }
        }
       
        if (null == callback.getExecutor()) {
            serviceRequest(req, resp);
        } else
            Servicer servicer = new Servicer(req, resp);
            callback.getExecutor().execute(servicer);
            servicer.waitForCompletion();
        }       
    }
   
    void serviceRequest(final HttpRequest req, final HttpResponse resp) throws IOException {
        try {
            if (LOG.isLoggable(Level.INFO)) {
                LOG.info("Service http request on thread: " + Thread.currentThread());
            }
           
            HTTPServerInputStreamContext ctx = new HTTPServerInputStreamContext(this) {
                public void initContext() throws IOException {
                    super.initContext();
                    inStream = req.getInputStream();
                    origInputStream = inStream;
                }
            };
            BindingContextUtils.storeAsyncOnewayDispatch(ctx, true);
            ctx.put(HTTPServerInputStreamContext.HTTP_REQUEST, req);
            ctx.put(HTTPServerInputStreamContext.HTTP_RESPONSE, resp);
            ctx.initContext();
           
            callback.dispatch(ctx, this);
            resp.commit();
            req.setHandled(true);
        } finally {
            if (LOG.isLoggable(Level.INFO)) {
                LOG.info("Finished servicing http request on thread: " + Thread.currentThread());
            }
        }
    }

    private class HTTPServerOutputStreamContext
        extends AbstractHTTPServerOutputStreamContext {
       
        HTTPServerOutputStreamContext(MessageContext ctx) throws IOException {
            super(JettyHTTPServerTransport.this, ctx);
        }
        protected void flushHeaders() throws IOException {
            Object responseObj =
                get(HTTPServerInputStreamContext.HTTP_RESPONSE);
            OutputStream responseStream = null;
            if (responseObj instanceof HttpResponse) {
                // non-decoupled response
                HttpResponse response = (HttpResponse)responseObj;
           
                Integer i = (Integer)context.get(HTTP_RESPONSE_CODE);
                if (i != null) {
                    if (i.intValue() == 500) {
                        response.setStatus(i.intValue(), "Fault Occurred");
                    } else {
                        response.setStatus(i.intValue());
                    }
                } else {
                    response.setStatus(200);
                }
           
                copyHeaders(context, response);
                responseStream = response.getOutputStream();
               
                if (isOneWay()) {
                    response.commit();
                }
            } else if (responseObj instanceof EndpointReferenceType) {
                // decoupled response
                EndpointReferenceType decoupledResponseEndpoint =
                    (EndpointReferenceType)responseObj;
               
                if (!isOneWay()) {
                    // REVISIT: use policy logic from HTTPClientTransport
                    // REVISIT: handle connection closure
                    URL url = new URL(decoupledResponseEndpoint.getAddress().getValue());
                    URLConnection connection = getConnection(url);
                    responseStream = connection.getOutputStream();
                    put(HTTPServerInputStreamContext.HTTP_RESPONSE, connection);
                }
            } else if (responseObj instanceof URLConnection) {
                // resent decoupled response
                URL url = ((URLConnection)responseObj).getURL();
                URLConnection connection = getConnection(url);
                responseStream = connection.getOutputStream();
                put(HTTPServerInputStreamContext.HTTP_RESPONSE, connection);
            } else {
                LOG.log(Level.WARNING, "UNEXPECTED_RESPONSE_TYPE_MSG", responseObj.getClass());
                throw new IOException("UNEXPECTED_RESPONSE_TYPE_MSG" + responseObj.getClass());
            }

            if (isOneWay()) {
                context.remove(HTTPServerInputStreamContext.HTTP_RESPONSE);
            } else {
                origOut.resetOut(new BufferedOutputStream(responseStream, 1024));
            }
        }
    }
   
    private class HTTPServerRebasedOutputStreamContext
        extends AbstractHTTPServerOutputStreamContext {
   
        private HttpRequest request;
        private HttpResponse response;
       
        HTTPServerRebasedOutputStreamContext(MessageContext ctx,
                                             HttpRequest req,
                                             HttpResponse resp) throws IOException {
            super(JettyHTTPServerTransport.this, ctx);
            request = req;
            response = resp;
        }
       
        protected void flushHeaders() throws IOException {
            if (response != null) {
                copyHeaders(context, response);
                response.setStatus(HttpURLConnection.HTTP_ACCEPTED, "Accepted");
                response.commit();
                request.setHandled(true);
                origOut.resetOut(new BufferedOutputStream(response.getOutputStream(), 1024));
            }
        }
    }
    public void processEvent(BusEvent e) throws BusException {
        if (e.getID().equals(ConfigurationEvent.RECONFIGURED)) {
            String configName = (String)e.getSource();           
            reConfigure(configName);
        }
    }

    private void reConfigure(String configName) {
        if ("servicesMonitoring".equals(configName)) {
            if (bus.getConfiguration().getBoolean("servicesMonitoring")) {
                counters.resetCounters();
            } else {
                counters.stopCounters();
            }
        }
    }
}
TOP

Related Classes of org.objectweb.celtix.bus.transports.http.JettyHTTPServerTransport$HTTPServerRebasedOutputStreamContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.