Tue, 06 Mar 2012 16:09:35 -0800
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.