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.activemq.broker.jmx;
018    
019    import java.io.IOException;
020    import java.util.Hashtable;
021    
022    import javax.management.ObjectName;
023    
024    import org.apache.activemq.broker.Broker;
025    import org.apache.activemq.broker.TransportConnection;
026    import org.apache.activemq.broker.TransportConnector;
027    import org.apache.activemq.command.ConnectionInfo;
028    import org.apache.activemq.command.Response;
029    import org.apache.activemq.thread.TaskRunnerFactory;
030    import org.apache.activemq.transport.Transport;
031    import org.apache.activemq.util.IOExceptionSupport;
032    import org.apache.activemq.util.JMXSupport;
033    import org.slf4j.Logger;
034    import org.slf4j.LoggerFactory;
035    
036    /**
037     * A managed transport connection
038     */
039    public class ManagedTransportConnection extends TransportConnection {
040        private static final Logger LOG = LoggerFactory.getLogger(ManagedTransportConnection.class);
041    
042        private final ManagementContext managementContext;
043        private final ObjectName connectorName;
044        private ConnectionViewMBean mbean;
045    
046        private ObjectName byClientIdName;
047        private ObjectName byAddressName;
048    
049        private final boolean populateUserName;
050    
051        public ManagedTransportConnection(TransportConnector connector, Transport transport, Broker broker,
052                                          TaskRunnerFactory factory, TaskRunnerFactory stopFactory,
053                                          ManagementContext context, ObjectName connectorName)
054            throws IOException {
055            super(connector, transport, broker, factory, stopFactory);
056            this.managementContext = context;
057            this.connectorName = connectorName;
058            this.mbean = new ConnectionView(this, managementContext);
059            this.populateUserName = broker.getBrokerService().isPopulateUserNameInMBeans();
060            if (managementContext.isAllowRemoteAddressInMBeanNames()) {
061                byAddressName = createByAddressObjectName("address", transport.getRemoteAddress());
062                registerMBean(byAddressName);
063            }
064        }
065    
066        @Override
067        public void stopAsync() {
068            if (!isStopping()) {
069                synchronized (this) {
070                    unregisterMBean(byClientIdName);
071                    unregisterMBean(byAddressName);
072                    byClientIdName = null;
073                    byAddressName = null;
074                }
075            }
076            super.stopAsync();
077        }
078    
079        public Response processAddConnection(ConnectionInfo info) throws Exception {
080            Response answer = super.processAddConnection(info);
081            String clientId = info.getClientId();
082            if (populateUserName) {
083                ((ConnectionView) mbean).setUserName(info.getUserName());
084            }
085            if (clientId != null) {
086                if (byClientIdName == null) {
087                    byClientIdName = createByClientIdObjectName(clientId);
088                    registerMBean(byClientIdName);
089                }
090            }
091            return answer;
092        }
093    
094        // Implementation methods
095        // -------------------------------------------------------------------------
096        protected void registerMBean(ObjectName name) {
097            if (name != null) {
098                try {
099                    AnnotatedMBean.registerMBean(managementContext, mbean, name);
100                } catch (Throwable e) {
101                    LOG.warn("Failed to register MBean: " + name);
102                    LOG.debug("Failure reason: " + e, e);
103                }
104            }
105        }
106    
107        protected void unregisterMBean(ObjectName name) {
108            if (name != null) {
109                try {
110                    managementContext.unregisterMBean(name);
111                } catch (Throwable e) {
112                    LOG.warn("Failed to unregister mbean: " + name);
113                    LOG.debug("Failure reason: " + e, e);
114                }
115            }
116        }
117    
118        protected ObjectName createByAddressObjectName(String type, String value) throws IOException {
119            Hashtable<String, String> map = connectorName.getKeyPropertyList();
120            try {
121                return new ObjectName(connectorName.getDomain() + ":" + "BrokerName="
122                                      + JMXSupport.encodeObjectNamePart((String)map.get("BrokerName")) + ","
123                                      + "Type=Connection," + "ConnectorName="
124                                      + JMXSupport.encodeObjectNamePart((String)map.get("ConnectorName")) + ","
125                                      + "ViewType=" + JMXSupport.encodeObjectNamePart(type) + "," + "Name="
126                                      + JMXSupport.encodeObjectNamePart(value));
127            } catch (Throwable e) {
128                throw IOExceptionSupport.create(e);
129            }
130        }
131    
132        protected ObjectName createByClientIdObjectName(String value) throws IOException {
133            Hashtable<String, String> map = connectorName.getKeyPropertyList();
134            try {
135                return new ObjectName(connectorName.getDomain() + ":" + "BrokerName="
136                                      + JMXSupport.encodeObjectNamePart((String)map.get("BrokerName")) + ","
137                                      + "Type=Connection," + "ConnectorName="
138                                      + JMXSupport.encodeObjectNamePart((String)map.get("ConnectorName")) + ","
139                                      + "Connection=" + JMXSupport.encodeObjectNamePart(value));
140            } catch (Throwable e) {
141                throw IOExceptionSupport.create(e);
142            }
143        }
144    
145    }