Path: blob/master/test/jdk/javax/management/remote/mandatory/notif/NotificationEmissionTest.java
41155 views
/*1* Copyright (c) 2005, 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 510672126* @key intermittent27* @summary Check the emission of notifications when a Security Manager is28* installed. Test the property "jmx.remote.x.check.notification.emission".29* @author Luis-Miguel Alventosa30*31* @run clean NotificationEmissionTest32* @run build NotificationEmissionTest33* @run main NotificationEmissionTest 134* @run main/othervm -Djava.security.manager=allow NotificationEmissionTest 235* @run main/othervm -Djava.security.manager=allow NotificationEmissionTest 336* @run main/othervm -Djava.security.manager=allow NotificationEmissionTest 437* @run main/othervm -Djava.security.manager=allow NotificationEmissionTest 538*/3940import java.io.File;41import java.util.ArrayList;42import java.util.Collections;43import java.util.HashMap;44import java.util.List;45import java.util.Map;46import javax.management.MBeanServer;47import javax.management.MBeanServerConnection;48import javax.management.MBeanServerFactory;49import javax.management.Notification;50import javax.management.NotificationBroadcasterSupport;51import javax.management.NotificationListener;52import javax.management.ObjectName;53import javax.management.remote.JMXAuthenticator;54import javax.management.remote.JMXConnector;55import javax.management.remote.JMXConnectorFactory;56import javax.management.remote.JMXConnectorServer;57import javax.management.remote.JMXConnectorServerFactory;58import javax.management.remote.JMXPrincipal;59import javax.management.remote.JMXServiceURL;60import javax.security.auth.Subject;6162public class NotificationEmissionTest {6364public class CustomJMXAuthenticator implements JMXAuthenticator {65public Subject authenticate(Object credentials) {66String role = ((String[]) credentials)[0];67echo("Create principal with name = " + role);68return new Subject(true,69Collections.singleton(new JMXPrincipal(role)),70Collections.EMPTY_SET,71Collections.EMPTY_SET);72}73}7475public interface NBMBean {76public void emitNotification(int seqnum, ObjectName name);77}7879public static class NB80extends NotificationBroadcasterSupport81implements NBMBean {82public void emitNotification(int seqnum, ObjectName name) {83if (name == null) {84sendNotification(new Notification("nb", this, seqnum));85} else {86sendNotification(new Notification("nb", name, seqnum));87}88}89}9091public class Listener implements NotificationListener {92public List<Notification> notifs = new ArrayList<Notification>();93public void handleNotification(Notification n, Object h) {94echo("handleNotification:");95echo("\tNotification = " + n);96echo("\tNotification.SeqNum = " + n.getSequenceNumber());97echo("\tHandback = " + h);98notifs.add(n);99}100}101102public int checkNotifs(int size,103List<Notification> received,104List<ObjectName> expected) {105if (received.size() != size) {106echo("Error: expecting " + size + " notifications, got " +107received.size());108return 1;109} else {110for (Notification n : received) {111echo("Received notification: " + n);112if (!n.getType().equals("nb")) {113echo("Notification type must be \"nb\"");114return 1;115}116ObjectName o = (ObjectName) n.getSource();117int index = (int) n.getSequenceNumber();118ObjectName nb = expected.get(index);119if (!o.equals(nb)) {120echo("Notification source must be " + nb);121return 1;122}123}124}125return 0;126}127128public int runTest(int testcase) throws Exception {129echo("\n=-=-= Running testcase " + testcase + " =-=-=");130switch (testcase) {131case 1:132return testNotificationEmissionProperty();133case 2:134return testNotificationEmissionPositive(false);135case 3:136return testNotificationEmissionNegative(false);137case 4:138return testNotificationEmissionPositive(true);139case 5:140return testNotificationEmissionNegative(true);141default:142echo("Invalid testcase");143return 1;144}145}146147public int testNotificationEmissionProperty(boolean exception,148Object propValue)149throws Exception {150try {151testNotificationEmission(propValue);152if (exception) {153echo("Did not get expected exception for value: " + propValue);154return 1;155} else {156echo("Property has been correctly set to value: " + propValue);157}158} catch (Exception e) {159if (exception) {160echo("Got expected exception for value: " + propValue);161echo("Exception: " + e);162} else {163echo("Got unexpected exception for value: " + propValue);164echo("Exception: " + e);165return 1;166}167}168return 0;169}170171public int testNotificationEmissionProperty() throws Exception {172int error = 0;173error += testNotificationEmissionProperty(true, new Boolean(false));174error += testNotificationEmissionProperty(true, new Boolean(true));175error += testNotificationEmissionProperty(true, "dummy");176error += testNotificationEmissionProperty(false, "false");177error += testNotificationEmissionProperty(false, "true");178error += testNotificationEmissionProperty(false, "FALSE");179error += testNotificationEmissionProperty(false, "TRUE");180return error;181}182183public int testNotificationEmissionPositive(boolean prop) throws Exception {184return testNotificationEmission(prop, "true", true, true);185}186187public int testNotificationEmissionNegative(boolean prop) throws Exception {188return testNotificationEmission(prop, "true", true, false);189}190191public int testNotificationEmission(Object propValue) throws Exception {192return testNotificationEmission(true, propValue, false, true);193}194195public int testNotificationEmission(boolean prop,196Object propValue,197boolean sm,198boolean policyPositive)199throws Exception {200201JMXConnectorServer server = null;202JMXConnector client = null;203204// Set policy file205//206String policyFile =207System.getProperty("test.src") + File.separator +208(policyPositive ? "policy.positive" : "policy.negative");209echo("\nSetting policy file " + policyFile);210System.setProperty("java.security.policy", policyFile);211212// Create a new MBeanServer213//214final MBeanServer mbs = MBeanServerFactory.createMBeanServer();215216try {217// Create server environment map218//219final Map<String,Object> env = new HashMap<String,Object>();220env.put("jmx.remote.authenticator", new CustomJMXAuthenticator());221if (prop)222env.put("jmx.remote.x.check.notification.emission", propValue);223224// Create the JMXServiceURL225//226final JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");227228// Create a JMXConnectorServer229//230server = JMXConnectorServerFactory.newJMXConnectorServer(url,231env,232mbs);233234// Start the JMXConnectorServer235//236server.start();237238// Create server environment map239//240final Map<String,Object> cenv = new HashMap<String,Object>();241String[] credentials = new String[] { "role" , "password" };242cenv.put("jmx.remote.credentials", credentials);243244// Create JMXConnector and connect to JMXConnectorServer245//246client = JMXConnectorFactory.connect(server.getAddress(), cenv);247248// Get non-secure MBeanServerConnection249//250final MBeanServerConnection mbsc =251client.getMBeanServerConnection();252253// Create NB MBean254//255ObjectName nb1 = ObjectName.getInstance("domain:type=NB,name=1");256ObjectName nb2 = ObjectName.getInstance("domain:type=NB,name=2");257ObjectName nb3 = ObjectName.getInstance("domain:type=NB,name=3");258mbsc.createMBean(NB.class.getName(), nb1);259mbsc.createMBean(NB.class.getName(), nb2);260mbsc.createMBean(NB.class.getName(), nb3);261262// Add notification listener263//264Listener li = new Listener();265mbsc.addNotificationListener(nb1, li, null, null);266mbsc.addNotificationListener(nb2, li, null, null);267268// Set security manager269//270if (sm) {271echo("Setting SM");272System.setSecurityManager(new SecurityManager());273}274275// Invoke the "sendNotification" method276//277mbsc.invoke(nb1, "emitNotification",278new Object[] {0, null},279new String[] {"int", "javax.management.ObjectName"});280mbsc.invoke(nb2, "emitNotification",281new Object[] {1, null},282new String[] {"int", "javax.management.ObjectName"});283mbsc.invoke(nb2, "emitNotification",284new Object[] {2, nb3},285new String[] {"int", "javax.management.ObjectName"});286287// If the check is effective and we're using policy.negative,288// then we should see the two notifs sent by nb2 (of which one289// has a getSource() that is nb3), but not the notif sent by nb1.290// Otherwise we should see all three notifs. The check is only291// effective if the property jmx.remote.x.check.notification.emission292// is explicitly true and there is a security manager.293int expectedNotifs =294(prop && sm && !policyPositive) ? 2 : 3;295296// Wait for notifications to be emitted297//298long deadline = System.currentTimeMillis() + 2000;299while (li.notifs.size() < expectedNotifs &&300System.currentTimeMillis() < deadline)301Thread.sleep(1);302303// Remove notification listener304//305mbsc.removeNotificationListener(nb1, li);306mbsc.removeNotificationListener(nb2, li);307308int result = 0;309List<ObjectName> sources = new ArrayList<ObjectName>();310sources.add(nb1);311sources.add(nb2);312sources.add(nb3);313314result = checkNotifs(expectedNotifs, li.notifs, sources);315if (result > 0) {316echo("...SecurityManager=" + sm + "; policy=" + policyPositive);317return result;318}319} finally {320// Close the connection321//322if (client != null)323client.close();324325// Stop the connector server326//327if (server != null)328server.stop();329330// Release the MBeanServer331//332if (mbs != null)333MBeanServerFactory.releaseMBeanServer(mbs);334}335336return 0;337}338339private static void echo(String message) {340System.out.println(message);341}342343public static void main(String[] args) throws Exception {344345echo("\n--- Check the emission of notifications " +346"when a Security Manager is installed");347348NotificationEmissionTest net = new NotificationEmissionTest();349350int error = 0;351352error += net.runTest(Integer.parseInt(args[0]));353354if (error > 0) {355final String msg = "\nTest FAILED! Got " + error + " error(s)";356echo(msg);357throw new IllegalArgumentException(msg);358} else {359echo("\nTest PASSED!");360}361}362}363364365