1 /*
   2  * Copyright (c) 2003, 2008, 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 4911721
  27  * @summary test on add/remove NotificationListener
  28  * @author Shanliang JIANG
  29  * @run clean DiffHBTest
  30  * @run build DiffHBTest
  31  * @run main DiffHBTest
  32  */
  33 
  34 
  35 import javax.management.*;
  36 import javax.management.remote.*;
  37 
  38 /**
  39  * This test registeres an unique listener with two different handbacks,
  40  * it expects to receive a same notification two times.
  41  */
  42 public class DiffHBTest {
  43     private static final String[] protocols = {"rmi", "iiop", "jmxmp"};
  44 
  45     private static final MBeanServer mbs = MBeanServerFactory.createMBeanServer();
  46     private static ObjectName delegateName;
  47     private static ObjectName timerName;
  48 
  49     public static final String[] hbs = new String[] {"0", "1"};
  50 
  51     public static void main(String[] args) throws Exception {
  52         System.out.println(">>> test on one listener with two different handbacks.");
  53 
  54         delegateName = new ObjectName("JMImplementation:type=MBeanServerDelegate");
  55         timerName = new ObjectName("MBean:name=Timer");
  56 
  57         String errors = "";
  58 
  59         for (int i = 0; i < protocols.length; i++) {
  60             final String s = test(protocols[i]);
  61             if (s != null) {
  62                 if ("".equals(errors)) {
  63                     errors = "Failed to " + protocols[i] + ": "+s;
  64                 } else {
  65                     errors = "\tFailed to " + protocols[i] + ": "+s;
  66                 }
  67             }
  68         }
  69 
  70         if ("".equals(errors)) {
  71             System.out.println(">>> Passed!");
  72         } else {
  73             System.out.println(">>> Failed!");
  74 
  75             throw new RuntimeException(errors);
  76         }
  77     }
  78 
  79     private static String test(String proto) throws Exception {
  80         System.out.println(">>> Test for protocol " + proto);
  81         JMXServiceURL u = new JMXServiceURL(proto, null, 0);
  82         JMXConnectorServer server;
  83         JMXConnector client;
  84 
  85         try {
  86             server =
  87                     JMXConnectorServerFactory.newJMXConnectorServer(u, null, mbs);
  88             server.start();
  89             JMXServiceURL addr = server.getAddress();
  90             client = JMXConnectorFactory.connect(addr, null);
  91         } catch (Exception e) {
  92             // not support
  93             System.out.println(">>> not support: " + proto);
  94             return null;
  95         }
  96 
  97         MBeanServerConnection mserver = client.getMBeanServerConnection();
  98 
  99         System.out.print(">>>\t");
 100         for (int i=0; i<5; i++) {
 101             System.out.print(i + "\t");
 102             final MyListener dummyListener = new MyListener();
 103             mserver.addNotificationListener(
 104                     delegateName, dummyListener, null, hbs[0]);
 105             mserver.addNotificationListener(
 106                     delegateName, dummyListener, null, hbs[1]);
 107 
 108             mserver.createMBean("javax.management.timer.Timer", timerName);
 109 
 110             long remainingTime = waitingTime;
 111             final long startTime = System.currentTimeMillis();
 112 
 113             try {
 114                 synchronized(dummyListener) {
 115                     while (!dummyListener.done && remainingTime > 0) {
 116                         dummyListener.wait(remainingTime);
 117                         remainingTime = waitingTime -
 118                                 (System.currentTimeMillis() - startTime);
 119                     }
 120 
 121                     if (dummyListener.errorInfo != null) {
 122                         return dummyListener.errorInfo;
 123                     }
 124                 }
 125             } finally {
 126                 //System.out.println("Unregister: "+i);
 127                 mserver.unregisterMBean(timerName);
 128                 mserver.removeNotificationListener(delegateName, dummyListener);
 129             }
 130         }
 131 
 132         System.out.println("");
 133         client.close();
 134         server.stop();
 135 
 136         return null;
 137     }
 138 
 139     private static class MyListener implements NotificationListener {
 140         public boolean done = false;
 141         public String errorInfo = null;
 142 
 143         private int received = 0;
 144         private MBeanServerNotification receivedNotif = null;
 145         private Object receivedHB = null;
 146         public void handleNotification(Notification n, Object o) {
 147             if (!(n instanceof MBeanServerNotification)) {
 148                 failed("Received an unexpected notification: "+n);
 149                 return;
 150             }
 151 
 152             if (!hbs[0].equals(o) && !hbs[1].equals(o)) {
 153                 failed("Unkown handback: "+o);
 154                 return;
 155             }
 156 
 157             // what we need
 158             final MBeanServerNotification msn = (MBeanServerNotification)n;
 159             if (!(MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(
 160                     msn.getType())) ||
 161                     !msn.getMBeanName().equals(timerName)) {
 162                 return;
 163             }
 164 
 165             synchronized(this) {
 166                 received++;
 167 
 168                 if (received == 1) { // first time
 169                     receivedNotif = msn;
 170                     receivedHB = o;
 171 
 172                     return;
 173                 }
 174 
 175                 if (received > 2) {
 176                     failed("Expect to receive 2 notifs,  but get "+received);
 177 
 178                     return;
 179                 }
 180 
 181                 // second time
 182                 if (receivedHB.equals(o)) {
 183                     failed("Got same handback twice: "+o);
 184                 } else if(!hbs[0].equals(o) && !hbs[1].equals(o)) {
 185                     failed("Unknown handback: "+o);
 186                 } else if (receivedNotif.getSequenceNumber() !=
 187                         msn.getSequenceNumber()) {
 188                     failed("expected to receive:\n"
 189                             +receivedNotif
 190                             +"\n but got\n"+msn);
 191                 }
 192 
 193                 // passed
 194                 done = true;
 195                 this.notify();
 196             }
 197         }
 198 
 199         private void failed(String errorInfo) {
 200             this.errorInfo = errorInfo;
 201             done = true;
 202 
 203             this.notify();
 204         }
 205     }
 206 
 207     private final static long waitingTime = 2000;
 208 }