jdk/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java
changeset 26208 a581ee8890b1
parent 5506 202f599c92aa
child 30376 2ccf2cf7ea48
equal deleted inserted replaced
26207:a02f6165d5be 26208:a581ee8890b1
     1 /*
     1 /*
     2  * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    35 import java.util.ArrayList;
    35 import java.util.ArrayList;
    36 import java.util.Collections;
    36 import java.util.Collections;
    37 import java.util.HashMap;
    37 import java.util.HashMap;
    38 import java.util.List;
    38 import java.util.List;
    39 import java.util.Map;
    39 import java.util.Map;
       
    40 import java.util.concurrent.CopyOnWriteArrayList;
       
    41 import java.util.concurrent.Semaphore;
    40 import javax.management.MBeanServer;
    42 import javax.management.MBeanServer;
    41 import javax.management.MBeanServerConnection;
    43 import javax.management.MBeanServerConnection;
    42 import javax.management.MBeanServerFactory;
    44 import javax.management.MBeanServerFactory;
    43 import javax.management.Notification;
    45 import javax.management.Notification;
    44 import javax.management.NotificationBroadcasterSupport;
    46 import javax.management.NotificationBroadcasterSupport;
    54 import javax.security.auth.Subject;
    56 import javax.security.auth.Subject;
    55 
    57 
    56 public class NotificationAccessControllerTest {
    58 public class NotificationAccessControllerTest {
    57 
    59 
    58     public class NAC implements NotificationAccessController {
    60     public class NAC implements NotificationAccessController {
    59         private boolean throwException;
    61         private final boolean throwException;
    60         public NAC(boolean throwException) {
    62         public NAC(boolean throwException) {
    61             this.throwException = throwException;
    63             this.throwException = throwException;
    62         }
    64         }
       
    65 
       
    66         @Override
    63         public void addNotificationListener(
    67         public void addNotificationListener(
    64             String connectionId,
    68             String connectionId,
    65             ObjectName name,
    69             ObjectName name,
    66             Subject subject)
    70             Subject subject)
    67             throws SecurityException {
    71             throws SecurityException {
    71             echo("\tsubject: " +
    75             echo("\tsubject: " +
    72                  (subject == null ? null : subject.getPrincipals()));
    76                  (subject == null ? null : subject.getPrincipals()));
    73             if (throwException)
    77             if (throwException)
    74                 if (name.getCanonicalName().equals("domain:name=1,type=NB")
    78                 if (name.getCanonicalName().equals("domain:name=1,type=NB")
    75                     &&
    79                     &&
       
    80                     subject != null
       
    81                     &&
    76                     subject.getPrincipals().contains(new JMXPrincipal("role")))
    82                     subject.getPrincipals().contains(new JMXPrincipal("role")))
    77                     throw new SecurityException();
    83                     throw new SecurityException();
    78         }
    84         }
       
    85 
       
    86         @Override
    79         public void removeNotificationListener(
    87         public void removeNotificationListener(
    80             String connectionId,
    88             String connectionId,
    81             ObjectName name,
    89             ObjectName name,
    82             Subject subject)
    90             Subject subject)
    83             throws SecurityException {
    91             throws SecurityException {
    87             echo("\tsubject: " +
    95             echo("\tsubject: " +
    88                  (subject == null ? null : subject.getPrincipals()));
    96                  (subject == null ? null : subject.getPrincipals()));
    89             if (throwException)
    97             if (throwException)
    90                 if (name.getCanonicalName().equals("domain:name=2,type=NB")
    98                 if (name.getCanonicalName().equals("domain:name=2,type=NB")
    91                     &&
    99                     &&
       
   100                     subject != null
       
   101                     &&
    92                     subject.getPrincipals().contains(new JMXPrincipal("role")))
   102                     subject.getPrincipals().contains(new JMXPrincipal("role")))
    93                     throw new SecurityException();
   103                     throw new SecurityException();
    94         }
   104         }
       
   105 
       
   106         @Override
    95         public void fetchNotification(
   107         public void fetchNotification(
    96             String connectionId,
   108             String connectionId,
    97             ObjectName name,
   109             ObjectName name,
    98             Notification notification,
   110             Notification notification,
    99             Subject subject)
   111             Subject subject)
   103             echo("\tname: " +  name);
   115             echo("\tname: " +  name);
   104             echo("\tnotification: " +  notification);
   116             echo("\tnotification: " +  notification);
   105             echo("\tsubject: " +
   117             echo("\tsubject: " +
   106                  (subject == null ? null : subject.getPrincipals()));
   118                  (subject == null ? null : subject.getPrincipals()));
   107             if (!throwException)
   119             if (!throwException)
   108                 if (name.getCanonicalName().equals("domain:name=2,type=NB") &&
   120                 if (name.getCanonicalName().equals("domain:name=2,type=NB")
       
   121                     &&
       
   122                     subject != null
       
   123                     &&
   109                     subject.getPrincipals().contains(new JMXPrincipal("role")))
   124                     subject.getPrincipals().contains(new JMXPrincipal("role")))
   110                     throw new SecurityException();
   125                     throw new SecurityException();
   111         }
   126         }
   112     }
   127     }
   113 
   128 
   114     public class CustomJMXAuthenticator implements JMXAuthenticator {
   129     public class CustomJMXAuthenticator implements JMXAuthenticator {
       
   130         @Override
   115         public Subject authenticate(Object credentials) {
   131         public Subject authenticate(Object credentials) {
   116             String role = ((String[]) credentials)[0];
   132             String role = ((String[]) credentials)[0];
   117             echo("\nCreate principal with name = " + role);
   133             echo("\nCreate principal with name = " + role);
   118             return new Subject(true,
   134             return new Subject(true,
   119                                Collections.singleton(new JMXPrincipal(role)),
   135                                Collections.singleton(new JMXPrincipal(role)),
   127     }
   143     }
   128 
   144 
   129     public static class NB
   145     public static class NB
   130         extends NotificationBroadcasterSupport
   146         extends NotificationBroadcasterSupport
   131         implements NBMBean {
   147         implements NBMBean {
       
   148         @Override
   132         public void emitNotification(int seqnum, ObjectName name) {
   149         public void emitNotification(int seqnum, ObjectName name) {
   133             if (name == null) {
   150             if (name == null) {
   134                 sendNotification(new Notification("nb", this, seqnum));
   151                 sendNotification(new Notification("nb", this, seqnum));
   135             } else {
   152             } else {
   136                 sendNotification(new Notification("nb", name, seqnum));
   153                 sendNotification(new Notification("nb", name, seqnum));
   137             }
   154             }
   138         }
   155         }
   139     }
   156     }
   140 
   157 
   141     public class Listener implements NotificationListener {
   158     public class Listener implements NotificationListener {
   142         public List<Notification> notifs = new ArrayList<Notification>();
   159         public final List<Notification> notifs = new CopyOnWriteArrayList<>();
       
   160 
       
   161         private final Semaphore s;
       
   162         public Listener(Semaphore s) {
       
   163             this.s = s;
       
   164         }
       
   165         @Override
   143         public void handleNotification(Notification n, Object h) {
   166         public void handleNotification(Notification n, Object h) {
   144             echo("handleNotification:");
   167             echo("handleNotification:");
   145             echo("\tNotification = " + n);
   168             echo("\tNotification = " + n);
   146             echo("\tNotification.SeqNum = " + n.getSequenceNumber());
   169             echo("\tNotification.SeqNum = " + n.getSequenceNumber());
   147             echo("\tHandback = " + h);
   170             echo("\tHandback = " + h);
   148             notifs.add(n);
   171             notifs.add(n);
       
   172             s.release();
   149         }
   173         }
   150     }
   174     }
   151 
   175 
   152     /**
   176     /**
   153      * Check received notifications
   177      * Check received notifications
   190              ": fetch ")) + "=-=-=");
   214              ": fetch ")) + "=-=-=");
   191 
   215 
   192         JMXConnectorServer server = null;
   216         JMXConnectorServer server = null;
   193         JMXConnector client = null;
   217         JMXConnector client = null;
   194 
   218 
       
   219         /*
       
   220         * (!enableChecks)
       
   221         * - List must contain three notifs from sources nb1, nb2 and nb3
       
   222         * (enableChecks && !throwException)
       
   223         * - List must contain one notif from source nb1
       
   224         * (enableChecks && throwException)
       
   225         * - List must contain two notifs from sources nb2 and nb3
       
   226         */
       
   227         final int expected_notifs =
       
   228             (!enableChecks ? 3 : (throwException ? 2 : 1));
       
   229 
   195         // Create a new MBeanServer
   230         // Create a new MBeanServer
   196         //
   231         //
   197         final MBeanServer mbs = MBeanServerFactory.createMBeanServer();
   232         final MBeanServer mbs = MBeanServerFactory.createMBeanServer();
   198 
   233 
   199         try {
   234         try {
   200             // Create server environment map
   235             // Create server environment map
   201             //
   236             //
   202             final Map<String,Object> env = new HashMap<String,Object>();
   237             final Map<String,Object> env = new HashMap<>();
   203             env.put("jmx.remote.authenticator", new CustomJMXAuthenticator());
   238             env.put("jmx.remote.authenticator", new CustomJMXAuthenticator());
   204             if (enableChecks) {
   239             if (enableChecks) {
   205                 env.put("com.sun.jmx.remote.notification.access.controller",
   240                 env.put("com.sun.jmx.remote.notification.access.controller",
   206                         new NAC(throwException));
   241                         new NAC(throwException));
   207             }
   242             }
   220             //
   255             //
   221             server.start();
   256             server.start();
   222 
   257 
   223             // Create server environment map
   258             // Create server environment map
   224             //
   259             //
   225             final Map<String,Object> cenv = new HashMap<String,Object>();
   260             final Map<String,Object> cenv = new HashMap<>();
   226             String[] credentials = new String[] { "role" , "password" };
   261             String[] credentials = new String[] { "role" , "password" };
   227             cenv.put("jmx.remote.credentials", credentials);
   262             cenv.put("jmx.remote.credentials", credentials);
   228 
   263 
   229             // Create JMXConnector and connect to JMXConnectorServer
   264             // Create JMXConnector and connect to JMXConnectorServer
   230             //
   265             //
   244             mbsc.createMBean(NB.class.getName(), nb2);
   279             mbsc.createMBean(NB.class.getName(), nb2);
   245             mbsc.createMBean(NB.class.getName(), nb3);
   280             mbsc.createMBean(NB.class.getName(), nb3);
   246 
   281 
   247             // Add notification listener
   282             // Add notification listener
   248             //
   283             //
   249             Listener li = new Listener();
   284             Semaphore s = new Semaphore(0);
       
   285 
       
   286             Listener li = new Listener(s);
   250             try {
   287             try {
   251                 mbsc.addNotificationListener(nb1, li, null, null);
   288                 mbsc.addNotificationListener(nb1, li, null, null);
   252                 if (enableChecks && throwException) {
   289                 if (enableChecks && throwException) {
   253                     echo("Didn't get expected exception");
   290                     echo("Didn't get expected exception");
   254                     return 1;
   291                     return 1;
   261                     return 1;
   298                     return 1;
   262                 }
   299                 }
   263             }
   300             }
   264             mbsc.addNotificationListener(nb2, li, null, null);
   301             mbsc.addNotificationListener(nb2, li, null, null);
   265 
   302 
       
   303             System.out.println("\n+++ Expecting to receive " + expected_notifs +
       
   304                                " notification" + (expected_notifs > 1 ? "s" : "") +
       
   305                                " +++");
   266             // Invoke the "sendNotification" method
   306             // Invoke the "sendNotification" method
   267             //
   307             //
   268             mbsc.invoke(nb1, "emitNotification",
   308             mbsc.invoke(nb1, "emitNotification",
   269                 new Object[] {0, null},
   309                 new Object[] {0, null},
   270                 new String[] {"int", "javax.management.ObjectName"});
   310                 new String[] {"int", "javax.management.ObjectName"});
   275                 new Object[] {2, nb3},
   315                 new Object[] {2, nb3},
   276                 new String[] {"int", "javax.management.ObjectName"});
   316                 new String[] {"int", "javax.management.ObjectName"});
   277 
   317 
   278             // Wait for notifications to be emitted
   318             // Wait for notifications to be emitted
   279             //
   319             //
   280             Thread.sleep(2000);
   320             s.acquire(expected_notifs);
   281 
   321 
   282             // Remove notification listener
   322             // Remove notification listener
   283             //
   323             //
   284             if (!throwException)
   324             if (!throwException)
   285                 mbsc.removeNotificationListener(nb1, li);
   325                 mbsc.removeNotificationListener(nb1, li);
   301             int result = 0;
   341             int result = 0;
   302             List<ObjectName> sources = new ArrayList();
   342             List<ObjectName> sources = new ArrayList();
   303             sources.add(nb1);
   343             sources.add(nb1);
   304             sources.add(nb2);
   344             sources.add(nb2);
   305             sources.add(nb3);
   345             sources.add(nb3);
   306             if (!enableChecks) {
   346             result = checkNotifs(expected_notifs, li.notifs, sources);
   307                 // List must contain three notifs from sources nb1, nb2 and nb3
       
   308                 //
       
   309                 result = checkNotifs(3, li.notifs, sources);
       
   310             }
       
   311             if (enableChecks && !throwException) {
       
   312                 // List must contain one notif from source nb1
       
   313                 //
       
   314                 result = checkNotifs(1, li.notifs, sources);
       
   315             }
       
   316             if (enableChecks && throwException) {
       
   317                 // List must contain two notifs from sources nb2 and nb3
       
   318                 //
       
   319                 result = checkNotifs(2, li.notifs, sources);
       
   320             }
       
   321             if (result > 0) {
   347             if (result > 0) {
   322                 return result;
   348                 return result;
   323             }
   349             }
   324         } catch (Exception e) {
   350         } catch (Exception e) {
   325             echo("Failed to perform operation: " + e);
   351             echo("Failed to perform operation: " + e);