1/*
2 * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 4757273
27 * @summary Test that registered notification is sent early enough
28 * @author Eamonn McManus
29 *
30 * @run clean NewMBeanListenerTest
31 * @run build NewMBeanListenerTest
32 * @run main NewMBeanListenerTest
33 */
34
35import javax.management.*;
36
37/* Tests that you can write a listener for MBean registrations, that
38 * registers another listener on every newly-registered MBean (that is
39 * a NotificationBroadcaster).  Provided the newly-registered MBean
40 * waits until its postRegister is called, no notifications will be lost.
41 */
42public class NewMBeanListenerTest {
43    public static void main(String[] args) throws Exception {
44        final MBeanServer mbs = MBeanServerFactory.createMBeanServer();
45        final ObjectName delegateName =
46            new ObjectName("JMImplementation:type=MBeanServerDelegate");
47        final CountListener countListener = new CountListener();
48        final NotificationListener addListener = new NotificationListener() {
49            public void handleNotification(Notification n, Object h) {
50                if (!(n instanceof MBeanServerNotification)) {
51                    System.out.println("Ignoring delegate notif: " +
52                                       n.getClass().getName());
53                    return;
54                }
55                MBeanServerNotification mbsn = (MBeanServerNotification) n;
56                if (!(mbsn.getType()
57                      .equals(MBeanServerNotification
58                              .REGISTRATION_NOTIFICATION))) {
59                    System.out.println("Ignoring MBeanServer notif: " +
60                                       mbsn.getType());
61                    return;
62                }
63                System.out.println("Got registration notif for " +
64                                   mbsn.getMBeanName());
65                try {
66                    mbs.addNotificationListener(mbsn.getMBeanName(),
67                                                countListener, null, null);
68                } catch (Exception e) {
69                    System.out.println("TEST INCORRECT: addNL failed:");
70                    e.printStackTrace(System.out);
71                    System.exit(1);
72                }
73                System.out.println("Added notif listener for " +
74                                   mbsn.getMBeanName());
75            }
76        };
77        System.out.println("Adding registration listener");
78        mbs.addNotificationListener(delegateName, addListener, null, null);
79        final ObjectName broadcasterName = new ObjectName(":type=Broadcaster");
80        System.out.println("Creating Broadcaster MBean");
81        mbs.createMBean(Broadcaster.class.getName(), broadcasterName);
82        if (countListener.getCount() == 1)
83            System.out.println("Got notif as expected");
84        else {
85            System.out.println("TEST FAILED: added listener not called");
86            System.exit(1);
87        }
88        mbs.unregisterMBean(broadcasterName);
89        Broadcaster b = new Broadcaster();
90        System.out.println("Registering Broadcaster MBean");
91        mbs.registerMBean(b, broadcasterName);
92        if (countListener.getCount() == 2)
93            System.out.println("Got notif as expected");
94        else {
95            System.out.println("TEST FAILED: added listener not called");
96            System.exit(1);
97        }
98        System.out.println("Test passed");
99    }
100
101    public static interface BroadcasterMBean {}
102
103    public static class Broadcaster
104            extends NotificationBroadcasterSupport
105            implements BroadcasterMBean, MBeanRegistration {
106
107        public ObjectName preRegister(MBeanServer mbs, ObjectName name) {
108            return name;
109        }
110
111        public void postRegister(Boolean registrationDone) {
112            System.out.println("Broadcaster.postRegister: sending notif");
113            sendNotification(new Notification("x", this, 0L));
114        }
115
116        public void preDeregister() {
117        }
118
119        public void postDeregister() {
120        }
121    }
122
123    private static class CountListener implements NotificationListener {
124        private int count;
125
126        public synchronized void handleNotification(Notification n, Object h) {
127            if (!n.getType().equals("x")) {
128                System.out.println("TEST FAILED: received bogus notif: " + n +
129                                   " (type=" + n.getType() + ")");
130                System.exit(1);
131            }
132            count++;
133        }
134
135        public synchronized int getCount() {
136            return count;
137        }
138    }
139}
140