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