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
39import java.rmi.RemoteException;
40import java.rmi.registry.LocateRegistry;
41import java.rmi.registry.Registry;
42import java.util.Random;
43import javax.management.MBeanNotificationInfo;
44import javax.management.MBeanServer;
45import javax.management.MBeanServerConnection;
46import javax.management.MBeanServerFactory;
47import javax.management.Notification;
48import javax.management.NotificationBroadcasterSupport;
49import javax.management.NotificationFilterSupport;
50import javax.management.NotificationListener;
51import javax.management.ObjectInstance;
52import javax.management.ObjectName;
53import javax.management.remote.JMXConnector;
54import javax.management.remote.JMXConnectorFactory;
55import javax.management.remote.JMXConnectorServer;
56import javax.management.remote.JMXConnectorServerFactory;
57import javax.management.remote.JMXServiceURL;
58
59public 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}
237