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;
getInteger()55         public Integer getInteger() {
56             setPrincipal();
57             return 0;
58         }
getDouble()59         public Double getDouble() {
60             setPrincipal();
61             return 0.0;
62         }
getString()63         public String getString() {
64             setPrincipal();
65             return "";
66         }
setPrincipal()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 {
getInteger()76         public Integer getInteger();
getDouble()77         public Double getDouble();
getString()78         public String getString();
79     }
80 
main(String args[])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 
testPrincipals(ObservedObject[] monitored, ObjectName[] monitorNames, Monitor[] monitor, String[] principals)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 
echo(String message)172     private static void echo(String message) {
173         System.out.println(message);
174     }
175 }
176