Path: blob/master/test/jdk/javax/management/modelmbean/RequiredModelMBeanMethodTest.java
41152 views
/*1* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 495075626* @summary Test that RequiredModelMBean.invoke will not invoke methods27* from the RequiredModelMBean class itself if they are not in the28* ModelMBeanInfo29* @author Eamonn McManus30*31* @run clean RequiredModelMBeanMethodTest32* @run build RequiredModelMBeanMethodTest33* @run main RequiredModelMBeanMethodTest34*/3536import java.lang.reflect.*;37import javax.management.*;38import javax.management.modelmbean.*;3940/*41* We do the same test with a number of different operations:42*43* - A plain operation that is directed to the managed resource in the44* usual way. We give it some parameters so we can test that the45* class loading logic for signature parameters is reasonable.46*47* - An operation (removeNotificationListener) that is directed to the48* RequiredModelMBean itself. We use this particular operation because49* it will throw an exception, which allows us to check that it did in50* fact execute.51*52* - An operation (load()) that has the same signature as a53* RequiredModelMBean operation but is directed to the resource54* because of a "class" field in the descriptor.55*56* - An operation (store()) that has the same signature as a57* RequiredModelMBean operation but is directed to the resource58* because of a "targetObject" field in the descriptor.59*60* In each case we check that the operation does not work if it is not61* in the ModelMBeanInfo, and does work if it is.62*/63public class RequiredModelMBeanMethodTest {64public static void main(String[] args) throws Exception {65boolean ok = true;66MBeanServer mbs = MBeanServerFactory.createMBeanServer();6768Descriptor tralalaDescriptor =69new DescriptorSupport(new String[] {70"name=tralala",71"descriptorType=operation",72"role=operation",73"targetType=ObjectReference",74});75Method tralalaMethod =76Resource.class.getMethod("tralala",77new Class[] {int.class, Resource.class});78ModelMBeanOperationInfo tralalaInfo =79new ModelMBeanOperationInfo("tralala descr", tralalaMethod,80tralalaDescriptor);8182Method remACNLMethod =83RequiredModelMBean.class.getMethod("removeAttributeChangeNotificationListener",84new Class[] {85NotificationListener.class,86String.class87});88ModelMBeanOperationInfo remACNLInfo =89new ModelMBeanOperationInfo("remACNL descr", remACNLMethod);9091Descriptor loadDescriptor =92new DescriptorSupport(new String[] {93"name=load",94"descriptorType=operation",95"role=operation",96"targetType=ObjectReference",97"class=" + Resource.class.getName(),98});99ModelMBeanOperationInfo loadInfo =100new ModelMBeanOperationInfo("load", "load descr",101new MBeanParameterInfo[0],102"void", ModelMBeanOperationInfo.ACTION,103loadDescriptor);104105Descriptor storeDescriptor =106new DescriptorSupport(new String[] {107"name=store",108"descriptorType=operation",109"role=operation",110"targetType=ObjectReference",111});112storeDescriptor.setField("targetObject", resource);113ModelMBeanOperationInfo storeInfo =114new ModelMBeanOperationInfo("store", "store descr",115new MBeanParameterInfo[0],116"void", ModelMBeanOperationInfo.ACTION,117storeDescriptor);118119ModelMBeanInfo emptyMMBI =120new ModelMBeanInfoSupport(Resource.class.getName(),121"empty descr",122null, null, null, null);123ModelMBean emptyMMB = new RequiredModelMBean(emptyMMBI);124emptyMMB.setManagedResource(resource, "ObjectReference");125ObjectName emptyMMBName = new ObjectName("test:type=Empty");126mbs.registerMBean(emptyMMB, emptyMMBName);127128System.out.println("Testing that we cannot call methods not in the " +129"ModelMBeanInfo");130try {131boolean thisok = test(mbs, emptyMMBName, false);132if (thisok)133System.out.println("...OK");134else135ok = false;136} catch (Exception e) {137System.out.println("TEST FAILED: Caught exception:");138e.printStackTrace(System.out);139ok = false;140}141142ModelMBeanOperationInfo[] opInfos = {143tralalaInfo, remACNLInfo, loadInfo, storeInfo,144};145ModelMBeanInfo fullMMBI =146new ModelMBeanInfoSupport(Resource.class.getName(),147"full descr",148null, null, opInfos, null);149ModelMBean fullMMB = new RequiredModelMBean(fullMMBI);150fullMMB.setManagedResource(resource, "ObjectReference");151ObjectName fullMMBName = new ObjectName("test:type=Full");152mbs.registerMBean(fullMMB, fullMMBName);153154155System.out.println();156System.out.println("Testing that we can call methods in the " +157"ModelMBeanInfo");158System.out.println(" and that \"class\" or \"targetObject\" in " +159"descriptor directs methods to resource");160try {161boolean thisok = test(mbs, fullMMBName, true);162if (thisok)163System.out.println("...OK");164else165ok = false;166} catch (Exception e) {167System.out.println("TEST FAILED: Caught exception:");168e.printStackTrace(System.out);169ok = false;170}171172if (ok) {173if (!resource.loadCalled || !resource.storeCalled) {174System.out.println("TEST FAILED: not called:" +175(resource.loadCalled ? "" : " load") +176(resource.storeCalled ? "" : " store"));177ok = false;178}179}180181// Test the invoke("class.method") form182if (ok) {183System.out.println("Testing invoke(\"class.method\")");184resource.loadCalled = false;185mbs.invoke(fullMMBName, Resource.class.getName() + ".load",186null, null);187if (!resource.loadCalled) {188System.out.println("TEST FAILED: load not called");189ok = false;190}191try {192mbs.invoke(fullMMBName,193RequiredModelMBean.class.getName() +194".removeAttributeChangeNotificationListener",195new Object[] {boringListener, null},196new String[] {197NotificationListener.class.getName(),198String.class.getName(),199});200System.out.println("TEST FAILED: removeNotificationListener" +201" returned successfully but " +202"should not have");203ok = false;204} catch (MBeanException e) {205final Exception target = e.getTargetException();206if (target instanceof ListenerNotFoundException) {207// OK: there is no such listener208} else209throw e;210}211}212213if (ok)214System.out.println("Test passed");215else {216System.out.println("TEST FAILED");217System.exit(1);218}219}220221private static boolean test(MBeanServer mbs, ObjectName name,222boolean shouldWork)223throws Exception {224225boolean ok = true;226227final String[] names = {228"tralala",229"removeAttributeChangeNotificationListener",230"load",231"store",232};233234for (int i = 0; i < 4; i++) {235boolean thisok = true;236try {237switch (i) {238case 0:239String tralala = (String)240mbs.invoke(name, names[i],241new Object[] {new Integer(5), resource},242new String[] {"int",243Resource.class.getName()});244if (!"tralala".equals(tralala)) {245System.out.println("TEST FAILED: tralala returned: " +246tralala);247thisok = false;248}249break;250case 1:251try {252mbs.invoke(name,253names[i],254new Object[] {boringListener, null},255new String[] {256NotificationListener.class.getName(),257String.class.getName(),258});259System.out.println("TEST FAILED: " + names[i] +260" returned successfully but " +261"should not have");262thisok = false;263} catch (MBeanException e) {264final Exception target = e.getTargetException();265if (target instanceof ListenerNotFoundException) {266// OK: there is no such listener267} else268throw e;269}270break;271case 2:272case 3:273mbs.invoke(name,274names[i],275new Object[0],276new String[0]);277break;278default:279throw new AssertionError();280}281282thisok = shouldWork;283if (!shouldWork) {284System.out.println("TEST FAILED: " + names[i] +285" worked but should not");286}287} catch (MBeanException e) {288if (shouldWork) {289System.out.println("TEST FAILED: " + names[i] + ": " + e);290e.printStackTrace(System.out);291thisok = false;292} else {293Exception target = e.getTargetException();294if (!(target instanceof ServiceNotFoundException)) {295System.out.println("TEST FAILED: " + names[i] +296": wrong exception: " + target);297thisok = false;298}299}300} catch (Exception e) {301System.out.println("TEST FAILED: " + names[i] + ": " + e);302e.printStackTrace(System.out);303thisok = false;304}305306if (thisok)307System.out.println("OK: " + names[i]);308else309ok = false;310}311312return ok;313}314315public static class Resource {316public String tralala(int x, Resource y) {317if (x != 5 || y != this)318return "wrong params: " + x + " " + y;319return "tralala";320}321322public void load() {323loadCalled = true;324}325326public void store() {327storeCalled = true;328}329330boolean loadCalled, storeCalled;331}332333private static Resource resource = new Resource();334335private static NotificationListener boringListener =336new NotificationListener() {337public void handleNotification(Notification n, Object h) {338}339};340}341342343