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.logging.log4j.jmx.gui;
018    
019    import java.io.IOException;
020    import java.util.ArrayList;
021    import java.util.List;
022    import java.util.Set;
023    
024    import javax.management.JMX;
025    import javax.management.MBeanServerConnection;
026    import javax.management.MalformedObjectNameException;
027    import javax.management.ObjectName;
028    import javax.management.remote.JMXConnector;
029    
030    import org.apache.logging.log4j.core.helpers.Assert;
031    import org.apache.logging.log4j.core.jmx.ContextSelectorAdminMBean;
032    import org.apache.logging.log4j.core.jmx.LoggerContextAdminMBean;
033    import org.apache.logging.log4j.core.jmx.StatusLoggerAdminMBean;
034    
035    /**
036     * This class allows client-side code to perform operations on remote
037     * (server-side) MBeans via proxies.
038     */
039    public class Client {
040        private JMXConnector connector;
041        private final MBeanServerConnection connection;
042        private StatusLoggerAdminMBean statusLoggerAdmin;
043        private ContextSelectorAdminMBean contextSelectorAdmin;
044        private List<LoggerContextAdminMBean> contextAdminList;
045    
046        /**
047         * Constructs a new {@code Client} object and creates proxies for all known
048         * remote MBeans.
049         * 
050         * @param connector used to create the MBean server connection through which
051         *            to communicate with the remote mbeans
052         * @throws MalformedObjectNameException if a problem occurred identifying
053         *             one of the remote mbeans
054         * @throws IOException if the connection failed
055         */
056        public Client(final JMXConnector connector) throws MalformedObjectNameException,
057                IOException {
058            this.connector = Assert.isNotNull(connector, "JMXConnector");
059            this.connector.connect();
060            this.connection = connector.getMBeanServerConnection();
061            init();
062        }
063    
064        /**
065         * Constructs a new {@code Client} object and creates proxies for all known
066         * remote MBeans.
067         * 
068         * @param mBeanServerConnection the MBean server connection through which to
069         *            communicate with the remote mbeans
070         * @throws MalformedObjectNameException if a problem occurred identifying
071         *             one of the remote mbeans
072         * @throws IOException if the connection failed
073         */
074        public Client(final MBeanServerConnection mBeanServerConnection)
075                throws MalformedObjectNameException, IOException {
076            this.connection = mBeanServerConnection;
077            init();
078        }
079    
080        private void init() throws MalformedObjectNameException, IOException {
081            statusLoggerAdmin = JMX.newMBeanProxy(connection, //
082                    new ObjectName(StatusLoggerAdminMBean.NAME), //
083                    StatusLoggerAdminMBean.class, true);
084    
085            contextSelectorAdmin = JMX.newMBeanProxy(connection, //
086                    new ObjectName(ContextSelectorAdminMBean.NAME), //
087                    ContextSelectorAdminMBean.class, false);
088    
089            contextAdminList = new ArrayList<LoggerContextAdminMBean>();
090            final String pattern = String.format(LoggerContextAdminMBean.PATTERN, "*");
091            final ObjectName search = new ObjectName(pattern);
092            final Set<ObjectName> found = connection.queryNames(search, null);
093            for (final ObjectName contextName : found) {
094                final LoggerContextAdminMBean ctx = JMX.newMBeanProxy(connection, //
095                        contextName, //
096                        LoggerContextAdminMBean.class, false);
097                contextAdminList.add(ctx);
098    
099                // TODO Appenders, LoggerConfigs
100            }
101        }
102    
103        /**
104         * Returns a proxy that allows operations to be performed on the remote
105         * {@code ContextSelectorAdminMBean}.
106         * 
107         * @return a proxy to the remote {@code ContextSelectorAdminMBean}
108         */
109        public ContextSelectorAdminMBean getContextSelectorAdmin() {
110            return contextSelectorAdmin;
111        }
112    
113        /**
114         * Returns a list of proxies that allow operations to be performed on the
115         * remote {@code LoggerContextAdminMBean}s.
116         * 
117         * @return a list of proxies to the remote {@code LoggerContextAdminMBean}s
118         */
119        public List<LoggerContextAdminMBean> getLoggerContextAdmins() {
120            return new ArrayList<LoggerContextAdminMBean>(contextAdminList);
121        }
122    
123        /**
124         * Closes the client connection to its server. Any ongoing or new requests
125         * to the MBeanServerConnection will fail.
126         */
127        public void close() {
128            try {
129                connector.close();
130            } catch (final IOException e) {
131                e.printStackTrace();
132            }
133        }
134    
135        /**
136         * Returns the MBean server connection through which to communicate with the
137         * remote mbeans.
138         * 
139         * @return the MBean server connection
140         */
141        public MBeanServerConnection getConnection() {
142            return connection;
143        }
144    
145        /**
146         * Returns a proxy that allows operations to be performed on the remote
147         * {@code StatusLoggerAdminMBean}.
148         * 
149         * @return a proxy to the remote {@code StatusLoggerAdminMBean}
150         */
151        public StatusLoggerAdminMBean getStatusLoggerAdmin() {
152            return statusLoggerAdmin;
153        }
154    }