001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.jetty;
018    
019    import java.io.IOException;
020    import javax.servlet.ServletException;
021    import javax.servlet.http.HttpServletRequest;
022    import javax.servlet.http.HttpServletResponse;
023    
024    import org.apache.camel.AsyncCallback;
025    import org.apache.camel.Exchange;
026    import org.apache.camel.ExchangePattern;
027    import org.apache.camel.component.http.CamelServlet;
028    import org.apache.camel.component.http.HttpConsumer;
029    import org.apache.camel.component.http.HttpMessage;
030    import org.apache.camel.impl.DefaultExchange;
031    import org.eclipse.jetty.continuation.Continuation;
032    import org.eclipse.jetty.continuation.ContinuationSupport;
033    
034    /**
035     * Currently not in use.
036     *
037     * @version $Revision: 19985 $
038     */
039    public class CamelContinuationServlet extends CamelServlet {
040    
041        private static final long serialVersionUID = 1L;
042    
043        @Override
044        protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
045            try {
046                // Is there a consumer registered for the request.
047                HttpConsumer consumer = resolve(request);
048                if (consumer == null) {
049                    response.sendError(HttpServletResponse.SC_NOT_FOUND);
050                    return;
051                }
052    
053                // are we suspended?
054                if (consumer.isSuspended()) {
055                    response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
056                    return;
057                }
058    
059                final Continuation continuation = ContinuationSupport.getContinuation(request);
060                if (continuation.isInitial()) {
061    
062                    // a new request so create an exchange
063                    final Exchange exchange = new DefaultExchange(consumer.getEndpoint(), ExchangePattern.InOut);
064                    if (consumer.getEndpoint().isBridgeEndpoint()) {
065                        exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE);
066                    }
067                    if (consumer.getEndpoint().isDisableStreamCache()) {
068                        exchange.setProperty(Exchange.DISABLE_HTTP_STREAM_CACHE, Boolean.TRUE);
069                    }
070                    exchange.setIn(new HttpMessage(exchange, request, response));
071    
072                    // use the asynchronous API to process the exchange
073                    boolean sync = consumer.getAsyncProcessor().process(exchange, new AsyncCallback() {
074                        public void done(boolean doneSync) {
075                            // we only have to handle async completion
076                            if (doneSync) {
077                                return;
078                            }
079    
080                            // we should resume the continuation now that we are done asynchronously
081                            if (log.isTraceEnabled()) {
082                                log.trace("Resuming continuation of exchangeId: " + exchange.getExchangeId());
083                            }
084                            continuation.setAttribute("CamelExchange", exchange);
085                            continuation.resume();
086                        }
087                    });
088    
089                    if (!sync) {
090                        // wait for the exchange to get processed.
091                        // this might block until it completes or it might return via an exception and
092                        // then this method is re-invoked once the the exchange has finished processing
093                        if (log.isTraceEnabled()) {
094                            log.trace("Suspending continuation of exchangeId: " + exchange.getExchangeId());
095                        }
096                        continuation.suspend(response);
097                        return;
098                    }
099    
100                    // now lets output to the response
101                    if (log.isTraceEnabled()) {
102                        log.trace("Writing response of exchangeId: " + exchange.getExchangeId());
103                    }
104                    consumer.getBinding().writeResponse(exchange, response);
105                    return;
106                }
107    
108                if (continuation.isResumed()) {
109                    Exchange exchange = (Exchange) continuation.getAttribute("CamelExchange");
110                    if (log.isTraceEnabled()) {
111                        log.trace("Resuming continuation of exchangeId: " + exchange.getExchangeId());
112                    }
113    
114                    // now lets output to the response
115                    if (log.isTraceEnabled()) {
116                        log.trace("Writing response of exchangeId: " + exchange.getExchangeId());
117                    }
118                    consumer.getBinding().writeResponse(exchange, response);
119                    return;
120                }
121            } catch (Exception e) {
122                log.error("Error processing request", e);
123                throw new ServletException(e);
124            }
125        }
126    
127    }