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