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 018package org.apache.activemq.transport.ws; 019 020import java.net.InetSocketAddress; 021import java.net.URI; 022import java.util.Map; 023 024import javax.servlet.Servlet; 025 026import org.apache.activemq.command.BrokerInfo; 027import org.apache.activemq.transport.SocketConnectorFactory; 028import org.apache.activemq.transport.WebTransportServerSupport; 029import org.apache.activemq.util.IntrospectionSupport; 030import org.apache.activemq.util.ServiceStopper; 031import org.eclipse.jetty.server.Connector; 032import org.eclipse.jetty.server.Server; 033import org.eclipse.jetty.servlet.ServletContextHandler; 034import org.eclipse.jetty.servlet.ServletHolder; 035import org.slf4j.Logger; 036import org.slf4j.LoggerFactory; 037 038/** 039 * Creates a web server and registers web socket server 040 * 041 */ 042public class WSTransportServer extends WebTransportServerSupport { 043 044 private static final Logger LOG = LoggerFactory.getLogger(WSTransportServer.class); 045 046 public WSTransportServer(URI location) { 047 super(location); 048 this.bindAddress = location; 049 socketConnectorFactory = new SocketConnectorFactory(); 050 } 051 052 @Override 053 protected void doStart() throws Exception { 054 createServer(); 055 056 if (connector == null) { 057 connector = socketConnectorFactory.createConnector(server); 058 } 059 060 URI boundTo = bind(); 061 062 ServletContextHandler contextHandler = 063 new ServletContextHandler(server, "/", ServletContextHandler.NO_SECURITY); 064 065 ServletHolder holder = new ServletHolder(); 066 Map<String, Object> webSocketOptions = IntrospectionSupport.extractProperties(transportOptions, "websocket."); 067 for(Map.Entry<String,Object> webSocketEntry : webSocketOptions.entrySet()) { 068 Object value = webSocketEntry.getValue(); 069 if (value != null) { 070 holder.setInitParameter(webSocketEntry.getKey(), value.toString()); 071 } 072 } 073 074 holder.setServlet(createWSServlet()); 075 contextHandler.addServlet(holder, "/"); 076 077 contextHandler.setAttribute("acceptListener", getAcceptListener()); 078 079 server.start(); 080 081 // Update the Connect To URI with our actual location in case the configured port 082 // was set to zero so that we report the actual port we are listening on. 083 084 int port = getConnectorLocalPort(); 085 if (port == -1) { 086 port = boundTo.getPort(); 087 } 088 089 setConnectURI(new URI(boundTo.getScheme(), 090 boundTo.getUserInfo(), 091 boundTo.getHost(), 092 port, 093 boundTo.getPath(), 094 boundTo.getQuery(), 095 boundTo.getFragment())); 096 097 LOG.info("Listening for connections at {}", getConnectURI()); 098 } 099 100 private Servlet createWSServlet() throws Exception { 101 if (Server.getVersion().startsWith("9")) { 102 return (Servlet)Class.forName("org.apache.activemq.transport.ws.jetty9.WSServlet", true, 103 getClass().getClassLoader()).newInstance(); 104 } 105 return (Servlet)Class.forName("org.apache.activemq.transport.ws.jetty8.WSServlet", true, 106 getClass().getClassLoader()).newInstance(); 107 } 108 109 private int getConnectorLocalPort() throws Exception { 110 return (Integer)connector.getClass().getMethod("getLocalPort").invoke(connector); 111 } 112 113 @Override 114 protected void doStop(ServiceStopper stopper) throws Exception { 115 Server temp = server; 116 server = null; 117 if (temp != null) { 118 temp.stop(); 119 } 120 } 121 122 @Override 123 public InetSocketAddress getSocketAddress() { 124 return null; 125 } 126 127 @Override 128 public void setBrokerInfo(BrokerInfo brokerInfo) { 129 } 130 131 protected void setConnector(Connector connector) { 132 this.connector = connector; 133 } 134 135 @Override 136 public void setTransportOption(Map<String, Object> transportOptions) { 137 Map<String, Object> socketOptions = IntrospectionSupport.extractProperties(transportOptions, "transport."); 138 socketConnectorFactory.setTransportOptions(socketOptions); 139 super.setTransportOption(transportOptions); 140 } 141 142 @Override 143 public boolean isSslServer() { 144 return false; 145 } 146}