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 org.apache.activemq.broker.Broker;
020    import org.apache.activemq.broker.TransportConnection;
021    import org.apache.activemq.broker.TransportConnector;
022    import org.apache.activemq.command.ConnectionInfo;
023    import org.apache.activemq.command.Response;
024    import org.apache.activemq.thread.TaskRunnerFactory;
025    import org.apache.activemq.transport.Transport;
026    import org.apache.activemq.util.IOExceptionSupport;
027    import org.apache.activemq.util.JMXSupport;
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    import java.io.IOException;
031    import java.util.Hashtable;
032    import javax.management.ObjectName;
033    
034    /**
035     * A managed transport connection
036     * 
037     * @version $Revision: 1.1 $
038     */
039    public class ManagedTransportConnection extends TransportConnection {
040        private static final Log LOG = LogFactory.getLog(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        public ManagedTransportConnection(TransportConnector connector, Transport transport, Broker broker,
050                                          TaskRunnerFactory factory, ManagementContext context, ObjectName connectorName)
051            throws IOException {
052            super(connector, transport, broker, factory);
053            this.managementContext = context;
054            this.connectorName = connectorName;
055            this.mbean = new ConnectionView(this);
056            byAddressName = createByAddressObjectName("address", transport.getRemoteAddress());
057            registerMBean(byAddressName);
058        }
059    
060        public void doStop() throws Exception {
061            if (isStarting()) {
062                setPendingStop(true);
063                return;
064            }
065            synchronized (this) {
066                unregisterMBean(byClientIdName);
067                unregisterMBean(byAddressName);
068                byClientIdName = null;
069                byAddressName = null;
070            }
071            super.doStop();
072        }
073    
074        /**
075         * Sets the connection ID of this connection. On startup this connection ID
076         * is set to an incrementing counter; once the client registers it is set to
077         * the clientID of the JMS client.
078         */
079        public void setConnectionId(String connectionId) throws IOException {
080        }
081    
082        public Response processAddConnection(ConnectionInfo info) throws Exception {
083            Response answer = super.processAddConnection(info);
084            String clientId = info.getClientId();
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            // Build the object name for the destination
120            Hashtable map = connectorName.getKeyPropertyList();
121            try {
122                return new ObjectName(connectorName.getDomain() + ":" + "BrokerName="
123                                      + JMXSupport.encodeObjectNamePart((String)map.get("BrokerName")) + ","
124                                      + "Type=Connection," + "ConnectorName="
125                                      + JMXSupport.encodeObjectNamePart((String)map.get("ConnectorName")) + ","
126                                      + "ViewType=" + JMXSupport.encodeObjectNamePart(type) + "," + "Name="
127                                      + JMXSupport.encodeObjectNamePart(value));
128            } catch (Throwable e) {
129                throw IOExceptionSupport.create(e);
130            }
131        }
132    
133        protected ObjectName createByClientIdObjectName(String value) throws IOException {
134            // Build the object name for the destination
135            Hashtable map = connectorName.getKeyPropertyList();
136            try {
137                return new ObjectName(connectorName.getDomain() + ":" + "BrokerName="
138                                      + JMXSupport.encodeObjectNamePart((String)map.get("BrokerName")) + ","
139                                      + "Type=Connection," + "ConnectorName="
140                                      + JMXSupport.encodeObjectNamePart((String)map.get("ConnectorName")) + ","
141                                      + "Connection=" + JMXSupport.encodeObjectNamePart(value));
142            } catch (Throwable e) {
143                throw IOExceptionSupport.create(e);
144            }
145        }
146    
147    }