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 6222826
  27  * @summary Test that each thread in the thread pool runs
  28  *          in the context of the monitor.start() caller.
  29  * @author Luis-Miguel Alventosa
  30  *
  31  * @run clean ThreadPoolAccTest
  32  * @run build ThreadPoolAccTest
  33  * @run main ThreadPoolAccTest
  34  */
  35 
  36 import java.security.AccessController;
  37 import java.security.PrivilegedAction;
  38 import java.util.Date;
  39 import java.util.Set;
  40 import javax.management.MBeanServer;
  41 import javax.management.MBeanServerFactory;
  42 import javax.management.ObjectName;
  43 import javax.management.monitor.CounterMonitor;
  44 import javax.management.monitor.GaugeMonitor;
  45 import javax.management.monitor.Monitor;
  46 import javax.management.monitor.StringMonitor;
  47 import javax.management.remote.JMXPrincipal;
  48 import javax.security.auth.Subject;
  49 
  50 public class ThreadPoolAccTest {
  51 
  52     // MBean class
  53     public static class ObservedObject implements ObservedObjectMBean {
  54         public volatile String principal;
  55         public Integer getInteger() {
  56             setPrincipal();
  57             return 0;
  58         }
  59         public Double getDouble() {
  60             setPrincipal();
  61             return 0.0;
  62         }
  63         public String getString() {
  64             setPrincipal();
  65             return "";
  66         }
  67         private void setPrincipal() {
  68             Subject subject = Subject.getSubject(AccessController.getContext());
  69             Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
  70             principal = principals.iterator().next().getName();
  71         }
  72     }
  73 
  74     // MBean interface
  75     public interface ObservedObjectMBean {
  76         public Integer getInteger();
  77         public Double getDouble();
  78         public String getString();
  79     }
  80 
  81     public static void main (String args[]) throws Exception {
  82 
  83         ObjectName[] mbeanNames = new ObjectName[6];
  84         ObservedObject[] monitored = new ObservedObject[6];
  85         ObjectName[] monitorNames = new ObjectName[6];
  86         Monitor[] monitor = new Monitor[6];
  87         String[] principals = { "role1", "role2" };
  88         String[] attributes = { "Integer", "Double", "String" };
  89 
  90         try {
  91             echo(">>> CREATE MBeanServer");
  92             MBeanServer server = MBeanServerFactory.newMBeanServer();
  93 
  94             for (int i = 0; i < 6; i++) {
  95                 mbeanNames[i] =
  96                     new ObjectName(":type=ObservedObject,instance=" + i);
  97                 monitored[i] = new ObservedObject();
  98                 echo(">>> CREATE ObservedObject = " + mbeanNames[i].toString());
  99                 server.registerMBean(monitored[i], mbeanNames[i]);
 100 
 101                 switch (i) {
 102                     case 0:
 103                     case 3:
 104                         monitorNames[i] =
 105                             new ObjectName(":type=CounterMonitor,instance=" + i);
 106                         monitor[i] = new CounterMonitor();
 107                         break;
 108                     case 1:
 109                     case 4:
 110                         monitorNames[i] =
 111                             new ObjectName(":type=GaugeMonitor,instance=" + i);
 112                         monitor[i] = new GaugeMonitor();
 113                         break;
 114                     case 2:
 115                     case 5:
 116                         monitorNames[i] =
 117                             new ObjectName(":type=StringMonitor,instance=" + i);
 118                         monitor[i] = new StringMonitor();
 119                         break;
 120                 }
 121 
 122                 echo(">>> CREATE Monitor = " + monitorNames[i].toString());
 123                 server.registerMBean(monitor[i], monitorNames[i]);
 124                 monitor[i].addObservedObject(mbeanNames[i]);
 125                 monitor[i].setObservedAttribute(attributes[i % 3]);
 126                 monitor[i].setGranularityPeriod(500);
 127                 final Monitor m = monitor[i];
 128                 Subject subject = new Subject();
 129                 echo(">>> RUN Principal = " + principals[i / 3]);
 130                 subject.getPrincipals().add(new JMXPrincipal(principals[i / 3]));
 131                 PrivilegedAction<Void> action = new PrivilegedAction<Void>() {
 132                     public Void run() {
 133                         m.start();
 134                         return null;
 135                     }
 136                 };
 137                 Subject.doAs(subject, action);
 138             }
 139 
 140             while(!testPrincipals(monitored, monitorNames, monitor, principals));
 141 
 142         } finally {
 143             for (int i = 0; i < 6; i++)
 144                 if (monitor[i] != null)
 145                     monitor[i].stop();
 146         }
 147     }
 148 
 149     private static boolean testPrincipals(ObservedObject[] monitored, ObjectName[] monitorNames,
 150             Monitor[] monitor, String[] principals) throws Exception {
 151         for (int i = 0; i < 6; i++) {
 152             String principal =  monitored[i].principal;
 153             String expected = principals[i / 3];
 154             if (principal == null) {
 155                 echo("Task not submitted " + new Date() + ". RETRY");
 156                 return false;
 157             }
 158             echo(">>> Monitor = " + monitorNames[i]);
 159             echo(">>> ObservedObject = " + monitor[i].getObservedObject());
 160             echo(">>> ObservedAttribute = " + monitor[i].getObservedAttribute());
 161             echo(">>> Principal = " + principal);
 162 
 163             if (expected.equals(principal)) {
 164                 echo("\tOK: Got Expected principal");
 165             } else {
 166                 throw new Exception("Unexpected principal. Got: " + principal + " Expected: " + expected);
 167             }
 168         }
 169         return true;
 170     }
 171 
 172     private static void echo(String message) {
 173         System.out.println(message);
 174     }
 175 }