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: 966961 $
038     */
039    public class CamelContinuationServlet extends CamelServlet {
040    
041        static final String EXCHANGE_ATTRIBUTE_NAME = "CamelExchange";
042    
043        private static final long serialVersionUID = 1L;
044    
045        @Override
046        protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
047            try {
048                // Is there a consumer registered for the request.
049                HttpConsumer consumer = resolve(request);
050                if (consumer == null) {
051                    response.sendError(HttpServletResponse.SC_NOT_FOUND);
052                    return;
053                }
054    
055                final Continuation continuation = ContinuationSupport.getContinuation(request);
056    
057                // are we suspended and a request is dispatched initially?
058                if (consumer.isSuspended() && continuation.isInitial()) {
059                    response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
060                    return;
061                }
062    
063                if (continuation.isInitial()) {
064                    // a new request so create an exchange
065                    final Exchange exchange = new DefaultExchange(consumer.getEndpoint(), ExchangePattern.InOut);
066                    if (consumer.getEndpoint().isBridgeEndpoint()) {
067                        exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE);
068                    }
069                    if (consumer.getEndpoint().isDisableStreamCache()) {
070                        exchange.setProperty(Exchange.DISABLE_HTTP_STREAM_CACHE, Boolean.TRUE);
071                    }
072                    exchange.setIn(new HttpMessage(exchange, request, response));
073    
074                    if (log.isTraceEnabled()) {
075                        log.trace("Suspending continuation of exchangeId: " + exchange.getExchangeId());
076                    }
077                    continuation.suspend();
078    
079                    // use the asynchronous API to process the exchange
080                    consumer.getAsyncProcessor().process(exchange, new AsyncCallback() {
081                        public void done(boolean doneSync) {
082                            if (log.isTraceEnabled()) {
083                                log.trace("Resuming continuation of exchangeId: " + exchange.getExchangeId());
084                            }
085                            // resume processing after both, sync and async callbacks
086                            continuation.setAttribute(EXCHANGE_ATTRIBUTE_NAME, exchange);
087                            continuation.resume();
088                        }
089                    });
090                    return;
091                }
092    
093                if (continuation.isResumed()) {
094                    // a re-dispatched request containing the processing result
095                    Exchange exchange = (Exchange) continuation.getAttribute(EXCHANGE_ATTRIBUTE_NAME);
096                    if (log.isTraceEnabled()) {
097                        log.trace("Resuming continuation of exchangeId: " + exchange.getExchangeId());
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                }
106            } catch (IOException e) {
107                log.error("Error processing request", e);
108                throw e;
109            } catch (Exception e) {
110                log.error("Error processing request", e);
111                throw new ServletException(e);
112            }
113        }
114    
115    }