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.broker.jmx; 018 019import org.apache.activemq.broker.Broker; 020import org.apache.activemq.broker.TransportConnection; 021import org.apache.activemq.broker.TransportConnector; 022import org.apache.activemq.command.ConnectionInfo; 023import org.apache.activemq.command.Response; 024import org.apache.activemq.thread.TaskRunnerFactory; 025import org.apache.activemq.transport.Transport; 026import org.apache.activemq.util.IOExceptionSupport; 027import org.apache.activemq.util.JMXSupport; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030import java.io.IOException; 031import java.util.Hashtable; 032import javax.management.ObjectName; 033 034/** 035 * A managed transport connection 036 * 037 * 038 */ 039public 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 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}