699 lines
29 KiB
Java
699 lines
29 KiB
Java
/*
|
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation. Oracle designates this
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
* by Oracle in the LICENSE file that accompanied this code.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
package com.sun.xml.internal.ws.server;
|
|
|
|
import com.sun.istack.internal.NotNull;
|
|
import com.sun.istack.internal.Nullable;
|
|
import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
|
|
import com.sun.xml.internal.ws.addressing.EPRSDDocumentFilter;
|
|
import com.sun.xml.internal.ws.addressing.WSEPRExtension;
|
|
import com.sun.xml.internal.ws.api.Component;
|
|
import com.sun.xml.internal.ws.api.ComponentFeature;
|
|
import com.sun.xml.internal.ws.api.ComponentsFeature;
|
|
import com.sun.xml.internal.ws.api.SOAPVersion;
|
|
import com.sun.xml.internal.ws.api.WSBinding;
|
|
import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
|
|
import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
|
|
import com.sun.xml.internal.ws.api.message.Message;
|
|
import com.sun.xml.internal.ws.api.message.Packet;
|
|
import com.sun.xml.internal.ws.api.model.SEIModel;
|
|
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
|
import com.sun.xml.internal.ws.api.pipe.*;
|
|
import com.sun.xml.internal.ws.api.server.*;
|
|
import com.sun.xml.internal.ws.binding.BindingImpl;
|
|
import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
|
|
import com.sun.xml.internal.ws.model.wsdl.WSDLDirectProperties;
|
|
import com.sun.xml.internal.ws.model.wsdl.WSDLPortProperties;
|
|
import com.sun.xml.internal.ws.model.wsdl.WSDLProperties;
|
|
import com.sun.xml.internal.ws.policy.PolicyMap;
|
|
import com.sun.xml.internal.ws.resources.HandlerMessages;
|
|
import com.sun.xml.internal.ws.util.Pool;
|
|
import com.sun.xml.internal.ws.util.Pool.TubePool;
|
|
import com.sun.xml.internal.ws.util.ServiceFinder;
|
|
import com.sun.xml.internal.ws.wsdl.OperationDispatcher;
|
|
import com.sun.org.glassfish.gmbal.ManagedObjectManager;
|
|
import org.w3c.dom.Element;
|
|
|
|
import javax.annotation.PreDestroy;
|
|
import javax.xml.namespace.QName;
|
|
import javax.xml.stream.XMLStreamException;
|
|
import javax.xml.ws.EndpointReference;
|
|
import javax.xml.ws.WebServiceException;
|
|
import javax.xml.ws.handler.Handler;
|
|
import java.lang.reflect.Method;
|
|
import java.util.*;
|
|
import java.util.concurrent.CopyOnWriteArraySet;
|
|
import java.util.concurrent.Executor;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import javax.management.ObjectName;
|
|
|
|
/**
|
|
* {@link WSEndpoint} implementation.
|
|
*
|
|
* @author Kohsuke Kawaguchi
|
|
* @author Jitendra Kotamraju
|
|
*/
|
|
public /*final*/ class WSEndpointImpl<T> extends WSEndpoint<T> implements LazyMOMProvider.WSEndpointScopeChangeListener {
|
|
|
|
private static final Logger logger = Logger.getLogger(com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server.endpoint");
|
|
|
|
private final @NotNull QName serviceName;
|
|
private final @NotNull QName portName;
|
|
protected final WSBinding binding;
|
|
private final SEIModel seiModel;
|
|
private final @NotNull Container container;
|
|
private final WSDLPort port;
|
|
|
|
protected final Tube masterTubeline;
|
|
private final ServiceDefinitionImpl serviceDef;
|
|
private final SOAPVersion soapVersion;
|
|
private final Engine engine;
|
|
private final @NotNull Codec masterCodec;
|
|
private final @NotNull PolicyMap endpointPolicy;
|
|
private final Pool<Tube> tubePool;
|
|
private final OperationDispatcher operationDispatcher;
|
|
private @NotNull ManagedObjectManager managedObjectManager;
|
|
private boolean managedObjectManagerClosed = false;
|
|
private final Object managedObjectManagerLock = new Object();
|
|
private LazyMOMProvider.Scope lazyMOMProviderScope = LazyMOMProvider.Scope.STANDALONE;
|
|
private final @NotNull ServerTubeAssemblerContext context;
|
|
|
|
private Map<QName, WSEndpointReference.EPRExtension> endpointReferenceExtensions = new HashMap<QName, WSEndpointReference.EPRExtension>();
|
|
/**
|
|
* Set to true once we start shutting down this endpoint. Used to avoid
|
|
* running the clean up processing twice.
|
|
*
|
|
* @see #dispose()
|
|
*/
|
|
private boolean disposed;
|
|
private final Class<T> implementationClass;
|
|
private final @NotNull
|
|
WSDLProperties wsdlProperties;
|
|
private final Set<Component> componentRegistry = new CopyOnWriteArraySet<Component>();
|
|
|
|
protected WSEndpointImpl(@NotNull QName serviceName, @NotNull QName portName, WSBinding binding,
|
|
Container container, SEIModel seiModel, WSDLPort port,
|
|
Class<T> implementationClass,
|
|
@Nullable ServiceDefinitionImpl serviceDef,
|
|
EndpointAwareTube terminalTube, boolean isSynchronous,
|
|
PolicyMap endpointPolicy) {
|
|
this.serviceName = serviceName;
|
|
this.portName = portName;
|
|
this.binding = binding;
|
|
this.soapVersion = binding.getSOAPVersion();
|
|
this.container = container;
|
|
this.port = port;
|
|
this.implementationClass = implementationClass;
|
|
this.serviceDef = serviceDef;
|
|
this.seiModel = seiModel;
|
|
this.endpointPolicy = endpointPolicy;
|
|
|
|
LazyMOMProvider.INSTANCE.registerEndpoint(this);
|
|
initManagedObjectManager();
|
|
|
|
if (serviceDef != null) {
|
|
serviceDef.setOwner(this);
|
|
}
|
|
|
|
ComponentFeature cf = binding.getFeature(ComponentFeature.class);
|
|
if (cf != null) {
|
|
switch (cf.getTarget()) {
|
|
case ENDPOINT:
|
|
componentRegistry.add(cf.getComponent());
|
|
break;
|
|
case CONTAINER:
|
|
container.getComponents().add(cf.getComponent());
|
|
break;
|
|
default:
|
|
throw new IllegalArgumentException();
|
|
}
|
|
}
|
|
ComponentsFeature csf = binding.getFeature(ComponentsFeature.class);
|
|
if (csf != null) {
|
|
for (ComponentFeature cfi : csf.getComponentFeatures()) {
|
|
switch (cfi.getTarget()) {
|
|
case ENDPOINT:
|
|
componentRegistry.add(cfi.getComponent());
|
|
break;
|
|
case CONTAINER:
|
|
container.getComponents().add(cfi.getComponent());
|
|
break;
|
|
default:
|
|
throw new IllegalArgumentException();
|
|
}
|
|
}
|
|
}
|
|
|
|
TubelineAssembler assembler = TubelineAssemblerFactory.create(
|
|
Thread.currentThread().getContextClassLoader(), binding.getBindingId(), container);
|
|
assert assembler != null;
|
|
|
|
this.operationDispatcher = (port == null) ? null : new OperationDispatcher(port, binding, seiModel);
|
|
|
|
context = createServerTubeAssemblerContext(terminalTube, isSynchronous);
|
|
this.masterTubeline = assembler.createServer(context);
|
|
|
|
Codec c = context.getCodec();
|
|
if (c instanceof EndpointAwareCodec) {
|
|
// create a copy to avoid sharing the codec between multiple endpoints
|
|
c = c.copy();
|
|
((EndpointAwareCodec) c).setEndpoint(this);
|
|
}
|
|
this.masterCodec = c;
|
|
|
|
tubePool = new TubePool(masterTubeline);
|
|
terminalTube.setEndpoint(this);
|
|
engine = new Engine(toString(), container);
|
|
wsdlProperties = (port == null) ? new WSDLDirectProperties(serviceName, portName, seiModel) : new WSDLPortProperties(port, seiModel);
|
|
|
|
Map<QName, WSEndpointReference.EPRExtension> eprExtensions = new HashMap<QName, WSEndpointReference.EPRExtension>();
|
|
try {
|
|
if (port != null) {
|
|
//gather EPR extrensions from WSDL Model
|
|
WSEndpointReference wsdlEpr = port.getEPR();
|
|
if (wsdlEpr != null) {
|
|
for (WSEndpointReference.EPRExtension extnEl : wsdlEpr.getEPRExtensions()) {
|
|
eprExtensions.put(extnEl.getQName(), extnEl);
|
|
}
|
|
}
|
|
}
|
|
|
|
EndpointReferenceExtensionContributor[] eprExtnContributors = ServiceFinder.find(EndpointReferenceExtensionContributor.class).toArray();
|
|
for(EndpointReferenceExtensionContributor eprExtnContributor :eprExtnContributors) {
|
|
WSEndpointReference.EPRExtension wsdlEPRExtn = eprExtensions.remove(eprExtnContributor.getQName());
|
|
WSEndpointReference.EPRExtension endpointEprExtn = eprExtnContributor.getEPRExtension(this,wsdlEPRExtn);
|
|
if (endpointEprExtn != null) {
|
|
eprExtensions.put(endpointEprExtn.getQName(), endpointEprExtn);
|
|
}
|
|
}
|
|
for (WSEndpointReference.EPRExtension extn : eprExtensions.values()) {
|
|
endpointReferenceExtensions.put(extn.getQName(), new WSEPRExtension(
|
|
XMLStreamBuffer.createNewBufferFromXMLStreamReader(extn.readAsXMLStreamReader()),extn.getQName()));
|
|
}
|
|
} catch (XMLStreamException ex) {
|
|
throw new WebServiceException(ex);
|
|
}
|
|
if(!eprExtensions.isEmpty()) {
|
|
serviceDef.addFilter(new EPRSDDocumentFilter(this));
|
|
}
|
|
}
|
|
|
|
protected ServerTubeAssemblerContext createServerTubeAssemblerContext(
|
|
EndpointAwareTube terminalTube, boolean isSynchronous) {
|
|
ServerTubeAssemblerContext ctx = new ServerPipeAssemblerContext(
|
|
seiModel, port, this, terminalTube, isSynchronous);
|
|
return ctx;
|
|
}
|
|
|
|
protected WSEndpointImpl(@NotNull QName serviceName, @NotNull QName portName, WSBinding binding, Container container,
|
|
SEIModel seiModel, WSDLPort port,
|
|
Tube masterTubeline) {
|
|
this.serviceName = serviceName;
|
|
this.portName = portName;
|
|
this.binding = binding;
|
|
this.soapVersion = binding.getSOAPVersion();
|
|
this.container = container;
|
|
this.endpointPolicy = null;
|
|
this.port = port;
|
|
this.seiModel = seiModel;
|
|
this.serviceDef = null;
|
|
this.implementationClass = null;
|
|
this.masterTubeline = masterTubeline;
|
|
this.masterCodec = ((BindingImpl) this.binding).createCodec();
|
|
|
|
LazyMOMProvider.INSTANCE.registerEndpoint(this);
|
|
initManagedObjectManager();
|
|
|
|
this.operationDispatcher = (port == null) ? null : new OperationDispatcher(port, binding, seiModel);
|
|
this.context = new ServerPipeAssemblerContext(
|
|
seiModel, port, this, null /* not known */, false);
|
|
|
|
tubePool = new TubePool(masterTubeline);
|
|
engine = new Engine(toString(), container);
|
|
wsdlProperties = (port == null) ? new WSDLDirectProperties(serviceName, portName, seiModel) : new WSDLPortProperties(port, seiModel);
|
|
}
|
|
|
|
public Collection<WSEndpointReference.EPRExtension> getEndpointReferenceExtensions() {
|
|
return endpointReferenceExtensions.values();
|
|
}
|
|
|
|
/**
|
|
* Nullable when there is no associated WSDL Model
|
|
* @return
|
|
*/
|
|
public @Nullable OperationDispatcher getOperationDispatcher() {
|
|
return operationDispatcher;
|
|
}
|
|
|
|
public PolicyMap getPolicyMap() {
|
|
return endpointPolicy;
|
|
}
|
|
|
|
public @NotNull Class<T> getImplementationClass() {
|
|
return implementationClass;
|
|
}
|
|
|
|
public @NotNull WSBinding getBinding() {
|
|
return binding;
|
|
}
|
|
|
|
public @NotNull Container getContainer() {
|
|
return container;
|
|
}
|
|
|
|
public WSDLPort getPort() {
|
|
return port;
|
|
}
|
|
|
|
@Override
|
|
public @Nullable SEIModel getSEIModel() {
|
|
return seiModel;
|
|
}
|
|
|
|
public void setExecutor(Executor exec) {
|
|
engine.setExecutor(exec);
|
|
}
|
|
|
|
@Override
|
|
public Engine getEngine() {
|
|
return engine;
|
|
}
|
|
|
|
public void schedule(final Packet request, final CompletionCallback callback, FiberContextSwitchInterceptor interceptor) {
|
|
processAsync(request, callback, interceptor, true);
|
|
}
|
|
|
|
private void processAsync(final Packet request,
|
|
final CompletionCallback callback,
|
|
FiberContextSwitchInterceptor interceptor, boolean schedule) {
|
|
Container old = ContainerResolver.getDefault().enterContainer(container);
|
|
try {
|
|
request.endpoint = WSEndpointImpl.this;
|
|
request.addSatellite(wsdlProperties);
|
|
|
|
Fiber fiber = engine.createFiber();
|
|
fiber.setDeliverThrowableInPacket(true);
|
|
if (interceptor != null) {
|
|
fiber.addInterceptor(interceptor);
|
|
}
|
|
final Tube tube = tubePool.take();
|
|
Fiber.CompletionCallback cbak = new Fiber.CompletionCallback() {
|
|
public void onCompletion(@NotNull Packet response) {
|
|
ThrowableContainerPropertySet tc = response.getSatellite(ThrowableContainerPropertySet.class);
|
|
if (tc == null) {
|
|
// Only recycle tubes in non-exception path as some Tubes may be
|
|
// in invalid state following exception
|
|
tubePool.recycle(tube);
|
|
}
|
|
|
|
if (callback != null) {
|
|
if (tc != null) {
|
|
response = createServiceResponseForException(tc,
|
|
response,
|
|
soapVersion,
|
|
request.endpoint.getPort(),
|
|
null,
|
|
request.endpoint.getBinding());
|
|
}
|
|
callback.onCompletion(response);
|
|
}
|
|
}
|
|
|
|
public void onCompletion(@NotNull Throwable error) {
|
|
// will never be called now that we are using
|
|
// fiber.setDeliverThrowableInPacket(true);
|
|
throw new IllegalStateException();
|
|
}
|
|
};
|
|
|
|
fiber.start(tube, request, cbak,
|
|
binding.isFeatureEnabled(SyncStartForAsyncFeature.class)
|
|
|| !schedule);
|
|
} finally {
|
|
ContainerResolver.getDefault().exitContainer(old);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Packet createServiceResponseForException(final ThrowableContainerPropertySet tc,
|
|
final Packet responsePacket,
|
|
final SOAPVersion soapVersion,
|
|
final WSDLPort wsdlPort,
|
|
final SEIModel seiModel,
|
|
final WSBinding binding)
|
|
{
|
|
// This will happen in addressing if it is enabled.
|
|
if (tc.isFaultCreated()) return responsePacket;
|
|
|
|
final Message faultMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, tc.getThrowable());
|
|
final Packet result = responsePacket.createServerResponse(faultMessage, wsdlPort, seiModel, binding);
|
|
// Pass info to upper layers
|
|
tc.setFaultMessage(faultMessage);
|
|
tc.setResponsePacket(responsePacket);
|
|
tc.setFaultCreated(true);
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public void process(final Packet request, final CompletionCallback callback, FiberContextSwitchInterceptor interceptor) {
|
|
processAsync(request, callback, interceptor, false);
|
|
}
|
|
|
|
public @NotNull
|
|
PipeHead createPipeHead() {
|
|
return new PipeHead() {
|
|
private final Tube tube = TubeCloner.clone(masterTubeline);
|
|
|
|
public @NotNull
|
|
Packet process(Packet request, WebServiceContextDelegate wscd,
|
|
TransportBackChannel tbc) {
|
|
Container old = ContainerResolver.getDefault().enterContainer(container);
|
|
try {
|
|
request.webServiceContextDelegate = wscd;
|
|
request.transportBackChannel = tbc;
|
|
request.endpoint = WSEndpointImpl.this;
|
|
request.addSatellite(wsdlProperties);
|
|
|
|
Fiber fiber = engine.createFiber();
|
|
Packet response;
|
|
try {
|
|
response = fiber.runSync(tube, request);
|
|
} catch (RuntimeException re) {
|
|
// Catch all runtime exceptions so that transport
|
|
// doesn't
|
|
// have to worry about converting to wire message
|
|
// TODO XML/HTTP binding
|
|
Message faultMsg = SOAPFaultBuilder
|
|
.createSOAPFaultMessage(soapVersion, null, re);
|
|
response = request.createServerResponse(faultMsg,
|
|
request.endpoint.getPort(), null,
|
|
request.endpoint.getBinding());
|
|
}
|
|
return response;
|
|
} finally {
|
|
ContainerResolver.getDefault().exitContainer(old);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
public synchronized void dispose() {
|
|
if (disposed) {
|
|
return;
|
|
}
|
|
disposed = true;
|
|
|
|
masterTubeline.preDestroy();
|
|
|
|
for (Handler handler : binding.getHandlerChain()) {
|
|
for (Method method : handler.getClass().getMethods()) {
|
|
if (method.getAnnotation(PreDestroy.class) == null) {
|
|
continue;
|
|
}
|
|
try {
|
|
method.invoke(handler);
|
|
} catch (Exception e) {
|
|
logger.log(Level.WARNING, HandlerMessages.HANDLER_PREDESTROY_IGNORE(e.getMessage()), e);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
closeManagedObjectManager();
|
|
LazyMOMProvider.INSTANCE.unregisterEndpoint(this);
|
|
}
|
|
|
|
public ServiceDefinitionImpl getServiceDefinition() {
|
|
return serviceDef;
|
|
}
|
|
|
|
public Set<EndpointComponent> getComponentRegistry() {
|
|
Set<EndpointComponent> sec = new EndpointComponentSet();
|
|
for (Component c : componentRegistry) {
|
|
sec.add(c instanceof EndpointComponentWrapper ?
|
|
((EndpointComponentWrapper) c).component :
|
|
new ComponentWrapper(c));
|
|
}
|
|
return sec;
|
|
}
|
|
|
|
private class EndpointComponentSet extends HashSet<EndpointComponent> {
|
|
|
|
@Override
|
|
public Iterator<EndpointComponent> iterator() {
|
|
final Iterator<EndpointComponent> it = super.iterator();
|
|
return new Iterator<EndpointComponent>() {
|
|
private EndpointComponent last = null;
|
|
|
|
public boolean hasNext() {
|
|
return it.hasNext();
|
|
}
|
|
|
|
public EndpointComponent next() {
|
|
last = it.next();
|
|
return last;
|
|
}
|
|
|
|
public void remove() {
|
|
it.remove();
|
|
if (last != null) {
|
|
componentRegistry.remove(last instanceof ComponentWrapper ?
|
|
((ComponentWrapper) last).component :
|
|
new EndpointComponentWrapper(last));
|
|
}
|
|
last = null;
|
|
}
|
|
};
|
|
}
|
|
|
|
@Override
|
|
public boolean add(EndpointComponent e) {
|
|
boolean result = super.add(e);
|
|
if (result) {
|
|
componentRegistry.add(new EndpointComponentWrapper(e));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public boolean remove(Object o) {
|
|
boolean result = super.remove(o);
|
|
if (result) {
|
|
componentRegistry.remove(o instanceof ComponentWrapper ?
|
|
((ComponentWrapper) o).component :
|
|
new EndpointComponentWrapper((EndpointComponent)o));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
}
|
|
|
|
private static class ComponentWrapper implements EndpointComponent {
|
|
private final Component component;
|
|
|
|
public ComponentWrapper(Component component) {
|
|
this.component = component;
|
|
}
|
|
|
|
public <S> S getSPI(Class<S> spiType) {
|
|
return component.getSPI(spiType);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return component.hashCode();
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
return component.equals(obj);
|
|
}
|
|
}
|
|
|
|
private static class EndpointComponentWrapper implements Component {
|
|
private final EndpointComponent component;
|
|
|
|
public EndpointComponentWrapper(EndpointComponent component) {
|
|
this.component = component;
|
|
}
|
|
|
|
public <S> S getSPI(Class<S> spiType) {
|
|
return component.getSPI(spiType);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return component.hashCode();
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
return component.equals(obj);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public @NotNull Set<Component> getComponents() {
|
|
return componentRegistry;
|
|
}
|
|
|
|
public <T extends EndpointReference> T getEndpointReference(Class<T> clazz, String address, String wsdlAddress, Element... referenceParameters) {
|
|
List<Element> refParams = null;
|
|
if (referenceParameters != null) {
|
|
refParams = Arrays.asList(referenceParameters);
|
|
}
|
|
return getEndpointReference(clazz, address, wsdlAddress, null, refParams);
|
|
}
|
|
|
|
public <T extends EndpointReference> T getEndpointReference(Class<T> clazz,
|
|
String address, String wsdlAddress, List<Element> metadata,
|
|
List<Element> referenceParameters) {
|
|
QName portType = null;
|
|
if (port != null) {
|
|
portType = port.getBinding().getPortTypeName();
|
|
}
|
|
|
|
AddressingVersion av = AddressingVersion.fromSpecClass(clazz);
|
|
return new WSEndpointReference(
|
|
av, address, serviceName, portName, portType, metadata, wsdlAddress, referenceParameters, endpointReferenceExtensions.values(), null).toSpec(clazz);
|
|
|
|
}
|
|
|
|
public @NotNull QName getPortName() {
|
|
return portName;
|
|
}
|
|
|
|
|
|
public @NotNull Codec createCodec() {
|
|
return masterCodec.copy();
|
|
}
|
|
|
|
public @NotNull QName getServiceName() {
|
|
return serviceName;
|
|
}
|
|
|
|
private void initManagedObjectManager() {
|
|
synchronized (managedObjectManagerLock) {
|
|
if (managedObjectManager == null) {
|
|
switch (this.lazyMOMProviderScope) {
|
|
case GLASSFISH_NO_JMX:
|
|
managedObjectManager = new WSEndpointMOMProxy(this);
|
|
break;
|
|
default:
|
|
managedObjectManager = obtainManagedObjectManager();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public @NotNull ManagedObjectManager getManagedObjectManager() {
|
|
return managedObjectManager;
|
|
}
|
|
|
|
/**
|
|
* Obtains a real instance of {@code ManagedObjectManager} class no matter what lazyMOMProviderScope is this endpoint in (or if the
|
|
* Gmbal API calls should be deferred).
|
|
*
|
|
* @see com.sun.xml.internal.ws.api.server.LazyMOMProvider.Scope
|
|
* @return an instance of {@code ManagedObjectManager}
|
|
*/
|
|
@NotNull ManagedObjectManager obtainManagedObjectManager() {
|
|
final MonitorRootService monitorRootService = new MonitorRootService(this);
|
|
final ManagedObjectManager mOM = monitorRootService.createManagedObjectManager(this);
|
|
|
|
// ManagedObjectManager was suspended due to root creation (see MonitorBase#initMOM)
|
|
mOM.resumeJMXRegistration();
|
|
|
|
return mOM;
|
|
}
|
|
|
|
public void scopeChanged(LazyMOMProvider.Scope scope) {
|
|
synchronized (managedObjectManagerLock) {
|
|
if (managedObjectManagerClosed) {
|
|
return;
|
|
}
|
|
|
|
this.lazyMOMProviderScope = scope;
|
|
|
|
// possible lazyMOMProviderScope change can be LazyMOMProvider.Scope.GLASSFISH_NO_JMX or LazyMOMProvider.Scope.GLASSFISH_JMX
|
|
if (managedObjectManager == null) {
|
|
if (scope != LazyMOMProvider.Scope.GLASSFISH_NO_JMX) {
|
|
managedObjectManager = obtainManagedObjectManager();
|
|
} else {
|
|
managedObjectManager = new WSEndpointMOMProxy(this);
|
|
}
|
|
} else {
|
|
// if ManagedObjectManager for this endpoint has already been created and is uninitialized proxy then
|
|
// fill it with a real instance
|
|
if (managedObjectManager instanceof WSEndpointMOMProxy
|
|
&& !((WSEndpointMOMProxy)managedObjectManager).isInitialized()) {
|
|
((WSEndpointMOMProxy)managedObjectManager).setManagedObjectManager(obtainManagedObjectManager());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static final Logger monitoringLogger = Logger.getLogger(com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".monitoring");
|
|
|
|
// This can be called independently of WSEndpoint.dispose.
|
|
// Example: the WSCM framework calls this before dispose.
|
|
@Override
|
|
public void closeManagedObjectManager() {
|
|
synchronized (managedObjectManagerLock) {
|
|
if (managedObjectManagerClosed == true) {
|
|
return;
|
|
}
|
|
if (managedObjectManager != null) {
|
|
boolean close = true;
|
|
|
|
// ManagedObjectManager doesn't need to be closed because it exists only as a proxy
|
|
if (managedObjectManager instanceof WSEndpointMOMProxy
|
|
&& !((WSEndpointMOMProxy)managedObjectManager).isInitialized()) {
|
|
close = false;
|
|
}
|
|
|
|
if (close) {
|
|
try {
|
|
final ObjectName name = managedObjectManager.getObjectName(managedObjectManager.getRoot());
|
|
// The name is null when the MOM is a NOOP.
|
|
if (name != null) {
|
|
monitoringLogger.log(Level.INFO, "Closing Metro monitoring root: {0}", name);
|
|
}
|
|
managedObjectManager.close();
|
|
} catch (java.io.IOException e) {
|
|
monitoringLogger.log(Level.WARNING, "Ignoring error when closing Managed Object Manager", e);
|
|
}
|
|
}
|
|
}
|
|
managedObjectManagerClosed = true;
|
|
}
|
|
}
|
|
|
|
public @NotNull @Override ServerTubeAssemblerContext getAssemblerContext() {
|
|
return context;
|
|
}
|
|
}
|