All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.xml.ws.developer.StatefulWebServiceManager Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1997, 2022 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.developer;

import com.sun.istack.NotNull;
import com.sun.istack.Nullable;
import com.sun.xml.ws.api.message.Packet;
import com.sun.xml.ws.api.pipe.Tube;
import com.sun.xml.ws.api.server.AsyncProvider;
import com.sun.xml.ws.api.server.AsyncProviderCallback;

import jakarta.annotation.Resource;
import jakarta.jws.WebMethod;
import jakarta.jws.WebService;
import jakarta.xml.ws.EndpointReference;
import jakarta.xml.ws.WebServiceContext;
import jakarta.xml.ws.WebServiceException;
import jakarta.xml.ws.wsaddressing.W3CEndpointReference;

/**
 * Stateful web service support in the JAX-WS RI.
 *
 * 

Usage

*

* Application service implementation classes (or providers) who'd like * to use the stateful web service support must declare {@link Stateful} * annotation on a class. It should also have a public static method/field * that takes {@link StatefulWebServiceManager}. * *

 * @{@link Stateful} @{@link WebService}
 * class BankAccount {
 *     protected final int id;
 *     private int balance;
 *
 *     BankAccount(int id) { this.id = id; }
 *     @{@link WebMethod}
 *     public synchronized void deposit(int amount) { balance+=amount; }
 *
 *     // either via a public static field
 *     public static {@link StatefulWebServiceManager}<BankAccount> manager;
 *
 *     // ... or  via a public static method (the method name could be anything)
 *     public static void setManager({@link StatefulWebServiceManager}<BankAccount> manager) {
 *        ...
 *     }
 * }
 * 
* *

* After your service is deployed but before you receive a first request, * the resource injection occurs on the field or the method. * *

* A stateful web service class does not need to have a default constructor. * In fact, most of the time you want to define a constructor that takes * some arguments, so that each instance carries certain state (as illustrated * in the above example.) * *

* Each instance of a stateful web service class is identified by an unique * {@link EndpointReference}. Your application creates an instance of * a class, then you'll have the JAX-WS RI assign this unique EPR for the * instance as follows: * *

 * @{@link WebService}
 * class Bank { // this is ordinary stateless service
 *     @{@link WebMethod}
 *     public synchronized W3CEndpointReference login(int accountId, int pin) {
 *         if(!checkPin(pin))
 *             throw new AuthenticationFailedException("invalid pin");
 *         BankAccount acc = new BankAccount(accountId);
 *         return BankAccount.manager.{@link #export export}(acc);
 *     }
 * }
 * 
* *

* Typically you then pass this EPR to remote systems. When they send * messages to this EPR, the JAX-WS RI makes sure that the particular exported * instance associated with that EPR will receive a service invocation. * *

Things To Consider

*

* When you no longer need to tie an instance to the EPR, * use {@link #unexport(Object)} so that the object can be GC-ed * (or else you'll leak memory.) You may choose to do so explicitly, * or you can rely on the time out by using {@link #setTimeout(long, Callback)}. * *

* {@link StatefulWebServiceManager} is thread-safe. It can be safely * invoked from multiple threads concurrently. * * @author Kohsuke Kawaguchi * @see StatefulFeature * @since 2.1 */ public interface StatefulWebServiceManager { /** * Exports an object. * *

* This method works like {@link #export(Object)} except that * you can obtain the EPR in your choice of addressing version, * by passing in the suitable epr parameter. * * @param epr * Either {@link W3CEndpointReference} or {@link MemberSubmissionEndpointReference}. * If other types are specified, this method throws an {@link WebServiceException}. * @return * {@link EndpointReference}-subclass that identifies this exported * object. */ @NotNull EPR export(Class epr, T o); /** * Exports an object. * *

* This method works like {@link #export(Object)} except that * you can obtain the EPR in your choice of addressing version, * by passing in the suitable epr parameter. * * @param epr * Either {@link W3CEndpointReference} or {@link MemberSubmissionEndpointReference}. * If other types are specified, this method throws an {@link WebServiceException}. * @param o * The object to be exported, whose identity be referenced by the returned EPR. * @param recipe * The additional data to be put into EPR. Can be null. * @return * {@link EndpointReference}-subclass that identifies this exported * object. * @since 2.1.1 */ @NotNull EPR export(Class epr, T o, @Nullable EPRRecipe recipe ); /** * Exports an object. * *

* JAX-WS RI assigns an unique EPR to the exported object, * and from now on, messages that are sent to this EPR will * be routed to the given object. * *

* The object will be locked in memory, so be sure to * {@link #unexport(Object) unexport} it when it's no longer needed. * *

* Notice that the obtained EPR contains the address of the service, * which depends on the currently processed request. So invoking * this method multiple times with the same object may return * different EPRs, if such multiple invocations are done while * servicing different requests. (Of course all such EPRs point * to the same object, so messages sent to those EPRs will be * served by the same instance.) * * @return * {@link W3CEndpointReference} that identifies this exported * object. Always non-null. */ @NotNull W3CEndpointReference export(T o); /** * Exports an object (for {@link AsyncProvider asynchronous web services}.) * *

* This method works like {@link #export(Class,Object)} but it * takes an extra {@link WebServiceContext} that represents the request currently * being processed by the caller (the JAX-WS RI remembers this when the service * processing is synchronous, and that's why this parameter is only needed for * asynchronous web services.) * *

* Why {@link WebServiceContext} is needed? *

* The obtained EPR contains address, such as host name. The server does not * know what its own host name is (or there are more than one of them), * so this value is determined by what the current client thinks the server name is. * This is why we need to take {@link WebServiceContext}. Pass in the * object given to {@link AsyncProvider#invoke(Object, AsyncProviderCallback,WebServiceContext)}. */ @NotNull EPR export(Class eprType, @NotNull WebServiceContext context, T o); /** * Exports an object. * *

* This method is not meant for application code. * This is for {@link Tube}s that wish to use stateful web service support. * * @param currentRequest * The request that we are currently processing. This is used to infer the address in EPR. * @see #export(Class, WebServiceContext, Object) */ @NotNull EPR export(Class eprType, @NotNull Packet currentRequest, T o); /** * The same as {@link #export(Class, Packet, Object)} except * that it takes {@link EPRRecipe}. * * @param recipe * See {@link #export(Class, Object, EPRRecipe)}. */ @NotNull EPR export(Class eprType, @NotNull Packet currentRequest, T o, EPRRecipe recipe); /** * Exports an object. * * @deprecated * This method is provided as a temporary workaround, and we'll eventually try to remove it. * * @param endpointAddress * The endpoint address URL. Normally, this information is determined by other inputs, * like {@link Packet} or {@link WebServiceContext}. */ @Deprecated @NotNull EPR export(Class eprType, String endpointAddress, T o); /** * Unexports the given instance. * *

* JAX-WS will release a strong reference to unexported objects, * and they will never receive further requests (requests targeted * for those unexported objects will be served by the fallback object.) * * @param o * if null, this method will be no-op. */ void unexport(@Nullable T o); /** * Checks if the given EPR represents an object that has been exported from this manager. * *

* This method can be used to have two endpoints in the same application communicate * locally. * * @return null if the EPR is not exported from this manager. */ @Nullable T resolve(@NotNull EndpointReference epr); /** * Sets the "fallback" instance. * *

* When the incoming request does not have the necessary header to * distinguish instances of T, or when the header is present * but its value does not correspond with any of the active exported * instances known to the JAX-WS, then the JAX-WS RI will try to * route the request to the fallback instance. * *

* This provides the application an opportunity to perform application * specific error recovery. * *

* If no fallback instance is provided, then the JAX-WS RI will * send back the fault. By default, no fallback instance is set. * *

* This method can be invoked any time, but most often you'd like to * use one instance at the get-go. The following code example * illustrates how to do this: * *

     * @{@link WebService}
     * class BankAccount {
     *     ... continuting from the example in class javadoc ...
     *
     *     @{@link Resource} static void setManager({@link StatefulWebServiceManager} manager) {
     *        manager.setFallbackInstance(new BankAccount(0) {
     *            @{@link Override}
     *            void deposit(int amount) {
     *                putToAuditRecord(id);
     *                if(thisLooksBad())   callPolice();
     *                throw new {@link WebServiceException}("No such bank account exists");
     *            }
     *        });
     *     }
     * }
     * 
* * @param o * Can be null. */ void setFallbackInstance(T o); /** * Configures timeout for exported instances. * *

* When configured, the JAX-WS RI will internally use a timer * so that exported objects that have not received any request * for the given amount of minutes will be automatically unexported. * *

* At some point after the time out has occurred for an instance, * the JAX-WS RI will invoke the {@link Callback} to notify the application * that the time out has reached. Application then has a choice of * either let the object go unexported, or {@link #touch(Object) touch} * let the object live for another round of timer interval. * *

* If no callback is set, the expired object will automatically unexported. * *

* When you call this method multiple times, its effect on existing * instances are unspecified, although deterministic. * * @param milliseconds * The time out interval. Specify 0 to cancel the timeout timer. * Note that this only guarantees that time out does not occur * at least until this amount of time has elapsed. It does not * guarantee that the time out will always happen right after * the timeout is reached. * @param callback * application may choose to install a callback to control the * timeout behavior. */ void setTimeout(long milliseconds, @Nullable Callback callback); /** * Resets the time out timer for the given instance. * *

* If the object is null, not exported, or already unexported, this * method will be no-op. */ void touch(T o); /** * Used by {@link StatefulWebServiceManager#setTimeout(long, Callback)} * to determine what to do when the time out is reached. */ interface Callback { /** * Application has a chance to decide if the object should be unexported, * or kept alive. * *

* The application should either unexport the object, or touch the object * from within this callback. * If no action is taken, the object will remain exported until it is * manually unexported. * * @param timedOutObject * The object that reached the time out. * @param manager * The manager instance that you exported the object to. */ void onTimeout(@NotNull T timedOutObject, @NotNull StatefulWebServiceManager manager); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy