|
1 /* |
|
2 * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
21 * have any questions. |
|
22 */ |
|
23 /* |
|
24 * |
|
25 * @test JMXRemoteNamespaceTest.java |
|
26 * @summary Basic tests on a JMXRemoteNamespace. |
|
27 * @author Daniel Fuchs |
|
28 * @run clean JMXRemoteNamespaceTest Wombat WombatMBean |
|
29 * @run build JMXRemoteNamespaceTest Wombat WombatMBean |
|
30 * @run main JMXRemoteNamespaceTest |
|
31 */ |
|
32 |
|
33 import javax.management.JMX; |
|
34 import javax.management.Notification; |
|
35 import javax.management.ObjectName; |
|
36 import javax.management.namespace.JMXNamespaces; |
|
37 import javax.management.MBeanServer; |
|
38 import javax.management.MBeanServerFactory; |
|
39 import javax.management.NotificationListener; |
|
40 import javax.management.namespace.JMXRemoteNamespace; |
|
41 import javax.management.remote.JMXConnectorServer; |
|
42 import javax.management.remote.JMXConnectorServerFactory; |
|
43 import javax.management.remote.JMXServiceURL; |
|
44 import java.util.List; |
|
45 import java.util.ArrayList; |
|
46 import java.util.Collections; |
|
47 import java.io.IOException; |
|
48 import javax.management.AttributeChangeNotification; |
|
49 |
|
50 /** |
|
51 * Test simple creation/registration of namespace. |
|
52 * |
|
53 */ |
|
54 public class JMXRemoteNamespaceTest { |
|
55 |
|
56 static class MyConnect implements NotificationListener { |
|
57 private final JMXRemoteNamespace my; |
|
58 private final List<Notification> list; |
|
59 private volatile int connectCount=0; |
|
60 private int closeCount=0; |
|
61 private final ObjectName myname; |
|
62 public MyConnect(JMXRemoteNamespace my, ObjectName myname) { |
|
63 this.my=my; |
|
64 this.myname = myname; |
|
65 list = Collections.synchronizedList(new ArrayList<Notification>()); |
|
66 my.addNotificationListener(this, null, null); |
|
67 } |
|
68 |
|
69 public synchronized void connect() throws IOException { |
|
70 my.connect(); |
|
71 if (!my.isConnected()) |
|
72 throw new IOException(myname+" should be connected"); |
|
73 connectCount++; |
|
74 } |
|
75 |
|
76 public void close() throws IOException { |
|
77 my.close(); |
|
78 if (my.isConnected()) |
|
79 throw new IOException(myname+" shouldn't be connected"); |
|
80 closeCount++; |
|
81 } |
|
82 |
|
83 public synchronized int getConnectCount() { |
|
84 return connectCount; |
|
85 } |
|
86 public synchronized int getClosedCount() { |
|
87 return closeCount; |
|
88 } |
|
89 |
|
90 public synchronized void handleNotification(Notification notification, |
|
91 Object handback) { |
|
92 list.add(notification); |
|
93 } |
|
94 |
|
95 public synchronized void checkNotifs(int externalConnect, |
|
96 int externalClosed) throws Exception { |
|
97 System.err.println("Connected: "+connectCount+" time"+ |
|
98 ((connectCount>1)?"s":"")); |
|
99 System.err.println("Closed: "+closeCount+" time"+ |
|
100 ((closeCount>1)?"s":"")); |
|
101 System.err.println("Received:"); |
|
102 int cl=0; |
|
103 int co=0; |
|
104 for (Notification n : list) { |
|
105 System.err.println("\t"+n); |
|
106 if (!(n instanceof AttributeChangeNotification)) |
|
107 throw new Exception("Unexpected notif: "+n.getClass()); |
|
108 final AttributeChangeNotification acn = |
|
109 (AttributeChangeNotification)n; |
|
110 if (((Boolean)acn.getNewValue()).booleanValue()) |
|
111 co++; |
|
112 else cl++; |
|
113 if ((((Boolean)acn.getNewValue()).booleanValue()) |
|
114 == (((Boolean)acn.getOldValue()).booleanValue())) { |
|
115 throw new Exception("Bad values: old=new"); |
|
116 } |
|
117 } |
|
118 if (! (list.size()==(closeCount+connectCount+ |
|
119 externalClosed+externalConnect))) { |
|
120 throw new Exception("Bad notif count - got "+list.size()); |
|
121 } |
|
122 if (cl!=(closeCount+externalClosed)) { |
|
123 throw new Exception("Bad count of close notif: expected " |
|
124 +(closeCount+externalClosed)+", got"+cl); |
|
125 } |
|
126 if (co!=(connectCount+externalConnect)) { |
|
127 throw new Exception("Bad count of connect notif: expected " |
|
128 +(connectCount+externalConnect)+", got"+co); |
|
129 } |
|
130 } |
|
131 } |
|
132 |
|
133 public static void testConnectClose() throws Exception { |
|
134 final MBeanServer myServer = MBeanServerFactory.newMBeanServer(); |
|
135 final JMXConnectorServer myRMI = |
|
136 JMXConnectorServerFactory.newJMXConnectorServer( |
|
137 new JMXServiceURL("rmi",null,0), null, myServer); |
|
138 myRMI.start(); |
|
139 try { |
|
140 final JMXRemoteNamespace my = |
|
141 JMXRemoteNamespace.newJMXRemoteNamespace( |
|
142 myRMI.getAddress(),null); |
|
143 final MBeanServer s = MBeanServerFactory.newMBeanServer(); |
|
144 final ObjectName myname = JMXNamespaces.getNamespaceObjectName("my"); |
|
145 final ObjectName wname = ObjectName.getInstance("backyard:type=Wombat"); |
|
146 myServer.registerMBean(new Wombat(),wname); |
|
147 final MyConnect myc = new MyConnect(my,myname); |
|
148 myc.connect(); |
|
149 myc.close(); |
|
150 myc.connect(); |
|
151 s.registerMBean(my,myname); |
|
152 myc.close(); |
|
153 myc.connect(); |
|
154 if (!s.queryNames(new ObjectName("my//b*:*"),null).contains( |
|
155 JMXNamespaces.insertPath("my", wname))) { |
|
156 throw new RuntimeException("1: Wombat not found: "+wname); |
|
157 } |
|
158 myc.close(); |
|
159 myc.connect(); |
|
160 final MBeanServer cd = JMXNamespaces.narrowToNamespace(s, "my"); |
|
161 if (!cd.queryNames(new ObjectName("b*:*"),null).contains(wname)) { |
|
162 throw new RuntimeException("2: Wombat not found: "+wname); |
|
163 } |
|
164 myc.close(); |
|
165 myc.connect(); |
|
166 System.out.println("Found a Wombat in my backyard."); |
|
167 |
|
168 final String deepThoughts = "I want to leave this backyard!"; |
|
169 final WombatMBean w = JMX.newMBeanProxy(cd, wname, WombatMBean.class); |
|
170 w.setCaption(deepThoughts); |
|
171 if (!deepThoughts.equals(w.getCaption())) |
|
172 throw new RuntimeException("4: Wombat is not thinking right: "+ |
|
173 w.getCaption()); |
|
174 s.unregisterMBean(myname); |
|
175 if (my.isConnected()) |
|
176 throw new Exception(myname+" shouldn't be connected"); |
|
177 myc.connect(); |
|
178 myc.close(); |
|
179 myc.checkNotifs(0,1); |
|
180 } finally { |
|
181 myRMI.stop(); |
|
182 } |
|
183 |
|
184 } |
|
185 |
|
186 public static void main(String... args) throws Exception { |
|
187 testConnectClose(); |
|
188 } |
|
189 } |