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 }