1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/server/MonitorBase.java Tue Mar 06 16:09:35 2012 -0800 1.3 @@ -0,0 +1,434 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.xml.internal.ws.server; 1.30 + 1.31 +import com.sun.istack.internal.NotNull; 1.32 +import com.sun.istack.internal.Nullable; 1.33 +import com.sun.xml.internal.ws.api.EndpointAddress; 1.34 +import com.sun.xml.internal.ws.api.config.management.policy.ManagedClientAssertion; 1.35 +import com.sun.xml.internal.ws.api.config.management.policy.ManagedServiceAssertion; 1.36 +import com.sun.xml.internal.ws.api.config.management.policy.ManagementAssertion.Setting; 1.37 +import com.sun.xml.internal.ws.api.server.BoundEndpoint; 1.38 +import com.sun.xml.internal.ws.api.server.Container; 1.39 +import com.sun.xml.internal.ws.api.server.Module; 1.40 +import com.sun.xml.internal.ws.api.server.WSEndpoint; 1.41 +import com.sun.xml.internal.ws.client.Stub; 1.42 +import com.sun.org.glassfish.external.amx.AMXGlassfish; 1.43 +import com.sun.org.glassfish.gmbal.Description; 1.44 +import com.sun.org.glassfish.gmbal.InheritedAttribute; 1.45 +import com.sun.org.glassfish.gmbal.InheritedAttributes; 1.46 +import com.sun.org.glassfish.gmbal.ManagedData; 1.47 +import com.sun.org.glassfish.gmbal.ManagedObjectManager; 1.48 +import com.sun.org.glassfish.gmbal.ManagedObjectManagerFactory; 1.49 +import java.io.IOException; 1.50 +import java.lang.reflect.*; 1.51 +import java.net.URL; 1.52 +import java.util.List; 1.53 +import java.util.logging.Level; 1.54 +import java.util.logging.Logger; 1.55 +import javax.management.ObjectName; 1.56 +import javax.xml.namespace.QName; 1.57 + 1.58 +// BEGIN IMPORTS FOR RewritingMOM 1.59 +import java.util.ResourceBundle ; 1.60 +import java.io.Closeable ; 1.61 +import java.lang.reflect.AnnotatedElement ; 1.62 +import java.lang.annotation.Annotation ; 1.63 +import javax.management.ObjectName ; 1.64 +import javax.management.MBeanServer ; 1.65 +import com.sun.org.glassfish.gmbal.AMXClient; 1.66 +import com.sun.org.glassfish.gmbal.GmbalMBean; 1.67 +// END IMPORTS FOR RewritingMOM 1.68 + 1.69 +/** 1.70 + * @author Harold Carr 1.71 + */ 1.72 +public abstract class MonitorBase { 1.73 + 1.74 + private static final Logger logger = Logger.getLogger( 1.75 + com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".monitoring"); 1.76 + 1.77 + /** 1.78 + * Endpoint monitoring is ON by default. 1.79 + * 1.80 + * prop | no assert | assert/no mon | assert/mon off | assert/mon on 1.81 + * ------------------------------------------------------------------- 1.82 + * not set | on | on | off | on 1.83 + * false | off | off | off | off 1.84 + * true | on | on | off | on 1.85 + */ 1.86 + @NotNull public ManagedObjectManager createManagedObjectManager(final WSEndpoint endpoint) { 1.87 + // serviceName + portName identifies the managed objects under it. 1.88 + // There can be multiple services in the container. 1.89 + // The same serviceName+portName can live in different apps at 1.90 + // different endpoint addresses. 1.91 + // 1.92 + // In general, monitoring will add -N, where N is unique integer, 1.93 + // in case of collisions. 1.94 + // 1.95 + // The endpoint address would be unique, but we do not know 1.96 + // the endpoint address until the first request comes in, 1.97 + // which is after monitoring is setup. 1.98 + 1.99 + String rootName = 1.100 + endpoint.getServiceName().getLocalPart() 1.101 + + "-" 1.102 + + endpoint.getPortName().getLocalPart(); 1.103 + 1.104 + if (rootName.equals("-")) { 1.105 + rootName = "provider"; 1.106 + } 1.107 + 1.108 + // contextPath is not always available 1.109 + final String contextPath = getContextPath(endpoint); 1.110 + if (contextPath != null) { 1.111 + rootName = contextPath + "-" + rootName; 1.112 + } 1.113 + 1.114 + final ManagedServiceAssertion assertion = 1.115 + ManagedServiceAssertion.getAssertion(endpoint); 1.116 + if (assertion != null) { 1.117 + final String id = assertion.getId(); 1.118 + if (id != null) { 1.119 + rootName = id; 1.120 + } 1.121 + if (assertion.monitoringAttribute() == Setting.OFF) { 1.122 + return disabled("This endpoint", rootName); 1.123 + } 1.124 + } 1.125 + 1.126 + if (endpointMonitoring.equals(Setting.OFF)) { 1.127 + return disabled("Global endpoint", rootName); 1.128 + } 1.129 + return createMOMLoop(rootName, 0); 1.130 + } 1.131 + 1.132 + private String getContextPath(final WSEndpoint endpoint) { 1.133 + try { 1.134 + Container container = endpoint.getContainer(); 1.135 + Method getSPI = 1.136 + container.getClass().getDeclaredMethod("getSPI", Class.class); 1.137 + getSPI.setAccessible(true); 1.138 + Class servletContextClass = 1.139 + Class.forName("javax.servlet.ServletContext"); 1.140 + Object servletContext = 1.141 + getSPI.invoke(container, servletContextClass); 1.142 + if (servletContext != null) { 1.143 + Method getContextPath = servletContextClass.getDeclaredMethod("getContextPath"); 1.144 + getContextPath.setAccessible(true); 1.145 + return (String) getContextPath.invoke(servletContext); 1.146 + } 1.147 + return null; 1.148 + } catch (Throwable t) { 1.149 + logger.log(Level.FINEST, "getContextPath", t); 1.150 + } 1.151 + return null; 1.152 + } 1.153 + 1.154 + /** 1.155 + * Client monitoring is OFF by default because there is 1.156 + * no standard stub.close() method. Therefore people do 1.157 + * not typically close a stub when they are done with it 1.158 + * (even though the RI does provide a .close). 1.159 + * <pre> 1.160 + * prop | no assert | assert/no mon | assert/mon off | assert/mon on 1.161 + * ------------------------------------------------------------------- 1.162 + * not set | off | off | off | on 1.163 + * false | off | off | off | off 1.164 + * true | on | on | off | on 1.165 + * </pre> 1.166 + */ 1.167 + @NotNull public ManagedObjectManager createManagedObjectManager(final Stub stub) { 1.168 + EndpointAddress ea = stub.requestContext.getEndpointAddress(); 1.169 + if (ea == null) { 1.170 + return ManagedObjectManagerFactory.createNOOP(); 1.171 + } 1.172 + 1.173 + String rootName = ea.toString(); 1.174 + 1.175 + final ManagedClientAssertion assertion = 1.176 + ManagedClientAssertion.getAssertion(stub.getPortInfo()); 1.177 + if (assertion != null) { 1.178 + final String id = assertion.getId(); 1.179 + if (id != null) { 1.180 + rootName = id; 1.181 + } 1.182 + if (assertion.monitoringAttribute() == Setting.OFF) { 1.183 + return disabled("This client", rootName); 1.184 + } else if (assertion.monitoringAttribute() == Setting.ON && 1.185 + clientMonitoring != Setting.OFF) { 1.186 + return createMOMLoop(rootName, 0); 1.187 + } 1.188 + } 1.189 + 1.190 + if (clientMonitoring == Setting.NOT_SET || 1.191 + clientMonitoring == Setting.OFF) 1.192 + { 1.193 + return disabled("Global client", rootName); 1.194 + } 1.195 + return createMOMLoop(rootName, 0); 1.196 + } 1.197 + 1.198 + @NotNull private ManagedObjectManager disabled(final String x, final String rootName) { 1.199 + final String msg = x + " monitoring disabled. " + rootName + " will not be monitored"; 1.200 + logger.log(Level.CONFIG, msg); 1.201 + return ManagedObjectManagerFactory.createNOOP(); 1.202 + } 1.203 + 1.204 + private @NotNull ManagedObjectManager createMOMLoop(final String rootName, final int unique) { 1.205 + final boolean isFederated = AMXGlassfish.getGlassfishVersion() != null; 1.206 + ManagedObjectManager mom = createMOM(isFederated); 1.207 + mom = initMOM(mom); 1.208 + mom = createRoot(mom, rootName, unique); 1.209 + return mom; 1.210 + } 1.211 + 1.212 + private @NotNull ManagedObjectManager createMOM(final boolean isFederated) { 1.213 + try { 1.214 + return new RewritingMOM(isFederated ? 1.215 + ManagedObjectManagerFactory.createFederated( 1.216 + AMXGlassfish.DEFAULT.serverMon(AMXGlassfish.DEFAULT.dasName())) 1.217 + : 1.218 + ManagedObjectManagerFactory.createStandalone("com.sun.metro")); 1.219 + } catch (Throwable t) { 1.220 + if (isFederated) { 1.221 + logger.log(Level.CONFIG, "Problem while attempting to federate with GlassFish AMX monitoring. Trying standalone.", t); 1.222 + return createMOM(false); 1.223 + } else { 1.224 + logger.log(Level.WARNING, "Ignoring exception - starting up without monitoring", t); 1.225 + return ManagedObjectManagerFactory.createNOOP(); 1.226 + } 1.227 + } 1.228 + } 1.229 + 1.230 + private @NotNull ManagedObjectManager initMOM(final ManagedObjectManager mom) { 1.231 + try { 1.232 + if (typelibDebug != -1) { 1.233 + mom.setTypelibDebug(typelibDebug); 1.234 + } 1.235 + if (registrationDebug.equals("FINE")) { 1.236 + mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.FINE); 1.237 + } else if (registrationDebug.equals("NORMAL")) { 1.238 + mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.NORMAL); 1.239 + } else { 1.240 + mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.NONE); 1.241 + } 1.242 + 1.243 + mom.setRuntimeDebug(runtimeDebug); 1.244 + 1.245 + // Instead of GMBAL throwing an exception and logging 1.246 + // duplicate name, just have it return null. 1.247 + mom.suppressDuplicateRootReport(true); 1.248 + 1.249 + mom.stripPrefix( 1.250 + "com.sun.xml.internal.ws.server", 1.251 + "com.sun.xml.internal.ws.rx.rm.runtime.sequence"); 1.252 + 1.253 + // Add annotations to a standard class 1.254 + mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(ManagedData.class)); 1.255 + mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(Description.class)); 1.256 + mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(InheritedAttributes.class)); 1.257 + 1.258 + // Defer so we can register "this" as root from 1.259 + // within constructor. 1.260 + mom.suspendJMXRegistration(); 1.261 + 1.262 + } catch (Throwable t) { 1.263 + try { 1.264 + mom.close(); 1.265 + } catch (IOException e) { 1.266 + logger.log(Level.CONFIG, "Ignoring exception caught when closing unused ManagedObjectManager", e); 1.267 + } 1.268 + logger.log(Level.WARNING, "Ignoring exception - starting up without monitoring", t); 1.269 + return ManagedObjectManagerFactory.createNOOP(); 1.270 + } 1.271 + return mom; 1.272 + } 1.273 + 1.274 + private ManagedObjectManager createRoot(final ManagedObjectManager mom, final String rootName, int unique) { 1.275 + final String name = rootName + (unique == 0 ? "" : "-" + String.valueOf(unique)); 1.276 + try { 1.277 + final Object ignored = mom.createRoot(this, name); 1.278 + if (ignored != null) { 1.279 + ObjectName ignoredName = mom.getObjectName(mom.getRoot()); 1.280 + // The name is null when the MOM is a NOOP. 1.281 + if (ignoredName != null) { 1.282 + logger.log(Level.INFO, "Metro monitoring rootname successfully set to: " + ignoredName); 1.283 + } 1.284 + return mom; 1.285 + } 1.286 + try { 1.287 + mom.close(); 1.288 + } catch (IOException e) { 1.289 + logger.log(Level.CONFIG, "Ignoring exception caught when closing unused ManagedObjectManager", e); 1.290 + } 1.291 + final String basemsg ="Duplicate Metro monitoring rootname: " + name + " : "; 1.292 + if (unique > maxUniqueEndpointRootNameRetries) { 1.293 + final String msg = basemsg + "Giving up."; 1.294 + logger.log(Level.INFO, msg); 1.295 + return ManagedObjectManagerFactory.createNOOP(); 1.296 + } 1.297 + final String msg = basemsg + "Will try to make unique"; 1.298 + logger.log(Level.CONFIG, msg); 1.299 + return createMOMLoop(rootName, ++unique); 1.300 + } catch (Throwable t) { 1.301 + logger.log(Level.WARNING, "Error while creating monitoring root with name: " + rootName, t); 1.302 + return ManagedObjectManagerFactory.createNOOP(); 1.303 + } 1.304 + } 1.305 + 1.306 + public static void closeMOM(ManagedObjectManager mom) { 1.307 + try { 1.308 + final ObjectName name = mom.getObjectName(mom.getRoot()); 1.309 + // The name is null when the MOM is a NOOP. 1.310 + if (name != null) { 1.311 + logger.log(Level.INFO, "Closing Metro monitoring root: " + name); 1.312 + } 1.313 + mom.close(); 1.314 + } catch (java.io.IOException e) { 1.315 + logger.log(Level.WARNING, "Ignoring error when closing Managed Object Manager", e); 1.316 + } 1.317 + } 1.318 + 1.319 + private static Setting clientMonitoring = Setting.NOT_SET; 1.320 + private static Setting endpointMonitoring = Setting.NOT_SET; 1.321 + private static int typelibDebug = -1; 1.322 + private static String registrationDebug = "NONE"; 1.323 + private static boolean runtimeDebug = false; 1.324 + private static int maxUniqueEndpointRootNameRetries = 100; 1.325 + private static final String monitorProperty = "com.sun.xml.internal.ws.monitoring."; 1.326 + 1.327 + private static Setting propertyToSetting(String propName) { 1.328 + String s = System.getProperty(propName); 1.329 + if (s == null) { 1.330 + return Setting.NOT_SET; 1.331 + } 1.332 + s = s.toLowerCase(); 1.333 + if (s.equals("false") || s.equals("off")) { 1.334 + return Setting.OFF; 1.335 + } else if (s.equals("true") || s.equals("on")) { 1.336 + return Setting.ON; 1.337 + } 1.338 + return Setting.NOT_SET; 1.339 + } 1.340 + 1.341 + static { 1.342 + try { 1.343 + endpointMonitoring = propertyToSetting(monitorProperty + "endpoint"); 1.344 + 1.345 + clientMonitoring = propertyToSetting(monitorProperty + "client"); 1.346 + 1.347 + Integer i = Integer.getInteger(monitorProperty + "typelibDebug"); 1.348 + if (i != null) { 1.349 + typelibDebug = i; 1.350 + } 1.351 + 1.352 + String s = System.getProperty(monitorProperty + "registrationDebug"); 1.353 + if (s != null) { 1.354 + registrationDebug = s.toUpperCase(); 1.355 + } 1.356 + 1.357 + s = System.getProperty(monitorProperty + "runtimeDebug"); 1.358 + if (s != null && s.toLowerCase().equals("true")) { 1.359 + runtimeDebug = true; 1.360 + } 1.361 + 1.362 + i = Integer.getInteger(monitorProperty + "maxUniqueEndpointRootNameRetries"); 1.363 + if (i != null) { 1.364 + maxUniqueEndpointRootNameRetries = i; 1.365 + } 1.366 + } catch (Exception e) { 1.367 + logger.log(Level.WARNING, "Error while reading monitoring properties", e); 1.368 + } 1.369 + } 1.370 +} 1.371 + 1.372 + 1.373 +// This enables us to annotate the WebServiceFeature class even thought 1.374 +// we can't explicitly put the annotations in the class itself. 1.375 +@ManagedData 1.376 +@Description("WebServiceFeature") 1.377 +@InheritedAttributes({ 1.378 + @InheritedAttribute(methodName="getID", description="unique id for this feature"), 1.379 + @InheritedAttribute(methodName="isEnabled", description="true if this feature is enabled") 1.380 +}) 1.381 +interface DummyWebServiceFeature {} 1.382 + 1.383 +class RewritingMOM implements ManagedObjectManager 1.384 +{ 1.385 + private final ManagedObjectManager mom; 1.386 + 1.387 + private final static String gmbalQuotingCharsRegex = "\n|\\|\"|\\*|\\?|:|=|,"; 1.388 + private final static String jmxQuotingCharsRegex = ",|=|:|\""; 1.389 + private final static String replacementChar = "-"; 1.390 + 1.391 + RewritingMOM(final ManagedObjectManager mom) { this.mom = mom; } 1.392 + 1.393 + private String rewrite(final String x) { 1.394 + return x.replaceAll(gmbalQuotingCharsRegex, replacementChar); 1.395 + } 1.396 + 1.397 + // The interface 1.398 + 1.399 + public void suspendJMXRegistration() { mom.suspendJMXRegistration(); } 1.400 + public void resumeJMXRegistration() { mom.resumeJMXRegistration(); } 1.401 + public GmbalMBean createRoot() { return mom.createRoot(); } 1.402 + public GmbalMBean createRoot(Object root) { return mom.createRoot(root); } 1.403 + public GmbalMBean createRoot(Object root, String name) { 1.404 + return mom.createRoot(root, rewrite(name)); 1.405 + } 1.406 + public Object getRoot() { return mom.getRoot(); } 1.407 + public GmbalMBean register(Object parent, Object obj, String name) { 1.408 + return mom.register(parent, obj, rewrite(name)); 1.409 + } 1.410 + public GmbalMBean register(Object parent, Object obj) { return mom.register(parent, obj);} 1.411 + public GmbalMBean registerAtRoot(Object obj, String name) { 1.412 + return mom.registerAtRoot(obj, rewrite(name)); 1.413 + } 1.414 + public GmbalMBean registerAtRoot(Object obj) { return mom.registerAtRoot(obj); } 1.415 + public void unregister(Object obj) { mom.unregister(obj); } 1.416 + public ObjectName getObjectName(Object obj) { return mom.getObjectName(obj); } 1.417 + public AMXClient getAMXClient(Object obj) { return mom.getAMXClient(obj); } 1.418 + public Object getObject(ObjectName oname) { return mom.getObject(oname); } 1.419 + public void stripPrefix(String... str) { mom.stripPrefix(str); } 1.420 + public void stripPackagePrefix() { mom.stripPackagePrefix(); } 1.421 + public String getDomain() { return mom.getDomain(); } 1.422 + public void setMBeanServer(MBeanServer server){mom.setMBeanServer(server); } 1.423 + public MBeanServer getMBeanServer() { return mom.getMBeanServer(); } 1.424 + public void setResourceBundle(ResourceBundle rb) { mom.setResourceBundle(rb); } 1.425 + public ResourceBundle getResourceBundle() { return mom.getResourceBundle(); } 1.426 + public void addAnnotation(AnnotatedElement element, Annotation annotation) { mom.addAnnotation(element, annotation); } 1.427 + public void setRegistrationDebug(RegistrationDebugLevel level) { mom.setRegistrationDebug(level); } 1.428 + public void setRuntimeDebug(boolean flag) { mom.setRuntimeDebug(flag); } 1.429 + public void setTypelibDebug(int level) { mom.setTypelibDebug(level); } 1.430 + public String dumpSkeleton(Object obj) { return mom.dumpSkeleton(obj); } 1.431 + public void suppressDuplicateRootReport(boolean suppressReport) { mom.suppressDuplicateRootReport(suppressReport); } 1.432 + public void close() throws IOException { mom.close(); } 1.433 + public void setJMXRegistrationDebug(boolean x) { mom.setJMXRegistrationDebug(x); } 1.434 + public boolean isManagedObject(Object x) { return mom.isManagedObject(x); } 1.435 +} 1.436 + 1.437 +// End of file.