001    /**
002     *
003     * Licensed to the Apache Software Foundation (ASF) under one or more
004     * contributor license agreements.  See the NOTICE file distributed with
005     * this work for additional information regarding copyright ownership.
006     * The ASF licenses this file to You under the Apache License, Version 2.0
007     * (the "License"); you may not use this file except in compliance with
008     * the License.  You may obtain a copy of the License at
009     *
010     * http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    package org.apache.camel.component.http;
019    
020    import java.util.HashMap;
021    
022    import org.mortbay.jetty.Connector;
023    import org.mortbay.jetty.Server;
024    import org.mortbay.jetty.nio.SelectChannelConnector;
025    import org.mortbay.jetty.security.SslSocketConnector;
026    import org.mortbay.jetty.servlet.Context;
027    import org.mortbay.jetty.servlet.ServletHolder;
028    
029    /**
030     * An HttpComponent which starts an embedded Jetty for to handle consuming from
031     * http endpoints.
032     * 
033     * @version $Revision: 525142 $
034     */
035    public class JettyHttpComponent extends HttpComponent {
036            
037            Server server;
038            
039            class ConnectorRef {
040                    Connector connector;
041                    int refCount = 0;
042                    public ConnectorRef(Connector connector) {
043                            this.connector=connector;
044                            increment();
045                    }
046                    public int increment() {
047                            return ++refCount;
048                    }
049                    public int decrement() {
050                            return --refCount;
051                    }
052            }
053            
054            final HashMap<String, ConnectorRef> connectors = new HashMap<String, ConnectorRef>();
055            
056            
057            
058            
059            @Override
060            protected void doStart() throws Exception {
061                    server = createServer();
062                    super.doStart();
063            }
064    
065            private Server createServer() throws Exception {
066                    setCamelServlet(new CamelServlet());
067                    
068                    Server server = new Server();
069                    Context context = new Context(Context.NO_SECURITY|Context.NO_SESSIONS);
070                            
071                    context.setContextPath("/");
072                    ServletHolder holder = new ServletHolder();
073                    holder.setServlet(getCamelServlet());
074                    context.addServlet(holder, "/*");               
075                    server.setHandler(context);
076                            
077                    server.start();
078                    return server;
079            }
080    
081            @Override
082            protected void doStop() throws Exception {
083                    for (ConnectorRef connectorRef : connectors.values()) {
084                            connectorRef.connector.stop();
085                    }
086                    connectors.clear();
087                    
088                    server.stop();
089                    super.doStop();
090            }
091    
092            @Override
093            public void connect(HttpConsumer consumer) throws Exception {
094                    
095                    // Make sure that there is a connector for the requested endpoint.
096                    HttpEndpoint endpoint = (HttpEndpoint) consumer.getEndpoint();
097                    String connectorKey = endpoint.getProtocol()+":"+endpoint.getPort();
098                    
099                    synchronized(connectors) {
100                            ConnectorRef connectorRef = connectors.get(connectorKey);
101                            if( connectorRef == null ) {
102                                    Connector connector;
103                                    if( "https".equals(endpoint.getProtocol()) ) {
104                                            connector = new SslSocketConnector();
105                                    } else {
106                                            connector = new SelectChannelConnector();
107                                    }
108                                    connector.setPort(endpoint.getPort());
109                                    server.addConnector(connector);
110                                    connector.start();
111                                    connectorRef = new ConnectorRef(connector);
112                            } else {
113                                    // ref track the connector
114                                    connectorRef.increment();
115                            }
116                    }
117                    
118                    super.connect(consumer);
119            }
120            
121            @Override
122            public void disconnect(HttpConsumer consumer) throws Exception {
123                    super.disconnect(consumer);
124                    
125                    // If the connector is not needed anymore.. then stop it.
126                    HttpEndpoint endpoint = (HttpEndpoint) consumer.getEndpoint();
127                    String connectorKey = endpoint.getProtocol()+":"+endpoint.getPort();
128                    
129                    synchronized(connectors) {
130                            ConnectorRef connectorRef = connectors.get(connectorKey);
131                            if( connectorRef != null ) {
132                                    if( connectorRef.decrement() == 0 ) {
133                                            server.removeConnector(connectorRef.connector);
134                                            connectorRef.connector.stop();
135                                            connectors.remove(connectorKey);
136                                    }
137                            }
138                    }
139            }
140    }