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, ManagementContext context, ObjectName connectorName)
053            throws IOException {
054            super(connector, transport, broker, factory);
055            this.managementContext = context;
056            this.connectorName = connectorName;
057            this.mbean = new ConnectionView(this, managementContext);
058            this.populateUserName = broker.getBrokerService().isPopulateUserNameInMBeans();
059            if (managementContext.isAllowRemoteAddressInMBeanNames()) {
060                byAddressName = createByAddressObjectName("address", transport.getRemoteAddress());
061                registerMBean(byAddressName);
062            }
063        }
064    
065        @Override
066        public void stopAsync() {
067            if (!isStopping()) {
068                synchronized (this) {
069                    unregisterMBean(byClientIdName);
070                    unregisterMBean(byAddressName);
071                    byClientIdName = null;
072                    byAddressName = null;
073                }
074            }
075            super.stopAsync();
076        }
077    
078        public Response processAddConnection(ConnectionInfo info) throws Exception {
079            Response answer = super.processAddConnection(info);
080            String clientId = info.getClientId();
081            if (populateUserName) {
082                ((ConnectionView) mbean).setUserName(info.getUserName());
083            }
084            if (clientId != null) {
085                if (byClientIdName == null) {
086                    byClientIdName = createByClientIdObjectName(clientId);
087                    registerMBean(byClientIdName);
088                }
089            }
090            return answer;
091        }
092    
093        // Implementation methods
094        // -------------------------------------------------------------------------
095        protected void registerMBean(ObjectName name) {
096            if (name != null) {
097                try {
098                    AnnotatedMBean.registerMBean(managementContext, mbean, name);
099                } catch (Throwable e) {
100                    LOG.warn("Failed to register MBean: " + name);
101                    LOG.debug("Failure reason: " + e, e);
102                }
103            }
104        }
105    
106        protected void unregisterMBean(ObjectName name) {
107            if (name != null) {
108                try {
109                    managementContext.unregisterMBean(name);
110                } catch (Throwable e) {
111                    LOG.warn("Failed to unregister mbean: " + name);
112                    LOG.debug("Failure reason: " + e, e);
113                }
114            }
115        }
116    
117        protected ObjectName createByAddressObjectName(String type, String value) throws IOException {
118            Hashtable<String, String> map = connectorName.getKeyPropertyList();
119            try {
120                return new ObjectName(connectorName.getDomain() + ":" + "BrokerName="
121                                      + JMXSupport.encodeObjectNamePart((String)map.get("BrokerName")) + ","
122                                      + "Type=Connection," + "ConnectorName="
123                                      + JMXSupport.encodeObjectNamePart((String)map.get("ConnectorName")) + ","
124                                      + "ViewType=" + JMXSupport.encodeObjectNamePart(type) + "," + "Name="
125                                      + JMXSupport.encodeObjectNamePart(value));
126            } catch (Throwable e) {
127                throw IOExceptionSupport.create(e);
128            }
129        }
130    
131        protected ObjectName createByClientIdObjectName(String value) throws IOException {
132            Hashtable<String, String> map = connectorName.getKeyPropertyList();
133            try {
134                return new ObjectName(connectorName.getDomain() + ":" + "BrokerName="
135                                      + JMXSupport.encodeObjectNamePart((String)map.get("BrokerName")) + ","
136                                      + "Type=Connection," + "ConnectorName="
137                                      + JMXSupport.encodeObjectNamePart((String)map.get("ConnectorName")) + ","
138                                      + "Connection=" + JMXSupport.encodeObjectNamePart(value));
139            } catch (Throwable e) {
140                throw IOExceptionSupport.create(e);
141            }
142        }
143    
144    }