Path: blob/master/test/jdk/javax/management/remote/mandatory/notif/NoPermToRemoveTest.java
41155 views
/*1* Copyright (c) 2017, 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 651516126* @summary checks the behaviour of mbeanServerConnection.removeNotificationListener27* operation when there is a exception thrown during removal28* @modules java.management29* @run main/othervm -Djava.security.manager=allow NoPermToRemoveTest30*/3132import java.lang.management.ManagementFactory;33import java.security.AllPermission;34import java.security.CodeSource;35import java.security.Permission;36import java.security.PermissionCollection;37import java.security.Permissions;38import java.security.Policy;39import java.security.ProtectionDomain;40import java.util.concurrent.Semaphore;41import java.util.concurrent.TimeUnit;42import java.util.concurrent.atomic.AtomicInteger;43import javax.management.ListenerNotFoundException;44import javax.management.MBeanPermission;45import javax.management.MBeanServer;46import javax.management.MBeanServerConnection;47import javax.management.Notification;48import javax.management.NotificationBroadcasterSupport;49import javax.management.NotificationFilter;50import javax.management.NotificationListener;51import javax.management.ObjectName;52import javax.management.remote.JMXConnector;53import javax.management.remote.JMXConnectorFactory;54import javax.management.remote.JMXConnectorServer;55import javax.management.remote.JMXConnectorServerFactory;56import javax.management.remote.JMXServiceURL;5758public class NoPermToRemoveTest {59public static void main(String[] args) throws Exception {60Policy.setPolicy(new NoRemovePolicy());61System.setSecurityManager(new SecurityManager());6263JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///");64MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();65ObjectName name = new ObjectName("foo:type=Sender");66mbs.registerMBean(new Sender(), name);67JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(68url, null, mbs);69cs.start();70try {71JMXServiceURL addr = cs.getAddress();72JMXConnector cc = JMXConnectorFactory.connect(addr);73MBeanServerConnection mbsc = cc.getMBeanServerConnection();74SnoopListener listener = new SnoopListener();75mbsc.addNotificationListener(name, listener, null, null);76mbsc.invoke(name, "send", null, null);77if (!listener.waitForNotification(60))78throw new Exception("Did not receive expected notification");7980try {81mbsc.removeNotificationListener(name, listener);82throw new Exception("RemoveNL did not get SecurityException");83} catch (SecurityException e) {84System.out.println("removeNL got expected exception: " + e);85}86mbsc.invoke(name, "send", null, null);87if (!listener.waitForNotification(60)) {88int listenerCount =89(Integer) mbsc.getAttribute(name, "ListenerCount");90System.out.println("Listener count: " + listenerCount);91if (listenerCount != 0)92throw new Exception("TEST FAILED");93/* We did not receive the notification, but the MBean still94* has a listener coming from the connector server, which95* means the connector server still thinks there is a96* listener. If we retained the listener after the failing97* removeNL that would be OK, and if the listener were98* dropped by both client and server that would be OK too,99* but the inconsistency is not OK.100*/101}102cc.close();103} finally {104cs.stop();105}106}107108private static class SnoopListener implements NotificationListener {109private Semaphore sema = new Semaphore(0);110111public void handleNotification(Notification notification, Object handback) {112System.out.println("Listener got: " + notification);113sema.release();114}115116boolean waitForNotification(int seconds) throws InterruptedException {117return sema.tryAcquire(seconds, TimeUnit.SECONDS);118}119}120121private static class NoRemovePolicy extends Policy {122public PermissionCollection getPermissions(CodeSource codesource) {123PermissionCollection pc = new Permissions();124pc.add(new AllPermission());125return pc;126}127128public void refresh() {129}130131public boolean implies(ProtectionDomain domain, Permission permission) {132if (!(permission instanceof MBeanPermission))133return true;134MBeanPermission jmxp = (MBeanPermission) permission;135if (jmxp.getActions().contains("removeNotificationListener")) {136System.out.println("DENIED");137return false;138}139return true;140}141}142143public static interface SenderMBean {144public void send();145public int getListenerCount();146}147148public static class Sender extends NotificationBroadcasterSupport149implements SenderMBean {150private AtomicInteger listenerCount = new AtomicInteger();151152public void send() {153System.out.println("Sending notif");154sendNotification(new Notification("type", this, 0L));155}156157public synchronized int getListenerCount() {158return listenerCount.get();159}160161public void removeNotificationListener(162NotificationListener listener,163NotificationFilter filter,164Object handback) throws ListenerNotFoundException {165System.out.println("Sender.removeNL(3)");166super.removeNotificationListener(listener, filter, handback);167listenerCount.decrementAndGet();168}169170public void addNotificationListener(171NotificationListener listener,172NotificationFilter filter,173Object handback) {174System.out.println("Sender.addNL(3)");175super.addNotificationListener(listener, filter, handback);176listenerCount.incrementAndGet();177}178179public void removeNotificationListener(NotificationListener listener)180throws ListenerNotFoundException {181System.out.println("Sender.removeNL(1)");182super.removeNotificationListener(listener);183listenerCount.decrementAndGet();184}185}186}187188189