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 }