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.http; 018 019 import java.util.HashMap; 020 021 import org.mortbay.jetty.Connector; 022 import org.mortbay.jetty.Server; 023 import org.mortbay.jetty.nio.SelectChannelConnector; 024 import org.mortbay.jetty.security.SslSocketConnector; 025 import org.mortbay.jetty.servlet.Context; 026 import org.mortbay.jetty.servlet.ServletHolder; 027 028 /** 029 * An HttpComponent which starts an embedded Jetty for to handle consuming from 030 * http endpoints. 031 * 032 * @version $Revision: 525142 $ 033 */ 034 public class JettyHttpComponent extends HttpComponent { 035 036 Server server; 037 038 class ConnectorRef { 039 Connector connector; 040 int refCount; 041 042 public ConnectorRef(Connector connector) { 043 this.connector = connector; 044 increment(); 045 } 046 047 public int increment() { 048 return ++refCount; 049 } 050 051 public int decrement() { 052 return --refCount; 053 } 054 } 055 056 final HashMap<String, ConnectorRef> connectors = new HashMap<String, ConnectorRef>(); 057 058 @Override 059 protected void doStart() throws Exception { 060 server = createServer(); 061 super.doStart(); 062 } 063 064 private Server createServer() throws Exception { 065 setCamelServlet(new CamelServlet()); 066 067 Server server = new Server(); 068 Context context = new Context(Context.NO_SECURITY | Context.NO_SESSIONS); 069 070 context.setContextPath("/"); 071 ServletHolder holder = new ServletHolder(); 072 holder.setServlet(getCamelServlet()); 073 context.addServlet(holder, "/*"); 074 server.setHandler(context); 075 076 server.start(); 077 return server; 078 } 079 080 @Override 081 protected void doStop() throws Exception { 082 for (ConnectorRef connectorRef : connectors.values()) { 083 connectorRef.connector.stop(); 084 } 085 connectors.clear(); 086 087 server.stop(); 088 super.doStop(); 089 } 090 091 @Override 092 public void connect(HttpConsumer consumer) throws Exception { 093 094 // Make sure that there is a connector for the requested endpoint. 095 HttpEndpoint endpoint = (HttpEndpoint)consumer.getEndpoint(); 096 String connectorKey = endpoint.getProtocol() + ":" + endpoint.getPort(); 097 098 synchronized (connectors) { 099 ConnectorRef connectorRef = connectors.get(connectorKey); 100 if (connectorRef == null) { 101 Connector connector; 102 if ("https".equals(endpoint.getProtocol())) { 103 connector = new SslSocketConnector(); 104 } else { 105 connector = new SelectChannelConnector(); 106 } 107 connector.setPort(endpoint.getPort()); 108 server.addConnector(connector); 109 connector.start(); 110 connectorRef = new ConnectorRef(connector); 111 } else { 112 // ref track the connector 113 connectorRef.increment(); 114 } 115 } 116 117 super.connect(consumer); 118 } 119 120 @Override 121 public void disconnect(HttpConsumer consumer) throws Exception { 122 super.disconnect(consumer); 123 124 // If the connector is not needed anymore.. then stop it. 125 HttpEndpoint endpoint = (HttpEndpoint)consumer.getEndpoint(); 126 String connectorKey = endpoint.getProtocol() + ":" + endpoint.getPort(); 127 128 synchronized (connectors) { 129 ConnectorRef connectorRef = connectors.get(connectorKey); 130 if (connectorRef != null) { 131 if (connectorRef.decrement() == 0) { 132 server.removeConnector(connectorRef.connector); 133 connectorRef.connector.stop(); 134 connectors.remove(connectorKey); 135 } 136 } 137 } 138 } 139 }