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