Sat, 07 Nov 2020 10:30:02 +0800
Added tag mips-jdk8u275-b01 for changeset fdbe50121f48
1 /*
2 * Copyright (c) 1997, 2012, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.xml.internal.ws.server;
28 import com.sun.istack.internal.NotNull;
29 import com.sun.xml.internal.ws.api.EndpointAddress;
30 import com.sun.xml.internal.ws.api.config.management.policy.ManagedClientAssertion;
31 import com.sun.xml.internal.ws.api.config.management.policy.ManagedServiceAssertion;
32 import com.sun.xml.internal.ws.api.config.management.policy.ManagementAssertion.Setting;
33 import com.sun.xml.internal.ws.api.server.Container;
34 import com.sun.xml.internal.ws.api.server.WSEndpoint;
35 import com.sun.xml.internal.ws.client.Stub;
36 import com.sun.org.glassfish.external.amx.AMXGlassfish;
37 import com.sun.org.glassfish.gmbal.Description;
38 import com.sun.org.glassfish.gmbal.InheritedAttribute;
39 import com.sun.org.glassfish.gmbal.InheritedAttributes;
40 import com.sun.org.glassfish.gmbal.ManagedData;
41 import com.sun.org.glassfish.gmbal.ManagedObjectManager;
42 import com.sun.org.glassfish.gmbal.ManagedObjectManagerFactory;
43 import java.io.IOException;
44 import java.lang.reflect.*;
45 import java.util.logging.Level;
46 import java.util.logging.Logger;
48 // BEGIN IMPORTS FOR RewritingMOM
49 import java.util.ResourceBundle ;
50 import java.lang.reflect.AnnotatedElement ;
51 import java.lang.annotation.Annotation ;
52 import javax.management.ObjectName ;
53 import javax.management.MBeanServer ;
54 import com.sun.org.glassfish.gmbal.AMXClient;
55 import com.sun.org.glassfish.gmbal.GmbalMBean;
56 // END IMPORTS FOR RewritingMOM
58 /**
59 * @author Harold Carr
60 */
61 public abstract class MonitorBase {
63 private static final Logger logger = Logger.getLogger(
64 com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".monitoring");
66 /**
67 * Endpoint monitoring is ON by default.
68 *
69 * prop | no assert | assert/no mon | assert/mon off | assert/mon on
70 * -------------------------------------------------------------------
71 * not set | on | on | off | on
72 * false | off | off | off | off
73 * true | on | on | off | on
74 */
75 @NotNull public ManagedObjectManager createManagedObjectManager(final WSEndpoint endpoint) {
76 // serviceName + portName identifies the managed objects under it.
77 // There can be multiple services in the container.
78 // The same serviceName+portName can live in different apps at
79 // different endpoint addresses.
80 //
81 // In general, monitoring will add -N, where N is unique integer,
82 // in case of collisions.
83 //
84 // The endpoint address would be unique, but we do not know
85 // the endpoint address until the first request comes in,
86 // which is after monitoring is setup.
88 String rootName =
89 endpoint.getServiceName().getLocalPart()
90 + "-"
91 + endpoint.getPortName().getLocalPart();
93 if (rootName.equals("-")) {
94 rootName = "provider";
95 }
97 // contextPath is not always available
98 final String contextPath = getContextPath(endpoint);
99 if (contextPath != null) {
100 rootName = contextPath + "-" + rootName;
101 }
103 final ManagedServiceAssertion assertion =
104 ManagedServiceAssertion.getAssertion(endpoint);
105 if (assertion != null) {
106 final String id = assertion.getId();
107 if (id != null) {
108 rootName = id;
109 }
110 if (assertion.monitoringAttribute() == Setting.OFF) {
111 return disabled("This endpoint", rootName);
112 }
113 }
115 if (endpointMonitoring.equals(Setting.OFF)) {
116 return disabled("Global endpoint", rootName);
117 }
118 return createMOMLoop(rootName, 0);
119 }
121 private String getContextPath(final WSEndpoint endpoint) {
122 try {
123 Container container = endpoint.getContainer();
124 Method getSPI =
125 container.getClass().getDeclaredMethod("getSPI", Class.class);
126 getSPI.setAccessible(true);
127 Class servletContextClass =
128 Class.forName("javax.servlet.ServletContext");
129 Object servletContext =
130 getSPI.invoke(container, servletContextClass);
131 if (servletContext != null) {
132 Method getContextPath = servletContextClass.getDeclaredMethod("getContextPath");
133 getContextPath.setAccessible(true);
134 return (String) getContextPath.invoke(servletContext);
135 }
136 return null;
137 } catch (Throwable t) {
138 logger.log(Level.FINEST, "getContextPath", t);
139 }
140 return null;
141 }
143 /**
144 * Client monitoring is OFF by default because there is
145 * no standard stub.close() method. Therefore people do
146 * not typically close a stub when they are done with it
147 * (even though the RI does provide a .close).
148 * <pre>
149 * prop | no assert | assert/no mon | assert/mon off | assert/mon on
150 * -------------------------------------------------------------------
151 * not set | off | off | off | on
152 * false | off | off | off | off
153 * true | on | on | off | on
154 * </pre>
155 */
156 @NotNull public ManagedObjectManager createManagedObjectManager(final Stub stub) {
157 EndpointAddress ea = stub.requestContext.getEndpointAddress();
158 if (ea == null) {
159 return ManagedObjectManagerFactory.createNOOP();
160 }
162 String rootName = ea.toString();
164 final ManagedClientAssertion assertion =
165 ManagedClientAssertion.getAssertion(stub.getPortInfo());
166 if (assertion != null) {
167 final String id = assertion.getId();
168 if (id != null) {
169 rootName = id;
170 }
171 if (assertion.monitoringAttribute() == Setting.OFF) {
172 return disabled("This client", rootName);
173 } else if (assertion.monitoringAttribute() == Setting.ON &&
174 clientMonitoring != Setting.OFF) {
175 return createMOMLoop(rootName, 0);
176 }
177 }
179 if (clientMonitoring == Setting.NOT_SET ||
180 clientMonitoring == Setting.OFF)
181 {
182 return disabled("Global client", rootName);
183 }
184 return createMOMLoop(rootName, 0);
185 }
187 @NotNull private ManagedObjectManager disabled(final String x, final String rootName) {
188 final String msg = x + " monitoring disabled. " + rootName + " will not be monitored";
189 logger.log(Level.CONFIG, msg);
190 return ManagedObjectManagerFactory.createNOOP();
191 }
193 private @NotNull ManagedObjectManager createMOMLoop(final String rootName, final int unique) {
194 final boolean isFederated = AMXGlassfish.getGlassfishVersion() != null;
195 ManagedObjectManager mom = createMOM(isFederated);
196 mom = initMOM(mom);
197 mom = createRoot(mom, rootName, unique);
198 return mom;
199 }
201 private @NotNull ManagedObjectManager createMOM(final boolean isFederated) {
202 try {
203 return new RewritingMOM(isFederated ?
204 ManagedObjectManagerFactory.createFederated(
205 AMXGlassfish.DEFAULT.serverMon(AMXGlassfish.DEFAULT.dasName()))
206 :
207 ManagedObjectManagerFactory.createStandalone("com.sun.metro"));
208 } catch (Throwable t) {
209 if (isFederated) {
210 logger.log(Level.CONFIG, "Problem while attempting to federate with GlassFish AMX monitoring. Trying standalone.", t);
211 return createMOM(false);
212 } else {
213 logger.log(Level.WARNING, "Ignoring exception - starting up without monitoring", t);
214 return ManagedObjectManagerFactory.createNOOP();
215 }
216 }
217 }
219 private @NotNull ManagedObjectManager initMOM(final ManagedObjectManager mom) {
220 try {
221 if (typelibDebug != -1) {
222 mom.setTypelibDebug(typelibDebug);
223 }
224 if (registrationDebug.equals("FINE")) {
225 mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.FINE);
226 } else if (registrationDebug.equals("NORMAL")) {
227 mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.NORMAL);
228 } else {
229 mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.NONE);
230 }
232 mom.setRuntimeDebug(runtimeDebug);
234 // Instead of GMBAL throwing an exception and logging
235 // duplicate name, just have it return null.
236 mom.suppressDuplicateRootReport(true);
238 mom.stripPrefix(
239 "com.sun.xml.internal.ws.server",
240 "com.sun.xml.internal.ws.rx.rm.runtime.sequence");
242 // Add annotations to a standard class
243 mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(ManagedData.class));
244 mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(Description.class));
245 mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(InheritedAttributes.class));
247 // Defer so we can register "this" as root from
248 // within constructor.
249 mom.suspendJMXRegistration();
251 } catch (Throwable t) {
252 try {
253 mom.close();
254 } catch (IOException e) {
255 logger.log(Level.CONFIG, "Ignoring exception caught when closing unused ManagedObjectManager", e);
256 }
257 logger.log(Level.WARNING, "Ignoring exception - starting up without monitoring", t);
258 return ManagedObjectManagerFactory.createNOOP();
259 }
260 return mom;
261 }
263 private ManagedObjectManager createRoot(final ManagedObjectManager mom, final String rootName, int unique) {
264 final String name = rootName + (unique == 0 ? "" : "-" + String.valueOf(unique));
265 try {
266 final Object ignored = mom.createRoot(this, name);
267 if (ignored != null) {
268 ObjectName ignoredName = mom.getObjectName(mom.getRoot());
269 // The name is null when the MOM is a NOOP.
270 if (ignoredName != null) {
271 logger.log(Level.INFO, "Metro monitoring rootname successfully set to: {0}", ignoredName);
272 }
273 return mom;
274 }
275 try {
276 mom.close();
277 } catch (IOException e) {
278 logger.log(Level.CONFIG, "Ignoring exception caught when closing unused ManagedObjectManager", e);
279 }
280 final String basemsg ="Duplicate Metro monitoring rootname: " + name + " : ";
281 if (unique > maxUniqueEndpointRootNameRetries) {
282 final String msg = basemsg + "Giving up.";
283 logger.log(Level.INFO, msg);
284 return ManagedObjectManagerFactory.createNOOP();
285 }
286 final String msg = basemsg + "Will try to make unique";
287 logger.log(Level.CONFIG, msg);
288 return createMOMLoop(rootName, ++unique);
289 } catch (Throwable t) {
290 logger.log(Level.WARNING, "Error while creating monitoring root with name: " + rootName, t);
291 return ManagedObjectManagerFactory.createNOOP();
292 }
293 }
295 private static Setting clientMonitoring = Setting.NOT_SET;
296 private static Setting endpointMonitoring = Setting.NOT_SET;
297 private static int typelibDebug = -1;
298 private static String registrationDebug = "NONE";
299 private static boolean runtimeDebug = false;
300 private static int maxUniqueEndpointRootNameRetries = 100;
301 private static final String monitorProperty = "com.sun.xml.internal.ws.monitoring.";
303 private static Setting propertyToSetting(String propName) {
304 String s = System.getProperty(propName);
305 if (s == null) {
306 return Setting.NOT_SET;
307 }
308 s = s.toLowerCase();
309 if (s.equals("false") || s.equals("off")) {
310 return Setting.OFF;
311 } else if (s.equals("true") || s.equals("on")) {
312 return Setting.ON;
313 }
314 return Setting.NOT_SET;
315 }
317 static {
318 try {
319 endpointMonitoring = propertyToSetting(monitorProperty + "endpoint");
321 clientMonitoring = propertyToSetting(monitorProperty + "client");
323 Integer i = Integer.getInteger(monitorProperty + "typelibDebug");
324 if (i != null) {
325 typelibDebug = i;
326 }
328 String s = System.getProperty(monitorProperty + "registrationDebug");
329 if (s != null) {
330 registrationDebug = s.toUpperCase();
331 }
333 s = System.getProperty(monitorProperty + "runtimeDebug");
334 if (s != null && s.toLowerCase().equals("true")) {
335 runtimeDebug = true;
336 }
338 i = Integer.getInteger(monitorProperty + "maxUniqueEndpointRootNameRetries");
339 if (i != null) {
340 maxUniqueEndpointRootNameRetries = i;
341 }
342 } catch (Exception e) {
343 logger.log(Level.WARNING, "Error while reading monitoring properties", e);
344 }
345 }
346 }
349 // This enables us to annotate the WebServiceFeature class even thought
350 // we can't explicitly put the annotations in the class itself.
351 @ManagedData
352 @Description("WebServiceFeature")
353 @InheritedAttributes({
354 @InheritedAttribute(methodName="getID", description="unique id for this feature"),
355 @InheritedAttribute(methodName="isEnabled", description="true if this feature is enabled")
356 })
357 interface DummyWebServiceFeature {}
359 class RewritingMOM implements ManagedObjectManager
360 {
361 private final ManagedObjectManager mom;
363 private final static String gmbalQuotingCharsRegex = "\n|\\|\"|\\*|\\?|:|=|,";
364 private final static String replacementChar = "-";
366 RewritingMOM(final ManagedObjectManager mom) { this.mom = mom; }
368 private String rewrite(final String x) {
369 return x.replaceAll(gmbalQuotingCharsRegex, replacementChar);
370 }
372 // The interface
374 @Override public void suspendJMXRegistration() { mom.suspendJMXRegistration(); }
375 @Override public void resumeJMXRegistration() { mom.resumeJMXRegistration(); }
376 @Override public GmbalMBean createRoot() { return mom.createRoot(); }
377 @Override public GmbalMBean createRoot(Object root) { return mom.createRoot(root); }
378 @Override public GmbalMBean createRoot(Object root, String name) {
379 return mom.createRoot(root, rewrite(name));
380 }
381 @Override public Object getRoot() { return mom.getRoot(); }
382 @Override public GmbalMBean register(Object parent, Object obj, String name) {
383 return mom.register(parent, obj, rewrite(name));
384 }
385 @Override public GmbalMBean register(Object parent, Object obj) { return mom.register(parent, obj);}
386 @Override public GmbalMBean registerAtRoot(Object obj, String name) {
387 return mom.registerAtRoot(obj, rewrite(name));
388 }
389 @Override public GmbalMBean registerAtRoot(Object obj) { return mom.registerAtRoot(obj); }
390 @Override public void unregister(Object obj) { mom.unregister(obj); }
391 @Override public ObjectName getObjectName(Object obj) { return mom.getObjectName(obj); }
392 @Override public AMXClient getAMXClient(Object obj) { return mom.getAMXClient(obj); }
393 @Override public Object getObject(ObjectName oname) { return mom.getObject(oname); }
394 @Override public void stripPrefix(String... str) { mom.stripPrefix(str); }
395 @Override public void stripPackagePrefix() { mom.stripPackagePrefix(); }
396 @Override public String getDomain() { return mom.getDomain(); }
397 @Override public void setMBeanServer(MBeanServer server){mom.setMBeanServer(server); }
398 @Override public MBeanServer getMBeanServer() { return mom.getMBeanServer(); }
399 @Override public void setResourceBundle(ResourceBundle rb) { mom.setResourceBundle(rb); }
400 @Override public ResourceBundle getResourceBundle() { return mom.getResourceBundle(); }
401 @Override public void addAnnotation(AnnotatedElement element, Annotation annotation) { mom.addAnnotation(element, annotation); }
402 @Override public void setRegistrationDebug(RegistrationDebugLevel level) { mom.setRegistrationDebug(level); }
403 @Override public void setRuntimeDebug(boolean flag) { mom.setRuntimeDebug(flag); }
404 @Override public void setTypelibDebug(int level) { mom.setTypelibDebug(level); }
405 @Override public String dumpSkeleton(Object obj) { return mom.dumpSkeleton(obj); }
406 @Override public void suppressDuplicateRootReport(boolean suppressReport) { mom.suppressDuplicateRootReport(suppressReport); }
407 @Override public void close() throws IOException { mom.close(); }
408 @Override public void setJMXRegistrationDebug(boolean x) { mom.setJMXRegistrationDebug(x); }
409 @Override public boolean isManagedObject(Object x) { return mom.isManagedObject(x); }
410 }
412 // End of file.