📄 scanmanager.java
字号:
/* * ScanManager.java * * Created on July 10, 2006, 2:17 PM * * @(#)ScanManager.java 1.2 06/08/02 * * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * -Redistribution of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */package com.sun.jmx.examples.scandir;import static com.sun.jmx.examples.scandir.ScanManagerMXBean.ScanState.*;import com.sun.jmx.examples.scandir.ScanManagerMXBean.ScanState;import com.sun.jmx.examples.scandir.config.DirectoryScannerConfig;import com.sun.jmx.examples.scandir.config.ScanManagerConfig;import java.io.File;import java.io.IOException;import java.lang.management.ManagementFactory;import java.util.ArrayList;import java.util.Collections;import java.util.EnumSet;import java.util.HashMap;import java.util.Map;import java.util.Map.Entry;import java.util.Timer;import java.util.TimerTask;import java.util.concurrent.BlockingQueue;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentLinkedQueue;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.Semaphore;import java.util.concurrent.TimeUnit;import java.util.logging.Level;import java.util.logging.Logger;import javax.management.AttributeChangeNotification;import javax.management.InstanceNotFoundException;import javax.management.JMException;import javax.management.JMX;import javax.management.ListenerNotFoundException;import javax.management.MBeanNotificationInfo;import javax.management.MBeanRegistration;import javax.management.MBeanServer;import javax.management.MBeanServerConnection;import javax.management.MalformedObjectNameException;import javax.management.Notification;import javax.management.NotificationBroadcasterSupport;import javax.management.NotificationEmitter;import javax.management.NotificationFilter;import javax.management.NotificationListener;import javax.management.ObjectInstance;import javax.management.ObjectName;/** * <p> * The <code>ScanManager</code> is responsible for applying a configuration, * starting and scheduling directory scans, and reporting application state. * </p> * <p> * The ScanManager MBean is a singleton MBean which controls * scan session. The ScanManager name is defined by * {@link #SCAN_MANAGER_NAME ScanManager.SCAN_MANAGER_NAME}. * </p> * <p> * The <code>ScanManager</code> MBean is the entry point of the <i>scandir</i> * application management interface. It is from this MBean that all other MBeans * will be created and registered. * </p> * * @author Sun Microsystems, 2006 - All rights reserved. */public class ScanManager implements ScanManagerMXBean, NotificationEmitter, MBeanRegistration { /** * A logger for this class. **/ private static final Logger LOG = Logger.getLogger(ScanManager.class.getName()); /** * The name of the ScanManager singleton MBean. **/ public final static ObjectName SCAN_MANAGER_NAME = makeSingletonName(ScanManagerMXBean.class); /** * Sequence number used for sending notifications. We use this * sequence number throughout the application. **/ private static long seqNumber=0; /** * The NotificationBroadcasterSupport object used to handle * listener registration. **/ private final NotificationBroadcasterSupport broadcaster; /** * The MBeanServer in which this MBean is registered. We obtain * this reference by implementing the {@link MBeanRegistration} * interface. **/ private volatile MBeanServer mbeanServer; /** * A queue of pending notifications we are about to send. * We're using a BlockingQueue in order to avoid sending * notifications from within a synchronized block. **/ private final BlockingQueue<Notification> pendingNotifs; /** * The state of the scan session. **/ private volatile ScanState state = STOPPED; /** * The list of DirectoryScannerMBean that are run by a scan session. **/ private final Map<ObjectName,DirectoryScannerMXBean> scanmap; /** * The list of ScanDirConfigMXBean that were created by this MBean. **/ private final Map<ObjectName, ScanDirConfigMXBean> configmap; // The ResultLogManager for this application. private final ResultLogManager log; /** * We use a semaphore to ensure proper sequencing of exclusive * action. The logic we have implemented is to fail - rather * than block, if an exclusive action is already in progress. **/ private final Semaphore sequencer = new Semaphore(1); // A proxy to the current ScanDirConfigMXBean which holds the current // configuration data. // private volatile ScanDirConfigMXBean config = null; // Avoid to write parameters twices when creating a new ConcurrentHashMap. // private static <K, V> Map<K, V> newConcurrentHashMap() { return new ConcurrentHashMap<K, V>(); } // Avoid to write parameters twices when creating a new HashMap. // private static <K, V> Map<K, V> newHashMap() { return new HashMap<K, V>(); } /** * Creates a default singleton ObjectName for a given class. * @param clazz The interface class of the MBean for which we want to obtain * a default singleton name, or its implementation class. * Give one or the other depending on what you wish to see in * the value of the key {@code type=}. * @return A default singleton name for a singleton MBean class. * @throws IllegalArgumentException if the name can't be created * for some unfathomable reason (e.g. an unexpected * exception was raised). **/ public final static ObjectName makeSingletonName(Class clazz) { try { final Package p = clazz.getPackage(); final String packageName = (p==null)?null:p.getName(); final String className = clazz.getSimpleName(); final String domain; if (packageName == null || packageName.length()==0) { // We use a reference to ScanDirAgent.class to ease // to keep track of possible class renaming. domain = ScanDirAgent.class.getSimpleName(); } else { domain = packageName; } final ObjectName name = new ObjectName(domain,"type",className); return name; } catch (Exception x) { final IllegalArgumentException iae = new IllegalArgumentException(String.valueOf(clazz),x); throw iae; } } /** * Creates a default ObjectName with keys <code>type=</code> and * <code>name=</code> for an instance of a given MBean interface class. * @param clazz The interface class of the MBean for which we want to obtain * a default name, or its implementation class. * Give one or the other depending on what you wish to see in * the value of the key {@code type=}. * @param name The value of the <code>name=</code> key. * @return A default name for an instance of the given MBean interface class. * @throws IllegalArgumentException if the name can't be created. * (e.g. an unexpected exception was raised). **/ public static final ObjectName makeMBeanName(Class clazz, String name) { try { return ObjectName. getInstance(makeSingletonName(clazz) .toString()+",name="+name); } catch (MalformedObjectNameException x) { final IllegalArgumentException iae = new IllegalArgumentException(String.valueOf(name),x); throw iae; } } /** * Return the ObjectName for a DirectoryScannerMXBean of that name. * This is {@code makeMBeanName(DirectoryScannerMXBean.class,name)}. * @param name The value of the <code>name=</code> key. * @return the ObjectName for a DirectoryScannerMXBean of that name. */ public static final ObjectName makeDirectoryScannerName(String name) { return makeMBeanName(DirectoryScannerMXBean.class,name); } /** * Return the ObjectName for a {@code ScanDirConfigMXBean} of that name. * This is {@code makeMBeanName(ScanDirConfigMXBean.class,name)}. * @param name The value of the <code>name=</code> key. * @return the ObjectName for a {@code ScanDirConfigMXBean} of that name. */ public static final ObjectName makeScanDirConfigName(String name) { return makeMBeanName(ScanDirConfigMXBean.class,name); } /** * Create and register a new singleton instance of the ScanManager * MBean in the given {@link MBeanServerConnection}. * @param mbs The MBeanServer in which the new singleton instance * should be created. * @throws JMException The MBeanServer connection raised an exception * while trying to instantiate and register the singleton MBean * instance. * @throws IOException There was a connection problem while trying to * communicate with the underlying MBeanServer. * @return A proxy for the registered MBean. **/ public static ScanManagerMXBean register(MBeanServerConnection mbs) throws IOException, JMException { final ObjectInstance moi = mbs.createMBean(ScanManager.class.getName(),SCAN_MANAGER_NAME); final ScanManagerMXBean proxy = JMX.newMXBeanProxy(mbs,moi.getObjectName(), ScanManagerMXBean.class,true); return proxy; } /** * Creates a new {@code ScanManagerMXBean} proxy over the given * {@code MBeanServerConnection}. Does not check whether a * {@code ScanManagerMXBean} * is actually registered in that {@code MBeanServerConnection}. * @return a new {@code ScanManagerMXBean} proxy. * @param mbs The {@code MBeanServerConnection} which holds the * {@code ScanManagerMXBean} to proxy. */ public static ScanManagerMXBean newSingletonProxy(MBeanServerConnection mbs) { final ScanManagerMXBean proxy = JMX.newMXBeanProxy(mbs,SCAN_MANAGER_NAME, ScanManagerMXBean.class,true); return proxy; } /** * Creates a new {@code ScanManagerMXBean} proxy over the platform * {@code MBeanServer}. This is equivalent to * {@code newSingletonProxy(ManagementFactory.getPlatformMBeanServer())}. * @return a new {@code ScanManagerMXBean} proxy. **/ public static ScanManagerMXBean newSingletonProxy() { return newSingletonProxy(ManagementFactory.getPlatformMBeanServer()); } /** * Create and register a new singleton instance of the ScanManager * MBean in the given {@link MBeanServerConnection}. * @throws JMException The MBeanServer connection raised an exception * while trying to instantiate and register the singleton MBean * instance. * @throws IOException There was a connection problem while trying to * communicate with the underlying MBeanServer. * @return A proxy for the registered MBean. **/ public static ScanManagerMXBean register() throws IOException, JMException { final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); return register(mbs); } /** * Create a new ScanManager MBean **/ public ScanManager() { broadcaster = new NotificationBroadcasterSupport(); pendingNotifs = new LinkedBlockingQueue<Notification>(100); scanmap = newConcurrentHashMap(); configmap = newConcurrentHashMap(); log = new ResultLogManager(); } // Creates a new DirectoryScannerMXBean, from the given configuration data. DirectoryScannerMXBean createDirectoryScanner(DirectoryScannerConfig config) { return new DirectoryScanner(config,log); } // Applies a configuration. // throws IllegalStateException if lock can't be acquired. // Unregisters all existing directory scanners, the create and registers // new directory scanners according to the given config. // Then pushes the log config to the result log manager. // private void applyConfiguration(ScanManagerConfig bean) throws IOException, JMException { if (bean == null) return; if (!sequencer.tryAcquire()) { throw new IllegalStateException("Can't acquire lock"); } try { unregisterScanners(); final DirectoryScannerConfig[] scans = bean.getScanList(); if (scans == null) return; for (DirectoryScannerConfig scan : scans) { addDirectoryScanner(scan); } log.setConfig(bean.getInitialResultLogConfig()); } finally { sequencer.release(); } } // See ScanManagerMXBean public void applyConfiguration(boolean fromMemory) throws IOException, JMException { if (fromMemory == false) config.load(); applyConfiguration(config.getConfiguration()); } // See ScanManagerMXBean public void applyCurrentResultLogConfig(boolean toMemory) throws IOException, JMException { final ScanManagerConfig bean = config.getConfiguration(); bean.setInitialResultLogConfig(log.getConfig()); config.setConfiguration(bean); if (toMemory==false) config.save(); } // See ScanManagerMXBean public void setConfigurationMBean(ScanDirConfigMXBean config) { this.config = config;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -