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