1 /*
   2  * Copyright (c) 2003, 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 7654321
  27  * @summary Tests to receive notifications for opened and closed connections
  28 ions
  29  * @author sjiang
  30  * @modules java.management
  31  * @run clean RMINotifTest
  32  * @run build RMINotifTest
  33  * @run main RMINotifTest
  34  * @run main RMINotifTest event
  35  */
  36 
  37 // java imports
  38 //
  39 
  40 import java.rmi.RemoteException;
  41 import java.rmi.registry.LocateRegistry;
  42 import java.rmi.registry.Registry;
  43 import java.util.Random;
  44 import javax.management.MBeanNotificationInfo;
  45 import javax.management.MBeanServer;
  46 import javax.management.MBeanServerConnection;
  47 import javax.management.MBeanServerFactory;
  48 import javax.management.Notification;
  49 import javax.management.NotificationBroadcasterSupport;
  50 import javax.management.NotificationFilterSupport;
  51 import javax.management.NotificationListener;
  52 import javax.management.ObjectInstance;
  53 import javax.management.ObjectName;
  54 import javax.management.remote.JMXConnector;
  55 import javax.management.remote.JMXConnectorFactory;
  56 import javax.management.remote.JMXConnectorServer;
  57 import javax.management.remote.JMXConnectorServerFactory;
  58 import javax.management.remote.JMXServiceURL;
  59 
  60 public class RMINotifTest {
  61 
  62     public static void main(String[] args) {
  63         try {
  64             // create a rmi registry
  65             Registry reg = null;
  66             int port = 6666;
  67             final Random r = new Random();
  68 
  69             while(port++<7000) {
  70                 try {
  71                     reg = LocateRegistry.createRegistry(++port);
  72                     System.out.println("Creation of rmi registry succeeded. Running on port " + port);
  73                     break;
  74                 } catch (RemoteException re) {
  75                 // no problem
  76                 }
  77             }
  78 
  79             if (reg == null) {
  80                 System.out.println("Failed to create a RMI registry, "+
  81                                    "the ports from 6666 to 6999 are all occupied.");
  82                 System.exit(1);
  83             }
  84 
  85             // create a MBeanServer
  86             MBeanServer server = MBeanServerFactory.createMBeanServer();
  87 
  88             // create a notif emitter mbean
  89             ObjectName mbean = new ObjectName ("Default:name=NotificationEmitter");
  90 
  91             server.registerMBean(new NotificationEmitter(), mbean);
  92 
  93             // create a rmi server
  94             JMXServiceURL url =
  95                 new JMXServiceURL("rmi", null, port,
  96                                   "/jndi/rmi://:" + port + "/server" + port);
  97             System.out.println("RMIConnectorServer address " + url);
  98 
  99             JMXConnectorServer sServer =
 100                 JMXConnectorServerFactory.newJMXConnectorServer(url, null,
 101                                                                 null);
 102 
 103             ObjectInstance ss = server.registerMBean(sServer, new ObjectName("Default:name=RmiConnectorServer"));
 104 
 105             sServer.start();
 106 
 107             // create a rmi client
 108             JMXConnector rmiConnection =
 109                 JMXConnectorFactory.newJMXConnector(url, null);
 110             rmiConnection.connect(null);
 111             MBeanServerConnection client = rmiConnection.getMBeanServerConnection();
 112 
 113             // add listener at the client side
 114             client.addNotificationListener(mbean, listener, null, null);
 115 
 116             //ask to send notifs
 117             Object[] params = new Object[1];
 118             String[] signatures = new String[1];
 119 
 120             params[0] = new Integer(nb);
 121             signatures[0] = "java.lang.Integer";
 122 
 123             client.invoke(mbean, "sendNotifications", params, signatures);
 124 
 125             // waiting ...
 126             synchronized (lock) {
 127                 if (receivedNotifs != nb) {
 128                     lock.wait(10000);
 129                     System.out.println(">>> Received notifications..."+receivedNotifs);
 130 
 131                 }
 132             }
 133 
 134             // check
 135             if (receivedNotifs != nb) {
 136                 System.exit(1);
 137             } else {
 138                 System.out.println("The client received all notifications.");
 139             }
 140 
 141             // remove listener
 142             client.removeNotificationListener(mbean, listener);
 143 
 144             // more test
 145             NotificationFilterSupport filter = new NotificationFilterSupport();
 146             Object o = new Object();
 147             client.addNotificationListener(mbean, listener, filter, o);
 148             client.removeNotificationListener(mbean, listener, filter, o);
 149 
 150             sServer.stop();
 151 
 152 //          // clean
 153 //          client.unregisterMBean(mbean);
 154 //          rmiConnection.close();
 155 
 156 //          Thread.sleep(2000);
 157 
 158 
 159 
 160         } catch (Exception e) {
 161             e.printStackTrace();
 162             System.exit(1);
 163         }
 164     }
 165 
 166 //--------------------------
 167 // private classes
 168 //--------------------------
 169 
 170     private static class Listener implements NotificationListener {
 171         public void handleNotification(Notification notif, Object handback) {
 172             if(++receivedNotifs == nb) {
 173                 synchronized(lock) {
 174                     lock.notifyAll();
 175                 }
 176             }
 177         }
 178     }
 179 
 180     public static class NotificationEmitter extends NotificationBroadcasterSupport implements NotificationEmitterMBean {
 181 //      public NotificationEmitter() {
 182 //              super();
 183 // System.out.println("===NotificationEmitter: new instance.");
 184 //      }
 185 
 186         /**
 187          * Returns a NotificationInfo object containing the name of the Java class of the notification
 188          * and the notification types sent by this notification broadcaster.
 189          */
 190         public MBeanNotificationInfo[] getNotificationInfo() {
 191 
 192             MBeanNotificationInfo[] ntfInfoArray  = new MBeanNotificationInfo[1];
 193 
 194             String[] ntfTypes = new String[1];
 195             ntfTypes[0] = myType;
 196 
 197             ntfInfoArray[0] = new MBeanNotificationInfo(ntfTypes,
 198                                                         "javax.management.Notification",
 199                                                         "Notifications sent by the NotificationEmitter");
 200             return ntfInfoArray;
 201         }
 202 
 203 //      public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) {
 204 //          super.addNotificationListener(listener, filter, handback);
 205 
 206 //          System.out.println("============NotificationEmitter: add new listener");
 207 //      }
 208 
 209         /**
 210          * Send a Notification object with the specified times.
 211          * The sequence number will be from zero to times-1.
 212          *
 213          * @param nb The number of notifications to send
 214          */
 215         public void sendNotifications(Integer nb) {
 216             System.out.println("===NotificationEmitter: be asked to send notifications: "+nb);
 217 
 218             Notification notif;
 219             for (int i=1; i<=nb.intValue(); i++) {
 220                 notif = new Notification(myType, this, i);
 221                 sendNotification(notif);
 222             }
 223         }
 224 
 225         private String myType = "notification.my_notification";
 226     }
 227 
 228     public interface NotificationEmitterMBean {
 229         public void sendNotifications(Integer nb);
 230     }
 231 
 232     private static NotificationListener listener = new Listener();
 233 
 234     private static int nb = 10;
 235     private static int receivedNotifs = 0;
 236     private static int[] lock = new int[0];
 237 }