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