src/share/jaxws_classes/com/sun/xml/internal/ws/server/MonitorBase.java

Fri, 14 Feb 2014 11:13:45 +0100

author
mkos
date
Fri, 14 Feb 2014 11:13:45 +0100
changeset 515
6cd506508147
parent 368
0989ad8c0860
child 637
9c07ef4934dd
permissions
-rw-r--r--

8026188: Enhance envelope factory
Summary: Avoiding caching data initialized via TCCL in static context; fix also reviewed by Alexander Fomin
Reviewed-by: ahgross, mgrebac, skoivu

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

mercurial