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

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 368
0989ad8c0860
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

     1 /*
     2  * Copyright (c) 1997, 2011, 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.istack.internal.Nullable;
    30 import com.sun.xml.internal.ws.api.EndpointAddress;
    31 import com.sun.xml.internal.ws.api.config.management.policy.ManagedClientAssertion;
    32 import com.sun.xml.internal.ws.api.config.management.policy.ManagedServiceAssertion;
    33 import com.sun.xml.internal.ws.api.config.management.policy.ManagementAssertion.Setting;
    34 import com.sun.xml.internal.ws.api.server.BoundEndpoint;
    35 import com.sun.xml.internal.ws.api.server.Container;
    36 import com.sun.xml.internal.ws.api.server.Module;
    37 import com.sun.xml.internal.ws.api.server.WSEndpoint;
    38 import com.sun.xml.internal.ws.client.Stub;
    39 import com.sun.org.glassfish.external.amx.AMXGlassfish;
    40 import com.sun.org.glassfish.gmbal.Description;
    41 import com.sun.org.glassfish.gmbal.InheritedAttribute;
    42 import com.sun.org.glassfish.gmbal.InheritedAttributes;
    43 import com.sun.org.glassfish.gmbal.ManagedData;
    44 import com.sun.org.glassfish.gmbal.ManagedObjectManager;
    45 import com.sun.org.glassfish.gmbal.ManagedObjectManagerFactory;
    46 import java.io.IOException;
    47 import java.lang.reflect.*;
    48 import java.net.URL;
    49 import java.util.List;
    50 import java.util.logging.Level;
    51 import java.util.logging.Logger;
    52 import javax.management.ObjectName;
    53 import javax.xml.namespace.QName;
    55 // BEGIN IMPORTS FOR RewritingMOM
    56 import java.util.ResourceBundle ;
    57 import java.io.Closeable ;
    58 import java.lang.reflect.AnnotatedElement ;
    59 import java.lang.annotation.Annotation ;
    60 import javax.management.ObjectName ;
    61 import javax.management.MBeanServer ;
    62 import com.sun.org.glassfish.gmbal.AMXClient;
    63 import com.sun.org.glassfish.gmbal.GmbalMBean;
    64 // END IMPORTS FOR RewritingMOM
    66 /**
    67  * @author Harold Carr
    68  */
    69 public abstract class MonitorBase {
    71     private static final Logger logger = Logger.getLogger(
    72         com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".monitoring");
    74     /**
    75      * Endpoint monitoring is ON by default.
    76      *
    77      * prop    |  no assert | assert/no mon | assert/mon off | assert/mon on
    78      * -------------------------------------------------------------------
    79      * not set |    on      |      on       |     off        |     on
    80      * false   |    off     |      off      |     off        |     off
    81      * true    |    on      |      on       |     off        |     on
    82      */
    83     @NotNull public ManagedObjectManager createManagedObjectManager(final WSEndpoint endpoint) {
    84         // serviceName + portName identifies the managed objects under it.
    85         // There can be multiple services in the container.
    86         // The same serviceName+portName can live in different apps at
    87         // different endpoint addresses.
    88         //
    89         // In general, monitoring will add -N, where N is unique integer,
    90         // in case of collisions.
    91         //
    92         // The endpoint address would be unique, but we do not know
    93         // the endpoint address until the first request comes in,
    94         // which is after monitoring is setup.
    96         String rootName =
    97             endpoint.getServiceName().getLocalPart()
    98             + "-"
    99             + endpoint.getPortName().getLocalPart();
   101         if (rootName.equals("-")) {
   102             rootName = "provider";
   103         }
   105         // contextPath is not always available
   106         final String contextPath = getContextPath(endpoint);
   107         if (contextPath != null) {
   108             rootName = contextPath + "-" + rootName;
   109         }
   111         final ManagedServiceAssertion assertion =
   112             ManagedServiceAssertion.getAssertion(endpoint);
   113         if (assertion != null) {
   114             final String id = assertion.getId();
   115             if (id != null) {
   116                 rootName = id;
   117             }
   118             if (assertion.monitoringAttribute() == Setting.OFF) {
   119                 return disabled("This endpoint", rootName);
   120             }
   121         }
   123         if (endpointMonitoring.equals(Setting.OFF)) {
   124             return disabled("Global endpoint", rootName);
   125         }
   126         return createMOMLoop(rootName, 0);
   127     }
   129     private String getContextPath(final WSEndpoint endpoint) {
   130         try {
   131             Container container = endpoint.getContainer();
   132             Method getSPI =
   133                 container.getClass().getDeclaredMethod("getSPI", Class.class);
   134             getSPI.setAccessible(true);
   135             Class servletContextClass =
   136                 Class.forName("javax.servlet.ServletContext");
   137             Object servletContext =
   138                 getSPI.invoke(container, servletContextClass);
   139             if (servletContext != null) {
   140                 Method getContextPath = servletContextClass.getDeclaredMethod("getContextPath");
   141                 getContextPath.setAccessible(true);
   142                 return (String) getContextPath.invoke(servletContext);
   143             }
   144             return null;
   145         } catch (Throwable t) {
   146             logger.log(Level.FINEST, "getContextPath", t);
   147         }
   148         return null;
   149     }
   151     /**
   152      * Client monitoring is OFF by default because there is
   153      * no standard stub.close() method.  Therefore people do
   154      * not typically close a stub when they are done with it
   155      * (even though the RI does provide a .close).
   156      * <pre>
   157      * prop    |  no assert | assert/no mon | assert/mon off | assert/mon on
   158      * -------------------------------------------------------------------
   159      * not set |    off     |      off      |     off        |     on
   160      * false   |    off     |      off      |     off        |     off
   161      * true    |    on      |      on       |     off        |     on
   162      * </pre>
   163     */
   164     @NotNull public ManagedObjectManager createManagedObjectManager(final Stub stub) {
   165         EndpointAddress ea = stub.requestContext.getEndpointAddress();
   166         if (ea == null) {
   167             return ManagedObjectManagerFactory.createNOOP();
   168         }
   170         String rootName = ea.toString();
   172         final ManagedClientAssertion assertion =
   173             ManagedClientAssertion.getAssertion(stub.getPortInfo());
   174         if (assertion != null) {
   175             final String id = assertion.getId();
   176             if (id != null) {
   177                 rootName = id;
   178             }
   179             if (assertion.monitoringAttribute() == Setting.OFF) {
   180                 return disabled("This client", rootName);
   181             } else if (assertion.monitoringAttribute() == Setting.ON &&
   182                        clientMonitoring != Setting.OFF) {
   183                 return createMOMLoop(rootName, 0);
   184             }
   185         }
   187         if (clientMonitoring == Setting.NOT_SET ||
   188             clientMonitoring == Setting.OFF)
   189         {
   190             return disabled("Global client", rootName);
   191         }
   192         return createMOMLoop(rootName, 0);
   193     }
   195     @NotNull private ManagedObjectManager disabled(final String x, final String rootName) {
   196         final String msg = x + " monitoring disabled. " + rootName + " will not be monitored";
   197         logger.log(Level.CONFIG, msg);
   198         return ManagedObjectManagerFactory.createNOOP();
   199     }
   201     private @NotNull ManagedObjectManager createMOMLoop(final String rootName, final int unique) {
   202         final boolean isFederated = AMXGlassfish.getGlassfishVersion() != null;
   203         ManagedObjectManager mom = createMOM(isFederated);
   204         mom = initMOM(mom);
   205         mom = createRoot(mom, rootName, unique);
   206         return mom;
   207     }
   209     private @NotNull ManagedObjectManager createMOM(final boolean isFederated) {
   210         try {
   211             return new RewritingMOM(isFederated ?
   212                 ManagedObjectManagerFactory.createFederated(
   213                     AMXGlassfish.DEFAULT.serverMon(AMXGlassfish.DEFAULT.dasName()))
   214                 :
   215                 ManagedObjectManagerFactory.createStandalone("com.sun.metro"));
   216         } catch (Throwable t) {
   217             if (isFederated) {
   218                 logger.log(Level.CONFIG, "Problem while attempting to federate with GlassFish AMX monitoring.  Trying standalone.", t);
   219                 return createMOM(false);
   220             } else {
   221                 logger.log(Level.WARNING, "Ignoring exception - starting up without monitoring", t);
   222                 return ManagedObjectManagerFactory.createNOOP();
   223             }
   224         }
   225     }
   227     private @NotNull ManagedObjectManager initMOM(final ManagedObjectManager mom) {
   228         try {
   229             if (typelibDebug != -1) {
   230                 mom.setTypelibDebug(typelibDebug);
   231             }
   232             if (registrationDebug.equals("FINE")) {
   233                 mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.FINE);
   234             } else if (registrationDebug.equals("NORMAL")) {
   235                 mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.NORMAL);
   236             } else {
   237                 mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.NONE);
   238             }
   240             mom.setRuntimeDebug(runtimeDebug);
   242             // Instead of GMBAL throwing an exception and logging
   243             // duplicate name, just have it return null.
   244             mom.suppressDuplicateRootReport(true);
   246             mom.stripPrefix(
   247                 "com.sun.xml.internal.ws.server",
   248                 "com.sun.xml.internal.ws.rx.rm.runtime.sequence");
   250             // Add annotations to a standard class
   251             mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(ManagedData.class));
   252             mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(Description.class));
   253             mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(InheritedAttributes.class));
   255             // Defer so we can register "this" as root from
   256             // within constructor.
   257             mom.suspendJMXRegistration();
   259         } catch (Throwable t) {
   260             try {
   261                 mom.close();
   262             } catch (IOException e) {
   263                 logger.log(Level.CONFIG, "Ignoring exception caught when closing unused ManagedObjectManager", e);
   264             }
   265             logger.log(Level.WARNING, "Ignoring exception - starting up without monitoring", t);
   266             return ManagedObjectManagerFactory.createNOOP();
   267         }
   268         return mom;
   269     }
   271     private ManagedObjectManager createRoot(final ManagedObjectManager mom, final String rootName, int unique) {
   272         final String name = rootName + (unique == 0 ? "" : "-" + String.valueOf(unique));
   273         try {
   274             final Object ignored = mom.createRoot(this, name);
   275             if (ignored != null) {
   276                 ObjectName ignoredName = mom.getObjectName(mom.getRoot());
   277                 // The name is null when the MOM is a NOOP.
   278                 if (ignoredName != null) {
   279                     logger.log(Level.INFO, "Metro monitoring rootname successfully set to: " + ignoredName);
   280                 }
   281                 return mom;
   282             }
   283             try {
   284                 mom.close();
   285             } catch (IOException e) {
   286                 logger.log(Level.CONFIG, "Ignoring exception caught when closing unused ManagedObjectManager", e);
   287             }
   288             final String basemsg ="Duplicate Metro monitoring rootname: " + name + " : ";
   289             if (unique > maxUniqueEndpointRootNameRetries) {
   290                 final String msg = basemsg + "Giving up.";
   291                 logger.log(Level.INFO, msg);
   292                 return ManagedObjectManagerFactory.createNOOP();
   293             }
   294             final String msg = basemsg + "Will try to make unique";
   295             logger.log(Level.CONFIG, msg);
   296             return createMOMLoop(rootName, ++unique);
   297         } catch (Throwable t) {
   298             logger.log(Level.WARNING, "Error while creating monitoring root with name: " + rootName, t);
   299             return ManagedObjectManagerFactory.createNOOP();
   300         }
   301     }
   303     public static void closeMOM(ManagedObjectManager mom) {
   304         try {
   305             final ObjectName name = mom.getObjectName(mom.getRoot());
   306             // The name is null when the MOM is a NOOP.
   307             if (name != null) {
   308                 logger.log(Level.INFO, "Closing Metro monitoring root: " + name);
   309             }
   310             mom.close();
   311         } catch (java.io.IOException e) {
   312             logger.log(Level.WARNING, "Ignoring error when closing Managed Object Manager", e);
   313         }
   314     }
   316     private static Setting clientMonitoring          = Setting.NOT_SET;
   317     private static Setting endpointMonitoring        = Setting.NOT_SET;
   318     private static int     typelibDebug                     = -1;
   319     private static String  registrationDebug                = "NONE";
   320     private static boolean runtimeDebug                     = false;
   321     private static int     maxUniqueEndpointRootNameRetries = 100;
   322     private static final String monitorProperty = "com.sun.xml.internal.ws.monitoring.";
   324     private static Setting propertyToSetting(String propName) {
   325         String s = System.getProperty(propName);
   326         if (s == null) {
   327             return Setting.NOT_SET;
   328         }
   329         s = s.toLowerCase();
   330         if (s.equals("false") || s.equals("off")) {
   331             return Setting.OFF;
   332         } else if (s.equals("true") || s.equals("on")) {
   333             return Setting.ON;
   334         }
   335         return Setting.NOT_SET;
   336     }
   338     static {
   339         try {
   340             endpointMonitoring = propertyToSetting(monitorProperty + "endpoint");
   342             clientMonitoring = propertyToSetting(monitorProperty + "client");
   344             Integer i = Integer.getInteger(monitorProperty + "typelibDebug");
   345             if (i != null) {
   346                 typelibDebug = i;
   347             }
   349             String s = System.getProperty(monitorProperty + "registrationDebug");
   350             if (s != null) {
   351                 registrationDebug = s.toUpperCase();
   352             }
   354             s = System.getProperty(monitorProperty + "runtimeDebug");
   355             if (s != null && s.toLowerCase().equals("true")) {
   356                 runtimeDebug = true;
   357             }
   359             i = Integer.getInteger(monitorProperty + "maxUniqueEndpointRootNameRetries");
   360             if (i != null) {
   361                 maxUniqueEndpointRootNameRetries = i;
   362             }
   363         } catch (Exception e) {
   364             logger.log(Level.WARNING, "Error while reading monitoring properties", e);
   365         }
   366     }
   367 }
   370 // This enables us to annotate the WebServiceFeature class even thought
   371 // we can't explicitly put the annotations in the class itself.
   372 @ManagedData
   373 @Description("WebServiceFeature")
   374 @InheritedAttributes({
   375         @InheritedAttribute(methodName="getID", description="unique id for this feature"),
   376         @InheritedAttribute(methodName="isEnabled", description="true if this feature is enabled")
   377 })
   378 interface DummyWebServiceFeature {}
   380 class RewritingMOM implements ManagedObjectManager
   381 {
   382     private final ManagedObjectManager mom;
   384     private final static String gmbalQuotingCharsRegex = "\n|\\|\"|\\*|\\?|:|=|,";
   385     private final static String jmxQuotingCharsRegex   = ",|=|:|\"";
   386     private final static String replacementChar        = "-";
   388     RewritingMOM(final ManagedObjectManager mom) { this.mom = mom; }
   390     private String rewrite(final String x) {
   391         return x.replaceAll(gmbalQuotingCharsRegex, replacementChar);
   392     }
   394     // The interface
   396     public void suspendJMXRegistration() { mom.suspendJMXRegistration(); }
   397     public void resumeJMXRegistration()  { mom.resumeJMXRegistration(); }
   398     public GmbalMBean createRoot()       { return mom.createRoot(); }
   399     public GmbalMBean createRoot(Object root) { return mom.createRoot(root); }
   400     public GmbalMBean createRoot(Object root, String name) {
   401         return mom.createRoot(root, rewrite(name));
   402     }
   403     public Object getRoot() { return mom.getRoot(); }
   404     public GmbalMBean register(Object parent, Object obj, String name) {
   405         return mom.register(parent, obj, rewrite(name));
   406     }
   407     public GmbalMBean register(Object parent, Object obj) { return mom.register(parent, obj);}
   408     public GmbalMBean registerAtRoot(Object obj, String name) {
   409         return mom.registerAtRoot(obj, rewrite(name));
   410     }
   411     public GmbalMBean registerAtRoot(Object obj) { return mom.registerAtRoot(obj); }
   412     public void unregister(Object obj)           { mom.unregister(obj); }
   413     public ObjectName getObjectName(Object obj)  { return mom.getObjectName(obj); }
   414     public AMXClient getAMXClient(Object obj)    { return mom.getAMXClient(obj); }
   415     public Object getObject(ObjectName oname)    { return mom.getObject(oname); }
   416     public void stripPrefix(String... str)       { mom.stripPrefix(str); }
   417     public void stripPackagePrefix()             { mom.stripPackagePrefix(); }
   418     public String getDomain()                    { return mom.getDomain(); }
   419     public void setMBeanServer(MBeanServer server){mom.setMBeanServer(server); }
   420     public MBeanServer getMBeanServer()          { return mom.getMBeanServer(); }
   421     public void setResourceBundle(ResourceBundle rb) { mom.setResourceBundle(rb); }
   422     public ResourceBundle getResourceBundle()    { return mom.getResourceBundle(); }
   423     public void addAnnotation(AnnotatedElement element, Annotation annotation) { mom.addAnnotation(element, annotation); }
   424     public void setRegistrationDebug(RegistrationDebugLevel level) { mom.setRegistrationDebug(level); }
   425     public void setRuntimeDebug(boolean flag) { mom.setRuntimeDebug(flag); }
   426     public void setTypelibDebug(int level)    { mom.setTypelibDebug(level); }
   427     public String dumpSkeleton(Object obj)    { return mom.dumpSkeleton(obj); }
   428     public void suppressDuplicateRootReport(boolean suppressReport) { mom.suppressDuplicateRootReport(suppressReport); }
   429     public void close() throws IOException    { mom.close(); }
   430     public void setJMXRegistrationDebug(boolean x) { mom.setJMXRegistrationDebug(x); }
   431     public boolean isManagedObject(Object x)  { return mom.isManagedObject(x); }
   432 }
   434 // End of file.

mercurial