1 /*
   2  * Copyright (c) 2005, 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 6175517 6304996
  27  * @summary General MXBean test: createMBean, registerMBean, immutableInfo,
  28  *          interfaceClassName, openType, originalType, StandardMBean,
  29  *          StandardEmitterMBean.
  30  * @author Luis-Miguel Alventosa
  31  *
  32  * @run clean MiscTest
  33  * @run build MiscTest
  34  * @run main MiscTest
  35  */
  36 
  37 import java.io.*;
  38 import java.lang.management.*;
  39 import javax.management.*;
  40 import javax.management.openmbean.*;
  41 
  42 public class MiscTest {
  43 
  44     private static final MBeanNotificationInfo notifs[] =
  45         new MBeanNotificationInfo[] {
  46           new MBeanNotificationInfo(
  47             new String[] {AttributeChangeNotification.ATTRIBUTE_CHANGE},
  48             AttributeChangeNotification.class.getName(),
  49             "This notification is emitted when the reset() method is called.")
  50     };
  51 
  52     private static Class<?> testClasses[] = {
  53         Test11.class, Test12.class,
  54         Test21.class, Test22.class,
  55         Test31.class, Test32.class,
  56         Test33.class, Test34.class,
  57         Test41.class, Test42.class,
  58         Test43.class, Test44.class,
  59     };
  60 
  61     private static Class<?> testIntfs[] = {
  62         Test11MBean.class, Test12MBean.class,
  63         Test21MXBean.class, Test22MXBean.class,
  64         Test31SMB.class, Test32SMB.class,
  65         Test33SMB.class, Test34SMB.class,
  66         Test41SMX.class, Test42SMX.class,
  67         Test43SMX.class, Test44SMX.class,
  68     };
  69 
  70     public interface SuperInterface {
  71         public String getState();
  72         public void setState(String s);
  73         public int getNbChanges();
  74         public void reset();
  75         public void close(boolean force);
  76         public MemoryUsage getMemoryUsage();
  77     }
  78 
  79     public static class BaseTest {
  80 
  81         public String getState() {
  82             return state;
  83         }
  84 
  85         public void setState(String s) {
  86             state = s;
  87             nbChanges++;
  88         }
  89 
  90         public int getNbChanges() {
  91             return nbChanges;
  92         }
  93 
  94         public void reset() {
  95             state = "initial state";
  96             nbChanges = 0;
  97             nbResets++;
  98         }
  99 
 100         public String getName() {
 101             return "name";
 102         }
 103 
 104         public void setName(String s) {
 105         }
 106 
 107         public void close(boolean force) {
 108         }
 109 
 110         public MemoryUsage getMemoryUsage() {
 111             return new MemoryUsage(10, 20, 30, 40);
 112         }
 113 
 114         public int getNbResets() {
 115             return nbResets;
 116         }
 117 
 118         private String state = "initial state";
 119         private int nbChanges = 0;
 120         private int nbResets = 0;
 121     }
 122 
 123     public static class BaseEmitterTest
 124         extends NotificationBroadcasterSupport {
 125 
 126         public String getState() {
 127             return state;
 128         }
 129 
 130         public void setState(String s) {
 131             state = s;
 132             nbChanges++;
 133         }
 134 
 135         public int getNbChanges() {
 136             return nbChanges;
 137         }
 138 
 139         public void reset() {
 140             state = "initial state";
 141             nbChanges = 0;
 142             nbResets++;
 143         }
 144 
 145         public String getName() {
 146             return "name";
 147         }
 148 
 149         public void setName(String s) {
 150         }
 151 
 152         public void close(boolean force) {
 153         }
 154 
 155         public MemoryUsage getMemoryUsage() {
 156             return new MemoryUsage(10, 20, 30, 40);
 157         }
 158 
 159         public int getNbResets() {
 160             return nbResets;
 161         }
 162 
 163         public MBeanNotificationInfo[] getNotificationInfo() {
 164             return notifs;
 165         }
 166 
 167         private String state = "initial state";
 168         private int nbChanges = 0;
 169         private int nbResets = 0;
 170     }
 171 
 172     public static interface Test11MBean extends SuperInterface {
 173     }
 174 
 175     public static interface Test12MBean extends SuperInterface {
 176     }
 177 
 178     public static interface Test21MXBean extends SuperInterface {
 179     }
 180 
 181     public static interface Test22MXBean extends SuperInterface {
 182     }
 183 
 184     public static interface Test31SMB extends SuperInterface {
 185     }
 186 
 187     public static interface Test32SMB extends SuperInterface {
 188     }
 189 
 190     public static interface Test33SMB extends SuperInterface {
 191     }
 192 
 193     public static interface Test34SMB extends SuperInterface {
 194     }
 195 
 196     public static interface Test41SMX extends SuperInterface {
 197     }
 198 
 199     public static interface Test42SMX extends SuperInterface {
 200     }
 201 
 202     public static interface Test43SMX extends SuperInterface {
 203     }
 204 
 205     public static interface Test44SMX extends SuperInterface {
 206     }
 207 
 208     public static class Test11 extends BaseTest
 209         implements Test11MBean {
 210     }
 211 
 212     public static class Test12 extends BaseEmitterTest
 213         implements Test12MBean {
 214     }
 215 
 216     public static class Test21 extends BaseTest
 217         implements Test21MXBean {
 218     }
 219 
 220     public static class Test22 extends BaseEmitterTest
 221         implements Test22MXBean {
 222     }
 223 
 224     public static class Test31 extends BaseTest
 225         implements Test31SMB {
 226     }
 227 
 228     public static class Test32 extends BaseEmitterTest
 229         implements Test32SMB {
 230     }
 231 
 232     public static class Test33 extends StandardMBean
 233         implements Test33SMB {
 234 
 235         public Test33() {
 236             super(Test33SMB.class, false);
 237         }
 238 
 239         public String getState() {
 240             return state;
 241         }
 242 
 243         public void setState(String s) {
 244             state = s;
 245             nbChanges++;
 246         }
 247 
 248         public int getNbChanges() {
 249             return nbChanges;
 250         }
 251 
 252         public void reset() {
 253             state = "initial state";
 254             nbChanges = 0;
 255             nbResets++;
 256         }
 257 
 258         public String getName() {
 259             return "name";
 260         }
 261 
 262         public void setName(String s) {
 263         }
 264 
 265         public void close(boolean force) {
 266         }
 267 
 268         public MemoryUsage getMemoryUsage() {
 269             return new MemoryUsage(10, 20, 30, 40);
 270         }
 271 
 272         public int getNbResets() {
 273             return nbResets;
 274         }
 275 
 276         private String state = "initial state";
 277         private int nbChanges = 0;
 278         private int nbResets = 0;
 279     }
 280 
 281     public static class Test34 extends StandardEmitterMBean
 282         implements Test34SMB {
 283 
 284         public Test34() {
 285             super(Test34SMB.class, false,
 286                   new NotificationBroadcasterSupport(notifs));
 287         }
 288 
 289         public String getState() {
 290             return state;
 291         }
 292 
 293         public void setState(String s) {
 294             state = s;
 295             nbChanges++;
 296         }
 297 
 298         public int getNbChanges() {
 299             return nbChanges;
 300         }
 301 
 302         public void reset() {
 303             state = "initial state";
 304             nbChanges = 0;
 305             nbResets++;
 306         }
 307 
 308         public String getName() {
 309             return "name";
 310         }
 311 
 312         public void setName(String s) {
 313         }
 314 
 315         public void close(boolean force) {
 316         }
 317 
 318         public MemoryUsage getMemoryUsage() {
 319             return new MemoryUsage(10, 20, 30, 40);
 320         }
 321 
 322         public int getNbResets() {
 323             return nbResets;
 324         }
 325 
 326         private String state = "initial state";
 327         private int nbChanges = 0;
 328         private int nbResets = 0;
 329     }
 330 
 331     public static class Test41 extends BaseTest
 332         implements Test41SMX {
 333     }
 334 
 335     public static class Test42 extends BaseEmitterTest
 336         implements Test42SMX {
 337     }
 338 
 339    public static class Test43 extends StandardMBean
 340         implements Test43SMX {
 341 
 342         public Test43() {
 343             super(Test43SMX.class, true);
 344         }
 345 
 346         public String getState() {
 347             return state;
 348         }
 349 
 350         public void setState(String s) {
 351             state = s;
 352             nbChanges++;
 353         }
 354 
 355         public int getNbChanges() {
 356             return nbChanges;
 357         }
 358 
 359         public void reset() {
 360             state = "initial state";
 361             nbChanges = 0;
 362             nbResets++;
 363         }
 364 
 365         public String getName() {
 366             return "name";
 367         }
 368 
 369         public void setName(String s) {
 370         }
 371 
 372         public void close(boolean force) {
 373         }
 374 
 375         public MemoryUsage getMemoryUsage() {
 376             return new MemoryUsage(10, 20, 30, 40);
 377         }
 378 
 379         public int getNbResets() {
 380             return nbResets;
 381         }
 382 
 383         private String state = "initial state";
 384         private int nbChanges = 0;
 385         private int nbResets = 0;
 386     }
 387 
 388     public static class Test44 extends StandardEmitterMBean
 389         implements Test44SMX {
 390 
 391         public Test44() {
 392             super(Test44SMX.class, true,
 393                   new NotificationBroadcasterSupport(notifs));
 394         }
 395 
 396         public String getState() {
 397             return state;
 398         }
 399 
 400         public void setState(String s) {
 401             state = s;
 402             nbChanges++;
 403         }
 404 
 405         public int getNbChanges() {
 406             return nbChanges;
 407         }
 408 
 409         public void reset() {
 410             state = "initial state";
 411             nbChanges = 0;
 412             nbResets++;
 413         }
 414 
 415         public String getName() {
 416             return "name";
 417         }
 418 
 419         public void setName(String s) {
 420         }
 421 
 422         public void close(boolean force) {
 423         }
 424 
 425         public MemoryUsage getMemoryUsage() {
 426             return new MemoryUsage(10, 20, 30, 40);
 427         }
 428 
 429         public int getNbResets() {
 430             return nbResets;
 431         }
 432 
 433         private String state = "initial state";
 434         private int nbChanges = 0;
 435         private int nbResets = 0;
 436     }
 437 
 438     public static void main(String[] args) throws Exception {
 439         // Instantiate the MBean server
 440         //
 441         echo("\n>>> Create the MBean server");
 442         MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
 443 
 444         // Get default domain
 445         //
 446         echo("\n>>> Get the MBean server's default domain");
 447         String domain = mbs.getDefaultDomain();
 448         echo("\tDefault Domain = " + domain);
 449 
 450         for (int i = 0; i < testClasses.length; i++) {
 451             // Create and register the Test MBean
 452             //
 453             String cn = testClasses[i].getName();
 454             String ons = domain + ":type=" + cn;
 455             echo("\n>>> Create the " + cn +
 456                  " MBean within the MBeanServer");
 457             echo("\tObjectName = " + ons);
 458             ObjectName on = ObjectName.getInstance(ons);
 459             if (testClasses[i] == Test31.class ||
 460                 testClasses[i] == Test41.class) {
 461                 StandardMBean s = new StandardMBean(
 462                                       testClasses[i].newInstance(),
 463                                       (Class) testIntfs[i],
 464                                       testClasses[i] == Test41.class);
 465                 mbs.registerMBean(s, on);
 466             } else if (testClasses[i] == Test32.class ||
 467                        testClasses[i] == Test42.class) {
 468                 Object o = testClasses[i].newInstance();
 469                 StandardEmitterMBean s = new StandardEmitterMBean(
 470                                o,
 471                                (Class) testIntfs[i],
 472                                testClasses[i] == Test42.class,
 473                                (NotificationEmitter) o);
 474                 mbs.registerMBean(s, on);
 475             } else {
 476                 mbs.createMBean(cn, on);
 477             }
 478 
 479             // Check notifs
 480             //
 481             MBeanInfo mbi = mbs.getMBeanInfo(on);
 482             MBeanNotificationInfo mbni[] = mbi.getNotifications();
 483             if (i % 2 == 0) {
 484                 if (mbni.length != 0) {
 485                     throw new IllegalArgumentException(
 486                     "Should not be a NotificationEmitter");
 487                 }
 488             } else {
 489                 if (mbni.length != 1) {
 490                     throw new IllegalArgumentException(
 491                     "Should not a NotificationEmitter with one notification");
 492                 }
 493             }
 494             // Manage the Test MBean
 495             //
 496             manageMBean(mbs, on, cn);
 497         }
 498     }
 499 
 500     private static void manageMBean(MBeanServer mbs,
 501                                     ObjectName on,
 502                                     String cn)
 503         throws Exception {
 504 
 505         echo("\n>>> Manage the " + cn +
 506              " MBean using its attributes ");
 507         echo("    and operations exposed for management");
 508 
 509         // Get attribute values
 510         printAttributes(mbs, on);
 511 
 512         // Change State attribute
 513         echo("\n    Setting State attribute to value \"new state\"...");
 514         Attribute stateAttribute = new Attribute("State","new state");
 515         mbs.setAttribute(on, stateAttribute);
 516 
 517         // Get attribute values
 518         printAttributes(mbs, on);
 519 
 520         // Invoking reset operation
 521         echo("\n    Invoking reset operation...");
 522         mbs.invoke(on, "reset", null, null);
 523 
 524         // Invoking close operation
 525         echo("\n    Invoking close operation...");
 526         String type = on.getKeyProperty("type");
 527         String signature[] = {"boolean"};
 528         mbs.invoke(on, "close", new Object[] {true}, signature);
 529 
 530         // Get attribute values
 531         printAttributes(mbs, on);
 532 
 533         // Create proxy
 534         if (type.equals(Test11.class.getName())) {
 535             Test11MBean p = JMX.newMBeanProxy(mbs,
 536                                               on,
 537                                               Test11MBean.class);
 538             // Get attribute values
 539             echo("\n    Getting attribute values through proxies:");
 540             echo("\tState       = \"" + p.getState() + "\"");
 541             echo("\tNbChanges   = " + p.getNbChanges());
 542             echo("\tMemoryUsage = " + p.getMemoryUsage());
 543             checkDescriptor(mbs, on, "true", Test11MBean.class.getName());
 544         } else if (type.equals(Test12.class.getName())) {
 545             Test12MBean p = JMX.newMBeanProxy(mbs,
 546                                               on,
 547                                               Test12MBean.class,
 548                                               true);
 549             // Get attribute values
 550             echo("\n    Getting attribute values through proxies:");
 551             echo("\tState       = \"" + p.getState() + "\"");
 552             echo("\tNbChanges   = " + p.getNbChanges());
 553             echo("\tMemoryUsage = " + p.getMemoryUsage());
 554             checkDescriptor(mbs, on, "false", Test12MBean.class.getName());
 555         } else if (type.equals(Test21.class.getName())) {
 556             Test21MXBean p = JMX.newMXBeanProxy(mbs,
 557                                                 on,
 558                                                 Test21MXBean.class);
 559             // Get attribute values
 560             echo("\n    Getting attribute values through proxies:");
 561             echo("\tState       = \"" + p.getState() + "\"");
 562             echo("\tNbChanges   = " + p.getNbChanges());
 563             echo("\tMemoryUsage = " + p.getMemoryUsage());
 564             checkDescriptor(mbs, on, "true", Test21MXBean.class.getName());
 565         } else if (type.equals(Test22.class.getName())) {
 566             Test22MXBean p = JMX.newMXBeanProxy(mbs,
 567                                                 on,
 568                                                 Test22MXBean.class,
 569                                                 true);
 570             // Get attribute values
 571             echo("\n    Getting attribute values through proxies:");
 572             echo("\tState       = \"" + p.getState() + "\"");
 573             echo("\tNbChanges   = " + p.getNbChanges());
 574             echo("\tMemoryUsage = " + p.getMemoryUsage());
 575             checkDescriptor(mbs, on, "true", Test22MXBean.class.getName());
 576         } else if (type.equals(Test31.class.getName())) {
 577             Test31SMB p = JMX.newMBeanProxy(mbs,
 578                                             on,
 579                                             Test31SMB.class);
 580             // Get attribute values
 581             echo("\n    Getting attribute values through proxies:");
 582             echo("\tState       = \"" + p.getState() + "\"");
 583             echo("\tNbChanges   = " + p.getNbChanges());
 584             echo("\tMemoryUsage = " + p.getMemoryUsage());
 585             checkDescriptor(mbs, on, "true", Test31SMB.class.getName());
 586         } else if (type.equals(Test32.class.getName())) {
 587             Test32SMB p = JMX.newMBeanProxy(mbs,
 588                                             on,
 589                                             Test32SMB.class,
 590                                             true);
 591             // Get attribute values
 592             echo("\n    Getting attribute values through proxies:");
 593             echo("\tState       = \"" + p.getState() + "\"");
 594             echo("\tNbChanges   = " + p.getNbChanges());
 595             echo("\tMemoryUsage = " + p.getMemoryUsage());
 596             checkDescriptor(mbs, on, "true", Test32SMB.class.getName());
 597         } else if (type.equals(Test33.class.getName())) {
 598             Test33SMB p = JMX.newMBeanProxy(mbs,
 599                                             on,
 600                                             Test33SMB.class,
 601                                             true);
 602             // Get attribute values
 603             echo("\n    Getting attribute values through proxies:");
 604             echo("\tState       = \"" + p.getState() + "\"");
 605             echo("\tNbChanges   = " + p.getNbChanges());
 606             echo("\tMemoryUsage = " + p.getMemoryUsage());
 607             checkDescriptor(mbs, on, "true", Test33SMB.class.getName());
 608         } else if (type.equals(Test34.class.getName())) {
 609             Test34SMB p = JMX.newMBeanProxy(mbs,
 610                                             on,
 611                                             Test34SMB.class,
 612                                             true);
 613             // Get attribute values
 614             echo("\n    Getting attribute values through proxies:");
 615             echo("\tState       = \"" + p.getState() + "\"");
 616             echo("\tNbChanges   = " + p.getNbChanges());
 617             echo("\tMemoryUsage = " + p.getMemoryUsage());
 618             checkDescriptor(mbs, on, "true", Test34SMB.class.getName());
 619         } else if (type.equals(Test41.class.getName())) {
 620             Test41SMX p = JMX.newMXBeanProxy(mbs,
 621                                              on,
 622                                              Test41SMX.class);
 623             // Get attribute values
 624             echo("\n    Getting attribute values through proxies:");
 625             echo("\tState       = \"" + p.getState() + "\"");
 626             echo("\tNbChanges   = " + p.getNbChanges());
 627             echo("\tMemoryUsage = " + p.getMemoryUsage());
 628             checkDescriptor(mbs, on, "true", Test41SMX.class.getName());
 629         } else if (type.equals(Test42.class.getName())) {
 630             Test42SMX p = JMX.newMXBeanProxy(mbs,
 631                                              on,
 632                                              Test42SMX.class,
 633                                              true);
 634             // Get attribute values
 635             echo("\n    Getting attribute values through proxies:");
 636             echo("\tState       = \"" + p.getState() + "\"");
 637             echo("\tNbChanges   = " + p.getNbChanges());
 638             echo("\tMemoryUsage = " + p.getMemoryUsage());
 639             checkDescriptor(mbs, on, "true", Test42SMX.class.getName());
 640         } else if (type.equals(Test43.class.getName())) {
 641             Test43SMX p = JMX.newMXBeanProxy(mbs,
 642                                              on,
 643                                              Test43SMX.class);
 644             // Get attribute values
 645             echo("\n    Getting attribute values through proxies:");
 646             echo("\tState       = \"" + p.getState() + "\"");
 647             echo("\tNbChanges   = " + p.getNbChanges());
 648             echo("\tMemoryUsage = " + p.getMemoryUsage());
 649             checkDescriptor(mbs, on, "true", Test43SMX.class.getName());
 650         } else if (type.equals(Test44.class.getName())) {
 651             Test44SMX p = JMX.newMXBeanProxy(mbs,
 652                                              on,
 653                                              Test44SMX.class,
 654                                              true);
 655             // Get attribute values
 656             echo("\n    Getting attribute values through proxies:");
 657             echo("\tState       = \"" + p.getState() + "\"");
 658             echo("\tNbChanges   = " + p.getNbChanges());
 659             echo("\tMemoryUsage = " + p.getMemoryUsage());
 660             checkDescriptor(mbs, on, "true", Test44SMX.class.getName());
 661         } else {
 662             throw new IllegalArgumentException("Invalid MBean type");
 663         }
 664     }
 665 
 666     private static void printAttributes(MBeanServer mbs,
 667                                         ObjectName on)
 668         throws Exception {
 669         echo("\n    Getting attribute values:");
 670         String state = (String) mbs.getAttribute(on, "State");
 671         Integer nbChanges = (Integer) mbs.getAttribute(on,"NbChanges");
 672         echo("\tState     = \"" + state + "\"");
 673         echo("\tNbChanges = " + nbChanges);
 674         String type = on.getKeyProperty("type");
 675         if (type.indexOf("Test2") != -1 || type.indexOf("Test4") != -1) {
 676             CompositeData memoryUsage =
 677                 (CompositeData) mbs.getAttribute(on, "MemoryUsage");
 678             echo("\tMemoryUsage = " + memoryUsage);
 679         } else {
 680             MemoryUsage memoryUsage =
 681                 (MemoryUsage) mbs.getAttribute(on, "MemoryUsage");
 682             echo("\tMemoryUsage = " + memoryUsage);
 683         }
 684     }
 685 
 686     public static void checkDescriptor(MBeanServer mbs,
 687                                        ObjectName on,
 688                                        String immutable,
 689                                        String intf)
 690             throws Exception {
 691 
 692         MBeanInfo mbi = mbs.getMBeanInfo(on);
 693 
 694         Descriptor d = mbi.getDescriptor();
 695         if (d == null || d.getFieldNames().length == 0)
 696             throw new IllegalArgumentException("Empty descriptor");
 697         if (!d.getFieldValue("immutableInfo").equals(immutable)) {
 698             final String msg =
 699                 "Bad descriptor: expected immutableInfo=" + immutable + ": " + d;
 700             throw new IllegalArgumentException(msg);
 701         }
 702         if (!d.getFieldValue("interfaceClassName").equals(intf)) {
 703             final String msg =
 704                 "Bad descriptor: expected interfaceClassName=" + intf + ": " + d;
 705             throw new IllegalArgumentException(msg);
 706         }
 707 
 708         if (intf.indexOf("MX") != -1) {
 709             MBeanAttributeInfo attrs[] = mbi.getAttributes();
 710             if (attrs == null || attrs.length == 0)
 711                 throw new IllegalArgumentException("No attributes");
 712             boolean nbChangesFound = false;
 713             for (MBeanAttributeInfo attr : attrs) {
 714                 if (attr.getName().equals("NbChanges")) {
 715                     nbChangesFound = true;
 716                     Descriptor ad = attr.getDescriptor();
 717                     OpenType<?> opty = (OpenType<?>)
 718                         ad.getFieldValue("openType");
 719                     if (!opty.equals(SimpleType.INTEGER)) {
 720                         throw new IllegalArgumentException("Open type should " +
 721                                                            "be INTEGER: " + opty);
 722                     }
 723                     String orty =
 724                         (String) ad.getFieldValue("originalType");
 725                     if (!orty.equals(Integer.TYPE.getName())) {
 726                         throw new IllegalArgumentException("Orig type should " +
 727                                                            "be int: " + orty);
 728                     }
 729                 }
 730             }
 731             if (!nbChangesFound)
 732                 throw new IllegalArgumentException("Did not find NbChanges");
 733         }
 734     }
 735 
 736     private static void echo(String msg) {
 737         System.out.println(msg);
 738     }
 739 }