jdk/src/share/classes/javax/management/event/EventClientDelegate.java
author dfuchs
Thu, 04 Sep 2008 14:46:36 +0200
changeset 1156 bbc2d15aaf7a
parent 1004 5ba8217eb504
child 1247 b4c26443dee5
permissions -rw-r--r--
5072476: RFE: support cascaded (federated) MBean Servers 6299231: Add support for named MBean Servers Summary: New javax.management.namespace package. Reviewed-by: emcmanus
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1004
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
     1
/*
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
     2
 * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
     4
 *
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    10
 *
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    15
 * accompanied this code).
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    16
 *
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    20
 *
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    23
 * have any questions.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    24
 *
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    25
 * @since JMX 2.0
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    26
 */
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    27
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    28
package javax.management.event;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    29
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    30
import java.io.IOException;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    31
import java.lang.reflect.Method;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    32
import java.util.HashMap;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    33
import java.util.Collection;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    34
import java.util.Collections;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    35
import java.util.UUID;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    36
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    37
import javax.management.InstanceNotFoundException;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    38
import javax.management.ListenerNotFoundException;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    39
import javax.management.Notification;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    40
import javax.management.NotificationFilter;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    41
import javax.management.NotificationListener;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    42
import javax.management.ObjectName;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    43
import javax.management.remote.NotificationResult;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    44
import com.sun.jmx.event.EventBuffer;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    45
import com.sun.jmx.event.LeaseManager;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    46
import com.sun.jmx.interceptor.SingleMBeanForwarder;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    47
import com.sun.jmx.mbeanserver.Util;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    48
import com.sun.jmx.remote.util.ClassLogger;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    49
import java.lang.ref.WeakReference;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    50
import java.lang.reflect.Constructor;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    51
import java.lang.reflect.InvocationHandler;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    52
import java.lang.reflect.Proxy;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    53
import java.security.AccessControlContext;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    54
import java.security.AccessController;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    55
import java.security.PrivilegedAction;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    56
import java.security.PrivilegedExceptionAction;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    57
import java.util.Arrays;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    58
import java.util.Map;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    59
import java.util.Set;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    60
import java.util.WeakHashMap;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    61
import java.util.concurrent.ConcurrentHashMap;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    62
import java.util.concurrent.atomic.AtomicInteger;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    63
import javax.management.DynamicMBean;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    64
import javax.management.MBeanException;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    65
import javax.management.MBeanPermission;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    66
import javax.management.MBeanServer;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    67
import javax.management.MBeanServerConnection;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    68
import javax.management.MBeanServerDelegate;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    69
import javax.management.MBeanServerInvocationHandler;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    70
import javax.management.MBeanServerNotification;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    71
import javax.management.ObjectInstance;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    72
import javax.management.StandardMBean;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    73
import javax.management.remote.MBeanServerForwarder;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    74
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    75
/**
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    76
 * This is the default implementation of the MBean
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    77
 * {@link EventClientDelegateMBean}.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    78
 */
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    79
public class EventClientDelegate implements EventClientDelegateMBean {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    80
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    81
    private EventClientDelegate(MBeanServer server) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    82
        if (server == null) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    83
            throw new NullPointerException("Null MBeanServer.");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    84
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    85
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    86
        if (logger.traceOn()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    87
            logger.trace("EventClientDelegate", "new one");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    88
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    89
        mbeanServer = server;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    90
        eventSubscriber = EventSubscriber.getEventSubscriber(mbeanServer);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    91
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    92
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    93
    /**
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    94
     * Returns an {@code EventClientDelegate} instance for the given
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    95
     * {@code MBeanServer}.  Calling this method more than once with the same
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    96
     * {@code server} argument may return the same object or a different object
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    97
     * each time.  See {@link EventClientDelegateMBean} for an example use of
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    98
     * this method.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
    99
     *
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   100
     * @param server An MBean server instance to work with.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   101
     * @return An {@code EventClientDelegate} instance.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   102
     * @throws NullPointerException If {@code server} is null.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   103
     */
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   104
    public static EventClientDelegate getEventClientDelegate(MBeanServer server) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   105
        EventClientDelegate delegate = null;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   106
        synchronized(delegateMap) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   107
            final WeakReference wrf = delegateMap.get(server);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   108
            delegate = (wrf == null) ? null : (EventClientDelegate)wrf.get();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   109
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   110
            if (delegate == null) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   111
                delegate = new EventClientDelegate(server);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   112
                try {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   113
                    // TODO: this may not work with federated MBean, because
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   114
                    // the delegate will *not* emit notifications for those MBeans.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   115
                    delegate.mbeanServer.addNotificationListener(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   116
                            MBeanServerDelegate.DELEGATE_NAME,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   117
                            delegate.cleanListener, null, null);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   118
                } catch (InstanceNotFoundException e) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   119
                    logger.fine(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   120
                            "getEventClientDelegate",
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   121
                            "Could not add MBeanServerDelegate listener", e);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   122
                }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   123
                delegateMap.put(server,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   124
                                new WeakReference<EventClientDelegate>(delegate));
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   125
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   126
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   127
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   128
        return delegate;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   129
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   130
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   131
    // Logic for the MBeanServerForwarder that simulates the existence of the
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   132
    // EventClientDelegate MBean. Things are complicated by the fact that
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   133
    // there may not be anything in the chain after this forwarder when it is
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   134
    // created - the connection to a real MBeanServer might only come later.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   135
    // Recall that there are two ways of creating a JMXConnectorServer -
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   136
    // either you specify its MBeanServer when you create it, or you specify
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   137
    // no MBeanServer and register it in an MBeanServer later. In the latter
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   138
    // case, the forwarder chain points nowhere until this registration
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   139
    // happens. Since EventClientDelegate wants to add a listener to the
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   140
    // MBeanServerDelegate, we can't create an EventClientDelegate until
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   141
    // there is an MBeanServer. So the forwarder initially has
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   142
    // a dummy ECD where every method throws an exception, and
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   143
    // the real ECD is created as soon as doing so does not produce an
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   144
    // exception.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   145
    // TODO: rewrite so that the switch from the dummy to the real ECD happens
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   146
    // just before we would otherwise have thrown UnsupportedOperationException.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   147
    // This is more correct, because it's not guaranteed that we will see the
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   148
    // moment where the real MBeanServer is attached, if it happens by virtue
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   149
    // of a setMBeanServer on some other forwarder later in the chain.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   150
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   151
    private static class Forwarder extends SingleMBeanForwarder {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   152
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   153
        private static class UnsupportedInvocationHandler
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   154
                implements InvocationHandler {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   155
            public Object invoke(Object proxy, Method method, Object[] args)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   156
                    throws Throwable {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   157
                throw new UnsupportedOperationException(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   158
                        "EventClientDelegate unavailable: no MBeanServer, or " +
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   159
                        "MBeanServer inaccessible");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   160
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   161
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   162
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   163
        private static DynamicMBean makeUnsupportedECD() {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   164
            EventClientDelegateMBean unsupported = (EventClientDelegateMBean)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   165
                Proxy.newProxyInstance(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   166
                    EventClientDelegateMBean.class.getClassLoader(),
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   167
                    new Class<?>[] {EventClientDelegateMBean.class},
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   168
                    new UnsupportedInvocationHandler());
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   169
            return new StandardMBean(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   170
                unsupported, EventClientDelegateMBean.class, false);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   171
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   172
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   173
        private volatile boolean madeECD;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   174
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   175
        Forwarder() {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   176
            super(OBJECT_NAME, makeUnsupportedECD());
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   177
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   178
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   179
        @Override
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   180
        public synchronized void setMBeanServer(final MBeanServer mbs) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   181
            super.setMBeanServer(mbs);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   182
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   183
            if (!madeECD) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   184
                try {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   185
                    EventClientDelegate ecd =
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   186
                        AccessController.doPrivileged(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   187
                            new PrivilegedAction<EventClientDelegate>() {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   188
                                public EventClientDelegate run() {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   189
                                    return getEventClientDelegate(Forwarder.this);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   190
                                }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   191
                            });
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   192
                    DynamicMBean mbean = new StandardMBean(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   193
                            ecd, EventClientDelegateMBean.class, false);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   194
                    setSingleMBean(mbean);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   195
                    madeECD = true;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   196
                } catch (Exception e) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   197
                    // OK: assume no MBeanServer
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   198
                    logger.fine("setMBeanServer", "isRegistered", e);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   199
                }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   200
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   201
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   202
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   203
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   204
    /**
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   205
     * <p>Create a new {@link MBeanServerForwarder} that simulates the existence
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   206
     * of an {@code EventClientDelegateMBean} with the {@linkplain
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   207
     * #OBJECT_NAME default name}.  This forwarder intercepts MBean requests
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   208
     * that are targeted for that MBean and handles them itself.  All other
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   209
     * requests are forwarded to the next element in the forwarder chain.</p>
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   210
     *
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   211
     * @return a new {@code MBeanServerForwarder} that simulates the existence
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   212
     * of an {@code EventClientDelegateMBean}.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   213
     */
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   214
    public static MBeanServerForwarder newForwarder() {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   215
        return new Forwarder();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   216
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   217
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   218
    /**
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   219
     * Returns a proxy of the default {@code EventClientDelegateMBean}.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   220
     *
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   221
     * @param conn An {@link MBeanServerConnection} to work with.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   222
     */
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   223
    @SuppressWarnings("cast") // cast for jdk 1.5
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   224
    public static EventClientDelegateMBean getProxy(MBeanServerConnection conn) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   225
        return  (EventClientDelegateMBean)MBeanServerInvocationHandler.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   226
                newProxyInstance(conn,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   227
                OBJECT_NAME,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   228
                EventClientDelegateMBean.class,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   229
                false);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   230
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   231
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   232
    public String addClient(String className, Object[] params, String[] sig)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   233
    throws MBeanException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   234
        return addClient(className, null, params, sig, true);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   235
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   236
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   237
    public String addClient(String className,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   238
            ObjectName classLoader,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   239
            Object[] params,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   240
            String[] sig) throws MBeanException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   241
        return addClient(className, classLoader, params, sig, false);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   242
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   243
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   244
    private String addClient(String className,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   245
            ObjectName classLoader,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   246
            Object[] params,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   247
            String[] sig,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   248
            boolean classLoaderRepository) throws MBeanException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   249
        try {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   250
            return addClientX(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   251
                    className, classLoader, params, sig, classLoaderRepository);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   252
        } catch (RuntimeException e) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   253
            throw e;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   254
        } catch (Exception e) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   255
            throw new MBeanException(e);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   256
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   257
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   258
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   259
    private String addClientX(String className,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   260
            ObjectName classLoader,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   261
            Object[] params,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   262
            String[] sig,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   263
            boolean classLoaderRepository) throws Exception {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   264
        if (className == null) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   265
            throw new IllegalArgumentException("Null class name.");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   266
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   267
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   268
        final Object o;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   269
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   270
        // The special treatment of standard EventForwarders is so that no
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   271
        // special permissions are necessary to use them.  Otherwise you
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   272
        // couldn't use EventClient if you didn't have permission to call
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   273
        // MBeanServer.instantiate.  We do require that permission for
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   274
        // non-standard forwarders, because otherwise you could instantiate
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   275
        // any class with possibly adverse consequences.  We also avoid using
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   276
        // MBeanInstantiator because it looks up constructors by loading each
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   277
        // class in the sig array, which means a remote user could cause any
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   278
        // class to be loaded.  That's probably not hugely risky but still.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   279
        if (className.startsWith("javax.management.event.")) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   280
            Class<?> c = Class.forName(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   281
                    className, false, this.getClass().getClassLoader());
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   282
            Constructor<?> foundCons = null;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   283
            if (sig == null)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   284
                sig = new String[0];
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   285
            for (Constructor cons : c.getConstructors()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   286
                Class<?>[] types = cons.getParameterTypes();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   287
                String[] consSig = new String[types.length];
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   288
                for (int i = 0; i < types.length; i++)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   289
                    consSig[i] = types[i].getName();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   290
                if (Arrays.equals(sig, consSig)) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   291
                    foundCons = cons;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   292
                    break;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   293
                }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   294
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   295
            if (foundCons == null) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   296
                throw new NoSuchMethodException(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   297
                        "Constructor for " + className + " with argument types " +
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   298
                        Arrays.toString(sig));
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   299
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   300
            o = foundCons.newInstance(params);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   301
        } else if (classLoaderRepository) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   302
            o = mbeanServer.instantiate(className, params, sig);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   303
        } else {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   304
            o = mbeanServer.instantiate(className, classLoader, params, sig);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   305
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   306
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   307
        if (!(o instanceof EventForwarder)) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   308
            throw new IllegalArgumentException(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   309
                    className+" is not an EventForwarder class.");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   310
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   311
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   312
        final EventForwarder forwarder = (EventForwarder)o;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   313
        final String clientId = UUID.randomUUID().toString();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   314
        ClientInfo clientInfo = new ClientInfo(clientId, forwarder);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   315
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   316
        clientInfoMap.put(clientId, clientInfo);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   317
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   318
        forwarder.setClientId(clientId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   319
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   320
        if (logger.traceOn()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   321
            logger.trace("addClient", clientId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   322
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   323
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   324
        return clientId;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   325
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   326
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   327
    public Integer[] getListenerIds(String clientId)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   328
    throws IOException, EventClientNotFoundException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   329
        ClientInfo clientInfo = getClientInfo(clientId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   330
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   331
        if (clientInfo == null) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   332
            throw new EventClientNotFoundException("The client is not found.");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   333
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   334
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   335
        Map<Integer, AddedListener> listenerInfoMap = clientInfo.listenerInfoMap;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   336
        synchronized (listenerInfoMap) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   337
            Set<Integer> ids = listenerInfoMap.keySet();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   338
            return ids.toArray(new Integer[ids.size()]);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   339
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   340
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   341
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   342
    /**
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   343
     * {@inheritDoc}
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   344
     *
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   345
     * <p>The execution of this method includes a call to
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   346
     * {@link MBeanServer#addNotificationListener(ObjectName,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   347
     * NotificationListener, NotificationFilter, Object)}.</p>
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   348
     */
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   349
    public Integer addListener(String clientId,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   350
            final ObjectName name,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   351
            NotificationFilter filter)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   352
            throws EventClientNotFoundException, InstanceNotFoundException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   353
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   354
        if (logger.traceOn()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   355
            logger.trace("addListener", "");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   356
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   357
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   358
        return getClientInfo(clientId).addListenerInfo(name, filter);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   359
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   360
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   361
    /**
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   362
     * {@inheritDoc}
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   363
     *
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   364
     * <p>The execution of this method can include call to
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   365
     * {@link MBeanServer#removeNotificationListener(ObjectName,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   366
     * NotificationListener, NotificationFilter, Object)}.</p>
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   367
     */
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   368
    public void removeListenerOrSubscriber(String clientId, Integer listenerId)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   369
    throws InstanceNotFoundException,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   370
            ListenerNotFoundException,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   371
            EventClientNotFoundException,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   372
            IOException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   373
        if (logger.traceOn()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   374
            logger.trace("removeListener", ""+listenerId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   375
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   376
        getClientInfo(clientId).removeListenerInfo(listenerId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   377
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   378
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   379
    /**
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   380
     * {@inheritDoc}
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   381
     *
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   382
     * <p>The execution of this method includes a call to
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   383
     * {@link MBeanServer#addNotificationListener(ObjectName,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   384
     * NotificationListener, NotificationFilter, Object)} for
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   385
     * every MBean matching {@code name}.  If {@code name} is
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   386
     * an {@code ObjectName} pattern, then the execution of this
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   387
     * method will include a call to {@link MBeanServer#queryNames}.</p>
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   388
     */
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   389
    public Integer addSubscriber(String clientId, ObjectName name,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   390
            NotificationFilter filter)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   391
            throws EventClientNotFoundException, IOException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   392
        if (logger.traceOn()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   393
            logger.trace("addSubscriber", "");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   394
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   395
        return getClientInfo(clientId).subscribeListenerInfo(name, filter);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   396
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   397
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   398
    public NotificationResult fetchNotifications(String clientId,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   399
            long startSequenceNumber,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   400
            int maxNotifs,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   401
            long timeout)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   402
            throws EventClientNotFoundException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   403
        if (logger.traceOn()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   404
            logger.trace("fetchNotifications", "for "+clientId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   405
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   406
        return getClientInfo(clientId).fetchNotifications(startSequenceNumber,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   407
                maxNotifs,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   408
                timeout);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   409
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   410
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   411
    public void removeClient(String clientId)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   412
    throws EventClientNotFoundException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   413
        if (clientId == null)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   414
            throw new EventClientNotFoundException("Null clientId");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   415
        if (logger.traceOn()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   416
            logger.trace("removeClient", clientId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   417
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   418
        ClientInfo ci = null;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   419
        ci = clientInfoMap.remove(clientId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   420
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   421
        if (ci == null) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   422
            throw new EventClientNotFoundException("clientId is "+clientId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   423
        } else {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   424
            ci.clean();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   425
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   426
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   427
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   428
    public long lease(String clientId, long timeout)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   429
    throws IOException, EventClientNotFoundException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   430
        if (logger.traceOn()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   431
            logger.trace("lease", "for "+clientId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   432
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   433
        return getClientInfo(clientId).lease(timeout);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   434
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   435
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   436
    // ------------------------------------
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   437
    // private classes
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   438
    // ------------------------------------
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   439
    private class ClientInfo {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   440
        String clientId;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   441
        EventBuffer buffer;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   442
        NotificationListener clientListener;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   443
        Map<Integer, AddedListener> listenerInfoMap =
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   444
                new HashMap<Integer, AddedListener>();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   445
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   446
        ClientInfo(String clientId, EventForwarder forwarder) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   447
            this.clientId = clientId;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   448
            this.forwarder = forwarder;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   449
            clientListener =
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   450
                    new ForwardingClientListener(listenerInfoMap, forwarder);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   451
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   452
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   453
        Integer addOrSubscribeListenerInfo(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   454
                ObjectName name, NotificationFilter filter, boolean subscribe)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   455
                throws InstanceNotFoundException, IOException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   456
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   457
            final Integer listenerId = nextListenerId();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   458
            AddedListener listenerInfo = new AddedListener(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   459
                    listenerId, filter, name, subscribe);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   460
            if (subscribe) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   461
                eventSubscriber.subscribe(name,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   462
                        clientListener,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   463
                        filter,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   464
                        listenerInfo);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   465
            } else {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   466
                mbeanServer.addNotificationListener(name,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   467
                        clientListener,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   468
                        filter,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   469
                        listenerInfo);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   470
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   471
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   472
            synchronized(listenerInfoMap) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   473
                listenerInfoMap.put(listenerId, listenerInfo);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   474
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   475
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   476
            return listenerId;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   477
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   478
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   479
        Integer addListenerInfo(ObjectName name,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   480
                NotificationFilter filter) throws InstanceNotFoundException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   481
            try {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   482
                return addOrSubscribeListenerInfo(name, filter, false);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   483
            } catch (IOException e) { // can't happen
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   484
                logger.warning(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   485
                        "EventClientDelegate.addListenerInfo",
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   486
                        "unexpected exception", e);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   487
                throw new RuntimeException(e);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   488
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   489
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   490
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   491
        Integer subscribeListenerInfo(ObjectName name,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   492
                NotificationFilter filter) throws IOException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   493
            try {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   494
                return addOrSubscribeListenerInfo(name, filter, true);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   495
            } catch (InstanceNotFoundException e) { // can't happen
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   496
                logger.warning(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   497
                        "EventClientDelegate.subscribeListenerInfo",
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   498
                        "unexpected exception", e);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   499
                throw new RuntimeException(e);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   500
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   501
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   502
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   503
        private final AtomicInteger nextListenerId = new AtomicInteger();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   504
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   505
        private Integer nextListenerId() {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   506
            return nextListenerId.getAndIncrement();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   507
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   508
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   509
        NotificationResult fetchNotifications(long startSequenceNumber,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   510
                int maxNotifs,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   511
                long timeout) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   512
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   513
            if (!(forwarder instanceof FetchingEventForwarder)) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   514
                throw new IllegalArgumentException(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   515
                        "This client is using Event Postal Service!");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   516
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   517
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   518
            return ((FetchingEventForwarder)forwarder).
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   519
                    fetchNotifications(startSequenceNumber,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   520
                        maxNotifs, timeout);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   521
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   522
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   523
        void removeListenerInfo(Integer listenerId)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   524
        throws InstanceNotFoundException, ListenerNotFoundException, IOException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   525
            AddedListener listenerInfo;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   526
            synchronized(listenerInfoMap) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   527
                listenerInfo = listenerInfoMap.remove(listenerId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   528
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   529
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   530
            if (listenerInfo == null) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   531
                throw new ListenerNotFoundException("The listener is not found.");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   532
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   533
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   534
            if (listenerInfo.subscription) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   535
                eventSubscriber.unsubscribe(listenerInfo.name,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   536
                        clientListener);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   537
            } else {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   538
                mbeanServer.removeNotificationListener(listenerInfo.name,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   539
                        clientListener,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   540
                        listenerInfo.filter,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   541
                        listenerInfo);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   542
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   543
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   544
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   545
        void clean(ObjectName name) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   546
            synchronized(listenerInfoMap) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   547
                for (Map.Entry<Integer, AddedListener> entry :
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   548
                        listenerInfoMap.entrySet()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   549
                    AddedListener li = entry.getValue();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   550
                    if (name.equals(li.name)) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   551
                        listenerInfoMap.remove(entry.getKey());
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   552
                    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   553
                }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   554
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   555
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   556
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   557
        void clean() {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   558
            synchronized(listenerInfoMap) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   559
                for (AddedListener li : listenerInfoMap.values()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   560
                    try {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   561
                        mbeanServer.removeNotificationListener(li.name,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   562
                                clientListener);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   563
                    } catch (Exception e) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   564
                        logger.trace("ClientInfo.clean", "removeNL", e);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   565
                    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   566
                }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   567
                listenerInfoMap.clear();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   568
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   569
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   570
            try {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   571
                forwarder.close();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   572
            } catch (Exception e) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   573
                logger.trace(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   574
                        "ClientInfo.clean", "forwarder.close", e);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   575
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   576
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   577
            if (leaseManager != null) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   578
                leaseManager.stop();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   579
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   580
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   581
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   582
        long lease(long timeout) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   583
            return leaseManager.lease(timeout);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   584
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   585
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   586
        @Override
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   587
        public boolean equals(Object o) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   588
            if (this == o) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   589
                return true;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   590
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   591
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   592
            if (o instanceof ClientInfo &&
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   593
                    clientId.equals(((ClientInfo)o).clientId)) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   594
                return true;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   595
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   596
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   597
            return false;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   598
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   599
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   600
        @Override
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   601
        public int hashCode() {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   602
            return clientId.hashCode();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   603
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   604
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   605
        private EventForwarder forwarder = null;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   606
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   607
        private final Runnable leaseExpiryCallback = new Runnable() {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   608
            public void run() {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   609
                try {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   610
                    removeClient(clientId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   611
                } catch (Exception e) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   612
                    logger.trace(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   613
                            "ClientInfo.leaseExpiryCallback", "removeClient", e);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   614
                }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   615
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   616
        };
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   617
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   618
        private LeaseManager leaseManager = new LeaseManager(leaseExpiryCallback);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   619
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   620
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   621
    private class ForwardingClientListener implements NotificationListener {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   622
        public ForwardingClientListener(Map<Integer, AddedListener> listenerInfoMap,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   623
                EventForwarder forwarder) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   624
            this.listenerInfoMap = listenerInfoMap;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   625
            this.forwarder = forwarder;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   626
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   627
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   628
        public void handleNotification(Notification n, Object o) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   629
            if (n == null || (!(o instanceof AddedListener))) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   630
                if (logger.traceOn()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   631
                    logger.trace("ForwardingClientListener-handleNotification",
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   632
                            "received a unknown notif");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   633
                }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   634
                return;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   635
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   636
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   637
            AddedListener li = (AddedListener) o;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   638
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   639
            if (checkListenerPermission(li.name,li.acc)) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   640
                try {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   641
                    forwarder.forward(n, li.listenerId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   642
                } catch (Exception e) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   643
                    if (logger.traceOn()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   644
                        logger.trace(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   645
                                "ForwardingClientListener-handleNotification",
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   646
                                "forwarding failed.", e);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   647
                    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   648
                }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   649
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   650
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   651
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   652
        private final Map<Integer, AddedListener> listenerInfoMap;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   653
        private final EventForwarder forwarder;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   654
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   655
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   656
    private class AddedListener {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   657
        final int listenerId;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   658
        final NotificationFilter filter;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   659
        final ObjectName name;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   660
        final boolean subscription;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   661
        final AccessControlContext acc;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   662
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   663
        public AddedListener(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   664
                int listenerId,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   665
                NotificationFilter filter,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   666
                ObjectName name,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   667
                boolean subscription) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   668
            this.listenerId = listenerId;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   669
            this.filter = filter;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   670
            this.name = name;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   671
            this.subscription = subscription;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   672
            acc = AccessController.getContext();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   673
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   674
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   675
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   676
    private class CleanListener implements NotificationListener {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   677
        public void handleNotification(Notification notification,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   678
                Object handback) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   679
            if (notification instanceof MBeanServerNotification) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   680
                if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   681
                        notification.getType())) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   682
                    final ObjectName name =
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   683
                            ((MBeanServerNotification)notification).getMBeanName();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   684
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   685
                    final Collection <ClientInfo> list =
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   686
                            Collections.unmodifiableCollection(clientInfoMap.values());
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   687
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   688
                    for (ClientInfo ci : list) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   689
                        ci.clean(name);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   690
                    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   691
                }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   692
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   693
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   694
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   695
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   696
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   697
    // -------------------------------------------------
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   698
    // private method
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   699
    // -------------------------------------------------
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   700
    private ClientInfo getClientInfo(String clientId)
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   701
    throws EventClientNotFoundException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   702
        ClientInfo clientInfo = null;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   703
        clientInfo = clientInfoMap.get(clientId);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   704
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   705
        if (clientInfo == null) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   706
            throw new EventClientNotFoundException("The client is not found.");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   707
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   708
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   709
        return clientInfo;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   710
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   711
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   712
    /**
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   713
     * Explicitly check the MBeanPermission for
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   714
     * the current access control context.
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   715
     */
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   716
    private boolean checkListenerPermission(final ObjectName name,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   717
            final AccessControlContext acc) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   718
        if (logger.traceOn()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   719
            logger.trace("checkListenerPermission", "");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   720
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   721
        SecurityManager sm = System.getSecurityManager();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   722
        if (sm != null) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   723
            try {
1156
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   724
                final String serverName = getMBeanServerName();
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   725
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   726
                ObjectInstance oi = (ObjectInstance)
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   727
                    AccessController.doPrivileged(
1004
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   728
                        new PrivilegedExceptionAction<Object>() {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   729
                    public Object run()
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   730
                    throws InstanceNotFoundException {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   731
                        return mbeanServer.getObjectInstance(name);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   732
                    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   733
                });
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   734
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   735
                String classname = oi.getClassName();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   736
                MBeanPermission perm = new MBeanPermission(
1156
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   737
                        serverName,
1004
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   738
                        classname,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   739
                        null,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   740
                        name,
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   741
                        "addNotificationListener");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   742
                sm.checkPermission(perm, acc);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   743
            } catch (Exception e) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   744
                if (logger.debugOn()) {
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   745
                    logger.debug("checkListenerPermission", "refused.", e);
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   746
                }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   747
                return false;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   748
            }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   749
        }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   750
        return true;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   751
    }
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   752
1156
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   753
    private String getMBeanServerName() {
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   754
        if (mbeanServerName != null) return mbeanServerName;
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   755
        else return (mbeanServerName = getMBeanServerName(mbeanServer));
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   756
    }
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   757
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   758
    private static String getMBeanServerName(final MBeanServer server) {
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   759
        final PrivilegedAction<String> action = new PrivilegedAction<String>() {
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   760
            public String run() {
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   761
                return Util.getMBeanServerSecurityName(server);
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   762
            }
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   763
        };
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   764
        return AccessController.doPrivileged(action);
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   765
    }
bbc2d15aaf7a 5072476: RFE: support cascaded (federated) MBean Servers
dfuchs
parents: 1004
diff changeset
   766
1004
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   767
    // ------------------------------------
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   768
    // private variables
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   769
    // ------------------------------------
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   770
    private final MBeanServer mbeanServer;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   771
    private volatile String mbeanServerName = null;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   772
    private Map<String, ClientInfo> clientInfoMap =
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   773
            new ConcurrentHashMap<String, ClientInfo>();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   774
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   775
    private final CleanListener cleanListener = new CleanListener();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   776
    private final EventSubscriber eventSubscriber;
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   777
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   778
    private static final ClassLogger logger =
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   779
            new ClassLogger("javax.management.event", "EventClientDelegate");
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   780
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   781
    private static final
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   782
            Map<MBeanServer, WeakReference<EventClientDelegate>> delegateMap =
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   783
            new WeakHashMap<MBeanServer, WeakReference<EventClientDelegate>>();
5ba8217eb504 5108776: Add reliable event handling to the JMX API
sjiang
parents:
diff changeset
   784
}