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 */
017package org.apache.activemq.transport.auto.nio;
018
019import java.io.IOException;
020import java.net.Socket;
021import java.net.URI;
022import java.net.URISyntaxException;
023import java.nio.ByteBuffer;
024import java.util.HashMap;
025import java.util.Map;
026import java.util.Set;
027
028import javax.net.ServerSocketFactory;
029import javax.net.ssl.SSLEngine;
030
031import org.apache.activemq.broker.BrokerService;
032import org.apache.activemq.broker.BrokerServiceAware;
033import org.apache.activemq.broker.SslContext;
034import org.apache.activemq.openwire.OpenWireFormatFactory;
035import org.apache.activemq.transport.Transport;
036import org.apache.activemq.transport.TransportServer;
037import org.apache.activemq.transport.auto.AutoTcpTransportServer;
038import org.apache.activemq.transport.auto.AutoTransportUtils;
039import org.apache.activemq.transport.nio.NIOSSLTransport;
040import org.apache.activemq.transport.nio.NIOSSLTransportFactory;
041import org.apache.activemq.transport.tcp.TcpTransport.InitBuffer;
042import org.apache.activemq.transport.tcp.TcpTransportFactory;
043import org.apache.activemq.util.IOExceptionSupport;
044import org.apache.activemq.util.IntrospectionSupport;
045import org.apache.activemq.util.URISupport;
046import org.apache.activemq.wireformat.WireFormat;
047
048/**
049 *
050 *
051 */
052public class AutoNioSslTransportFactory extends NIOSSLTransportFactory implements BrokerServiceAware {
053    protected BrokerService brokerService;
054
055    /* (non-Javadoc)
056     * @see org.apache.activemq.broker.BrokerServiceAware#setBrokerService(org.apache.activemq.broker.BrokerService)
057     */
058    @Override
059    public void setBrokerService(BrokerService brokerService) {
060        this.brokerService = brokerService;
061    }
062
063    @Override
064    protected AutoNIOSSLTransportServer createTcpTransportServer(URI location, ServerSocketFactory serverSocketFactory) throws IOException, URISyntaxException {
065        return new AutoNIOSSLTransportServer(context, this, location, serverSocketFactory, brokerService, enabledProtocols) {
066
067            @Override
068            protected Transport createTransport(Socket socket, WireFormat format, SSLEngine engine, InitBuffer initBuffer,
069                     ByteBuffer inputBuffer, TcpTransportFactory detectedFactory) throws IOException {
070                NIOSSLTransport nioSslTransport = (NIOSSLTransport) detectedFactory.createTransport(
071                        format, socket, engine, initBuffer, inputBuffer);
072
073                if (format.getClass().toString().contains("MQTT")) {
074                    if (!allowLinkStealingSet) {
075                        this.setAllowLinkStealing(true);
076                    }
077                }
078
079                if (context != null) {
080                    nioSslTransport.setSslContext(context);
081                }
082
083                nioSslTransport.setNeedClientAuth(isNeedClientAuth());
084                nioSslTransport.setWantClientAuth(isWantClientAuth());
085
086                return nioSslTransport;
087            }
088
089        };
090
091    }
092
093    boolean allowLinkStealingSet = false;
094    private Set<String> enabledProtocols;
095
096    @Override
097    public TransportServer doBind(final URI location) throws IOException {
098        try {
099            if (SslContext.getCurrentSslContext() != null) {
100                try {
101                    context = SslContext.getCurrentSslContext().getSSLContext();
102                } catch (Exception e) {
103                    throw new IOException(e);
104                }
105            }
106
107            Map<String, String> options = new HashMap<String, String>(URISupport.parseParameters(location));
108
109            Map<String, Object> autoProperties = IntrospectionSupport.extractProperties(options, "auto.");
110            this.enabledProtocols = AutoTransportUtils.parseProtocols((String) autoProperties.get("protocols"));
111
112            ServerSocketFactory serverSocketFactory = createServerSocketFactory();
113            AutoTcpTransportServer server = createTcpTransportServer(location, serverSocketFactory);
114            server.setWireFormatFactory(new OpenWireFormatFactory());
115            if (options.get("allowLinkStealing") != null){
116                allowLinkStealingSet = true;
117            }
118            IntrospectionSupport.setProperties(server, options);
119            server.setAutoTransportOptions(IntrospectionSupport.extractProperties(options, "auto."));
120            server.setTransportOption(IntrospectionSupport.extractProperties(options, "transport."));
121            server.setWireFormatOptions(AutoTransportUtils.extractWireFormatOptions(options));
122            server.bind();
123
124            return server;
125        } catch (URISyntaxException e) {
126            throw IOExceptionSupport.create(e);
127        }
128    }
129
130
131}