Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package com.sun.xml.ws.metro.api.config.management;
import com.sun.istack.NotNull;
import com.sun.istack.logging.Logger;
import com.sun.xml.ws.api.Component;
import com.sun.xml.ws.api.SOAPVersion;
import com.sun.xml.ws.api.WSBinding;
import com.sun.xml.ws.api.config.management.EndpointCreationAttributes;
import com.sun.xml.ws.api.config.management.Reconfigurable;
import com.sun.xml.ws.api.message.Packet;
import com.sun.xml.ws.api.model.SEIModel;
import com.sun.xml.ws.api.model.wsdl.WSDLPort;
import com.sun.xml.ws.api.pipe.Codec;
import com.sun.xml.ws.api.pipe.FiberContextSwitchInterceptor;
import com.sun.xml.ws.api.pipe.ServerTubeAssemblerContext;
import com.sun.xml.ws.api.pipe.ThrowableContainerPropertySet;
import com.sun.xml.ws.api.server.Container;
import com.sun.xml.ws.api.server.ServiceDefinition;
import com.sun.xml.ws.api.server.WSEndpoint;
import com.sun.xml.ws.api.server.WSEndpoint.CompletionCallback;
import com.sun.xml.ws.api.server.WSEndpoint.PipeHead;
import com.sun.xml.ws.config.management.ManagementMessages;
import com.sun.xml.ws.policy.PolicyMap;
import com.sun.xml.ws.wsdl.OperationDispatcher;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import javax.xml.namespace.QName;
import jakarta.xml.ws.EndpointReference;
import jakarta.xml.ws.WebServiceException;
import org.glassfish.gmbal.ManagedObjectManager;
import org.w3c.dom.Element;
/**
* Wraps an existing WSEndpoint instance and provides a method to swap the
* WSEndpoint instance. This class also brings up the management communication
* interfaces when it is instantiated.
*
* This class forwards all method invocations to the wrapped WSEndpoint instance.
*
* @param The implementation class of the endpoint.
*
* @author Fabian Ritzmann, Martin Grebac
*/
public class ManagedEndpoint extends WSEndpoint{
private static final Logger LOGGER = Logger.getLogger(ManagedEndpoint.class);
private WSEndpoint endpointDelegate;
private final Collection reconfigNotifiers = new LinkedList<>();
// Delay before dispose is called on a replaced endpoint delegate. Defaults to 2 minutes.
private static final long ENDPOINT_DISPOSE_DELAY_DEFAULT = 120000l;
private long endpointDisposeDelay = ENDPOINT_DISPOSE_DELAY_DEFAULT;
private volatile ScheduledExecutorService executorService;
private final EndpointCreationAttributes creationAttributes;
private boolean useContainerSpi = true;
private final AtomicBoolean isClosed;
/**
* Initializes this endpoint.
*
* @param endpoint The wrapped WSEndpoint instance.
* @param attributes Several attributes that were used to create the original WSEndpoint
* instance and that cannot be queried from WSEndpoint itself. This is used by
* the communication API to recreate WSEndpoint instances with the same parameters.
*/
public ManagedEndpoint(final WSEndpoint endpoint, final EndpointCreationAttributes attributes) {
this.creationAttributes = attributes;
this.endpointDelegate = endpoint;
this.isClosed = new AtomicBoolean(false);
for (ReconfigNotifier notifier : this.reconfigNotifiers) {
notifier.sendNotification();
}
if (LOGGER.isLoggable(Level.CONFIG)) {
LOGGER.config(ManagementMessages.WSM_5066_STARTING_ENDPOINT());
}
}
/**
* @param notifier Callback object allows us to send a notification when the
* endpoint was reconfigured.
*/
public void addNotifier(final ReconfigNotifier notifier) {
this.reconfigNotifiers.add(notifier);
}
/**
* Returns attributes used for creation of this endpoint.
* @return
*/
public EndpointCreationAttributes getCreationAttributes() {
return this.creationAttributes;
}
/**
* Sets a new WSEndpoint instance to which method calls will be forwarded from
* then on.
*
* @param endpoint The WSEndpoint instance. May not be null.
*/
synchronized public void swapEndpointDelegate(final WSEndpoint endpoint) {
// Plug in code that regenerates WSDL when the endpoint was reconfigured.
final Set endpointComponents = endpoint.getComponents();
final WSEndpoint oldEndpoint = this.endpointDelegate;
this.endpointDelegate = endpoint;
for (Component component : endpointComponents) {
final Reconfigurable reconfigurable = component.getSPI(Reconfigurable.class);
if (reconfigurable != null) {
reconfigurable.reconfigure();
}
}
disposeDelegate(oldEndpoint);
LOGGER.info(ManagementMessages.WSM_5000_RECONFIGURED_ENDPOINT(this/*.id*/));
}
@Override
synchronized public void dispose() {
this.isClosed.compareAndSet(false, true);
//no need to dispose thread pool if we got thread pool from container
if (!useContainerSpi) {
if (this.executorService != null) {
this.executorService.shutdown();
}
}
//either way we should dispose the endpoint delegate
if (this.endpointDelegate != null) {
this.endpointDelegate.dispose();
}
}
@Override
public Codec createCodec() {
return this.endpointDelegate.createCodec();
}
@Override
public QName getServiceName() {
return this.endpointDelegate.getServiceName();
}
@Override
public QName getPortName() {
return this.endpointDelegate.getPortName();
}
@Override
public Class getImplementationClass() {
return this.endpointDelegate.getImplementationClass();
}
@Override
public WSBinding getBinding() {
return this.endpointDelegate.getBinding();
}
@Override
public Container getContainer() {
return this.endpointDelegate.getContainer();
}
@Override
public WSDLPort getPort() {
return this.endpointDelegate.getPort();
}
@Override
public void setExecutor(Executor exec) {
this.endpointDelegate.setExecutor(exec);
}
@Override
public void schedule(Packet request, CompletionCallback callback, FiberContextSwitchInterceptor interceptor) {
this.endpointDelegate.schedule(request, callback, interceptor);
}
@Override
public void process(Packet request, CompletionCallback callback, FiberContextSwitchInterceptor interceptor) {
this.endpointDelegate.process(request, callback, interceptor);
}
@Override
public PipeHead createPipeHead() {
return this.endpointDelegate.createPipeHead();
}
@Override
public ServiceDefinition getServiceDefinition() {
return this.endpointDelegate.getServiceDefinition();
}
@Override
public @NotNull Set getComponents() {
return this.endpointDelegate.getComponents();
}
@Override
public SEIModel getSEIModel() {
return this.endpointDelegate.getSEIModel();
}
@Override
public PolicyMap getPolicyMap() {
return this.endpointDelegate.getPolicyMap();
}
@Override
public ManagedObjectManager getManagedObjectManager() {
return this.endpointDelegate.getManagedObjectManager();
}
@Override
public void closeManagedObjectManager() {
this.endpointDelegate.closeManagedObjectManager();
}
@Override
public ServerTubeAssemblerContext getAssemblerContext() {
return this.endpointDelegate.getAssemblerContext();
}
/**
* Call dispose on the endpoint delegate that was swapped out against a new
* instance.
*
* @param endpoint The previous endpoint delegate
*/
private void disposeDelegate(final WSEndpoint endpoint) {
final Runnable dispose = new Runnable() {
final WSEndpoint disposableEndpoint = endpoint;
@Override
public void run() {
try {
disposableEndpoint.dispose();
} catch (WebServiceException e) {
LOGGER.severe(ManagementMessages.WSM_5101_DISPOSE_FAILED(), e);
}
}
};
getExecutorService().schedule(dispose, this.endpointDisposeDelay, TimeUnit.MILLISECONDS);
}
@Override
public boolean equalsProxiedInstance(WSEndpoint endpoint) {
if (endpointDelegate == null) {
return (endpoint == null);
}
if (endpoint instanceof ManagedEndpoint) {
return false;
}
return endpointDelegate.equals(endpoint);
}
@Override
public T getEndpointReference(Class clazz, String address, String wsdlAddress, Element... referenceParameters) {
return endpointDelegate.getEndpointReference(clazz, address, wsdlAddress, referenceParameters);
}
@Override
public T getEndpointReference(Class clazz, String address, String wsdlAddress, List metadata, List referenceParameters) {
return endpointDelegate.getEndpointReference(clazz, address, wsdlAddress, metadata, referenceParameters);
}
@Override
public OperationDispatcher getOperationDispatcher() {
return endpointDelegate.getOperationDispatcher();
}
@Override
public Packet createServiceResponseForException(ThrowableContainerPropertySet tcps, Packet packet, SOAPVersion soapv, WSDLPort wsdlp, SEIModel seim, WSBinding wsb) {
return endpointDelegate.createServiceResponseForException(tcps, packet, soapv, wsdlp, seim, wsb);
}
/**
* Return the appropriate ScheduledExecutorService - on initial access, check for container.getSPI
* NOTE - THIS METHOD IS A COPY OF {@link com.sun.xml.ws.commons.AbstractTaskManager#getExecutorService() AbstractTaskManager.getExecutorService() } IN metro-commons!!!
* IF A SUITABLE COMMON LOCATION CAN BE FOUND IT MUST BE REMOVED FROM HERE!
* @return
*
*/
private ScheduledExecutorService getExecutorService() {
if (executorService == null) {
synchronized (this) {
if (executorService == null) {
if (getContainer() != null) {
executorService = getContainer().getSPI(ScheduledExecutorService.class);
}
if (executorService == null) {
//container did not return an SPI - create our own thread pool
LOGGER.finer("Container did not return SPI for ScheduledExecutorService - creating thread pool for dispose");
executorService = Executors.newScheduledThreadPool(getThreadPoolSize());
useContainerSpi = false;
} else {
LOGGER.finer("Using Container SPI for ScheduledExecutorService for dispose");
useContainerSpi = true;
}
this.isClosed.set(false);
}
}
}
return executorService;
}
private int getThreadPoolSize() {
return 1;
}
}