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

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     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.

mercurial