001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: package com.sun.xml.ws.api.pipe;
038:
039: import com.sun.istack.NotNull;
040: import com.sun.xml.ws.api.message.Message;
041: import com.sun.xml.ws.api.message.Packet;
042: import com.sun.xml.ws.api.pipe.helper.AbstractFilterTubeImpl;
043: import com.sun.xml.ws.api.pipe.helper.AbstractTubeImpl;
044: import com.sun.xml.ws.api.server.Adapter;
045:
046: import javax.annotation.PreDestroy;
047: import javax.xml.ws.Dispatch;
048: import javax.xml.ws.Provider;
049: import javax.xml.ws.WebServiceException;
050: import javax.xml.ws.handler.LogicalHandler;
051: import javax.xml.ws.handler.soap.SOAPHandler;
052: import java.text.SimpleDateFormat;
053:
054: /**
055: * Abstraction of the intermediate layers in the processing chain
056: * and transport.
057: *
058: * <h2>What is a {@link Tube}?</h2>
059: * <p>
060: * {@link Tube} is a basic processing unit that represents SOAP-level
061: * protocol handling code. Mutliple tubes are often put together in
062: * a line (it needs not one dimensional — more later), and act on
063: * {@link Packet}s in a sequential fashion.
064: *
065: * <p>
066: * {@link Tube}s run asynchronously. That is, there is no guarantee that
067: * {@link #processRequest(Packet)} and {@link #processResponse(Packet)} runs
068: * in the same thread, nor is there any guarantee that this tube and next
069: * tube runs in the same thread. Furthermore, one thread may be used to
070: * run multiple pipeline in turn (just like a real CPU runs multiple
071: * threads in turn.)
072: *
073: *
074: * <h2>Tube examples</h2>
075: * <p>
076: * Transport is a kind of tube. It sends the {@link Packet}
077: * through, say, HTTP connection, and receives the data back into another {@link Packet}.
078: *
079: * <p>
080: * More often, a tube works like a filter. It acts on a packet,
081: * and then it tells the JAX-WS that the packet should be passed into another
082: * tube. It can do the same on the way back.
083: *
084: * <p>
085: * For example, XWSS will be a {@link Tube}. It will act on a request
086: * {@link Packet}, then perhaps wrap it into
087: * another {@link Packet} to encrypt the body and add a header, then
088: * the processing will go on to the next tube.
089: *
090: * <p>
091: * Yet another kind of filter tube is those that wraps {@link LogicalHandler}
092: * and {@link SOAPHandler}. These tubes are heavy-weight; they often consume
093: * a message in a packet and create a new one, and then pass it to the next tube.
094: *
095: * <p>
096: * There would be a {@link Tube} implementation that invokes {@link Provider}.
097: * There would be a {@link Tube} implementation that invokes a service method
098: * on the user's code.
099: * There would be a {@link Dispatch} implementation that invokes a {@link Tube}.
100: *
101: * <p>
102: * WS-MEX can be implemented as a {@link Tube} that looks for
103: * {@link Message#getPayloadNamespaceURI()} and serves the request.
104: *
105: *
106: *
107: *
108: * <h2>Tube Lifecycle</h2>
109: * Pipeline is expensive to set up, so once it's created it will be reused.
110: * A pipeline is not reentrant; one pipeline is used to process one request/response
111: * at at time. The same pipeline instance may serve multiple request/response,
112: * if one comes after another and they don't overlap.
113: * <p>
114: * Where a need arises to process multiple requests concurrently, a pipeline
115: * gets cloned through {@link TubeCloner}. Note that this need may happen on
116: * both server (because it quite often serves multiple requests concurrently)
117: * and client (because it needs to support asynchronous method invocations.)
118: * <p>
119: * Created pipelines (including cloned ones and the original) may be discarded and GC-ed
120: * at any time at the discretion of whoever owns pipelines. Tubes can, however, expect
121: * at least one copy (or original) of pipeline to live at any given time while a pipeline
122: * owner is interested in the given pipeline configuration (in more concerete terms,
123: * for example, as long as a dispatch object lives, it's going to keep at least one
124: * copy of a pipeline alive.)
125: * <p>
126: * Before a pipeline owner dies, it may invoke {@link #preDestroy()} on the last
127: * remaining pipeline. It is "may" for pipeline owners that live in the client-side
128: * of JAX-WS (such as dispatches and proxies), but it is a "must" for pipeline owners
129: * that live in the server-side of JAX-WS.
130: * <p>
131: * This last invocation gives a chance for some pipes to clean up any state/resource
132: * acquired (such as WS-RM's sequence, WS-Trust's SecurityToken), although as stated above,
133: * this is not required for clients.
134: *
135: *
136: *
137: * <h2>Tube and state</h2>
138: * <p>
139: * The lifecycle of pipelines is designed to allow a {@link Tube} to store various
140: * state in easily accessible fashion.
141: *
142: *
143: * <h3>Per-packet state</h3>
144: * <p>
145: * Any information that changes from a packet to packet should be
146: * stored in {@link Packet} (if such informaton is specific to your problem domain,
147: * then most likely {@link Packet#invocationProperties}.)
148: * This includes information like transport-specific headers.
149: *
150: * <h3>Per-thread state</h3>
151: * <p>
152: * Any expensive-to-create objects that are non-reentrant can be stored
153: * either in instance variables of a {@link Tube}, or a static {@link ThreadLocal}.
154: *
155: * <p>
156: * The first approach works, because {@link Tube} is
157: * non reentrant. When a tube is copied, new instances should be allocated
158: * so that two {@link Tube} instances don't share thread-unsafe resources.
159: *
160: * Similarly the second approach works, since {@link ThreadLocal} guarantees
161: * that each thread gets its own private copy.
162: *
163: * <p>
164: * The former is faster to access, and you need not worry about clean up.
165: * On the other hand, because there can be many more concurrent requests
166: * than # of threads, you may end up holding onto more resources than necessary.
167: *
168: * <p>
169: * This includes state like canonicalizers, JAXB unmarshallers,
170: * {@link SimpleDateFormat}, etc.
171: *
172: *
173: * <h3>Per-proxy/per-endpoint state</h3>
174: * <p>
175: * Information that is tied to a particular proxy/dispatch can be stored
176: * in a separate object that is referenced from a tube. When
177: * a new tube is copied, you can simply hand out a reference to the newly
178: * created one, so that all copied tubes refer to the same instance.
179: * See the following code as an example:
180: *
181: * <pre>
182: * class TubeImpl {
183: * // this object stores per-proxy state
184: * class DataStore {
185: * int counter;
186: * }
187: *
188: * private DataStore ds;
189: *
190: * // create a fresh new pipe
191: * public TubeImpl(...) {
192: * ....
193: * ds = new DataStore();
194: * }
195: *
196: * // copy constructor
197: * private TubeImpl(TubeImpl that, PipeCloner cloner) {
198: * cloner.add(that,this);
199: * ...
200: * this.ds = that.ds;
201: * }
202: *
203: * public TubeImpl copy(PipeCloner pc) {
204: * return new TubeImpl(this,pc);
205: * }
206: * }
207: * </pre>
208: *
209: * <p>
210: * Note that access to such resource may need to be synchronized,
211: * since multiple copies of pipelines may execute concurrently.
212: *
213: *
214: *
215: * <h3>VM-wide state</h3>
216: * <p>
217: * <tt>static</tt> is always there for you to use.
218: *
219: *
220: *
221: * @see AbstractTubeImpl
222: * @see AbstractFilterTubeImpl
223: *
224: * @author Kohsuke Kawaguchi
225: * @author Jitendra Kotamraju
226: */
227: public interface Tube {
228: /**
229: * Acts on a request and perform some protocol specific operation.
230: *
231: * TODO: exception handling semantics need more discussion
232: *
233: * @throws WebServiceException
234: * On the server side, this signals an error condition where
235: * a fault reply is in order (or the exception gets eaten by
236: * the top-most transport {@link Adapter} if it's one-way.)
237: * This frees each {@link Tube} from try/catching a
238: * {@link WebServiceException} in every layer.
239: *
240: * Note that this method is also allowed to return
241: * {@link NextAction#returnWith(Packet)} with
242: * a {@link Packet} that has a fault as the payload.
243: *
244: * <p>
245: * On the client side, the {@link WebServiceException} thrown
246: * will be propagated all the way back to the calling client
247: * applications. (The consequence of that is that if you are
248: * a filtering {@link Tube}, you must not eat the exception
249: * that was given to {@link #processException(Throwable)} .
250: *
251: * @throws RuntimeException
252: * Other runtime exception thrown by this method must
253: * be treated as a bug in the tube implementation,
254: * and therefore should not be converted into a fault.
255: * (Otherwise it becomes very difficult to debug implementation
256: * problems.)
257: *
258: * <p>
259: * On the server side, this exception should be most likely
260: * just logged. On the client-side it gets propagated to the
261: * client application.
262: *
263: * <p>
264: * The consequence of this is that if a pipe calls
265: * into an user application (such as {@link SOAPHandler}
266: * or {@link LogicalHandler}), where a {@link RuntimeException}
267: * is *not* a bug in the JAX-WS implementation, it must be catched
268: * and wrapped into a {@link WebServiceException}.
269: *
270: * @param request
271: * The packet that represents a request message.
272: * If the packet has a non-null message, it must be a valid
273: * unconsumed {@link Message}. This message represents the
274: * SOAP message to be sent as a request.
275: * <p>
276: * The packet is also allowed to carry no message, which indicates
277: * that this is an output-only request.
278: * (that's called "solicit", right? - KK)
279: *
280: * @return
281: * A {@link NextAction} object that represents the next action
282: * to be taken by the JAX-WS runtime.
283: */
284: @NotNull
285: NextAction processRequest(@NotNull
286: Packet request);
287:
288: /**
289: * Acts on a response and performs some protocol specific operation.
290: *
291: * <p>
292: * Once a {@link #processRequest(Packet)} is invoked, this method
293: * will be always invoked with the response, before this {@link Tube}
294: * processes another request.
295: *
296: * @param response
297: * If the packet has a non-null message, it must be
298: * a valid unconsumed {@link Message}. This message represents
299: * a response to the request message passed to
300: * {@link #processRequest(Packet)} earlier.
301: * <p>
302: * The packet is also allowed to carry no message, which indicates
303: * that there was no response. This is used for things like
304: * one-way message and/or one-way transports.
305: *
306: * TODO: exception handling semantics need more discussion
307: *
308: * @return
309: * A {@link NextAction} object that represents the next action
310: * to be taken by the JAX-WS runtime.
311: */
312: @NotNull
313: NextAction processResponse(@NotNull
314: Packet response);
315:
316: /**
317: * Acts on a exception and performs some clean up operations.
318: *
319: * <p>
320: * If a {@link #processRequest(Packet)}, {@link #processResponse(Packet)},
321: * {@link #processException(Throwable)} throws an exception, this method
322: * will be always invoked on all the {@link Tube}s in the remaining
323: * {@link NextAction}s.
324: *
325: * <p>
326: * On the server side, the {@link Throwable} thrown will be propagated to the
327: * top-most transport. The transport converts the exception to fault reply or
328: * simply logs in case of one-way MEP. If you are a filtering {@link Tube} like
329: * {@link AbstractTubeImpl}, you don't have to override the implementation). On
330: * the other hand, any intermediate {@link Tube} may want to convert the exception
331: * to a fault message.
332: *
333: * <p>
334: * On the client side, the {@link Throwable} thrown
335: * will be propagated all the way back to the calling client
336: * applications. (The consequence of that is that if you are
337: * a filtering {@link Tube} like {@link AbstractTubeImpl}, you don't have to
338: * override the implementation)
339: *
340: * @param t
341: *
342: * @return
343: * A {@link NextAction} object that represents the next action
344: * to be taken by the JAX-WS runtime.
345: */
346: @NotNull
347: NextAction processException(@NotNull
348: Throwable t);
349:
350: /**
351: * Invoked before the last copy of the pipeline is about to be discarded,
352: * to give {@link Tube}s a chance to clean up any resources.
353: *
354: * <p>
355: * This can be used to invoke {@link PreDestroy} lifecycle methods
356: * on user handler. The invocation of it is optional on the client side,
357: * but mandatory on the server side.
358: *
359: * <p>
360: * When multiple copies of pipelines are created, this method is called
361: * only on one of them.
362: *
363: * @throws WebServiceException
364: * If the clean up fails, {@link WebServiceException} can be thrown.
365: * This exception will be propagated to users (if this is client),
366: * or recorded (if this is server.)
367: */
368: void preDestroy();
369:
370: /**
371: * Creates an identical clone of this {@link Tube}.
372: *
373: * <p>
374: * This method creates an identical pipeline that can be used
375: * concurrently with this pipeline. When the caller of a pipeline
376: * is multi-threaded and need concurrent use of the same pipeline,
377: * it can do so by creating copies through this method.
378: *
379: * <h3>Implementation Note</h3>
380: * <p>
381: * It is the implementation's responsibility to call
382: * {@link TubeCloner#add(Tube,Tube)} to register the copied pipe
383: * with the original. This is required before you start copying
384: * the other {@link Tube} references you have, or else there's a
385: * risk of infinite recursion.
386: * <p>
387: * For most {@link Tube} implementations that delegate to another
388: * {@link Tube}, this method requires that you also copy the {@link Tube}
389: * that you delegate to.
390: * <p>
391: * For limited number of {@link Tube}s that do not maintain any
392: * thread unsafe resource, it is allowed to simply return <tt>this</tt>
393: * from this method (notice that even if you are stateless, if you
394: * got a delegating {@link Tube} and that one isn't stateless, you
395: * still have to copy yourself.)
396: *
397: * <p>
398: * Note that this method might be invoked by one thread while another
399: * thread is executing the other process method. See
400: * the {@link Codec#copy()} for more discussion about this.
401: *
402: * @param cloner
403: * Use this object (in particular its {@link TubeCloner#copy(Tube)} method
404: * to clone other pipe references you have
405: * in your pipe. See {@link TubeCloner} for more discussion
406: * about why.
407: *
408: * @return
409: * always non-null {@link Tube}.
410: * @param cloner
411: */
412: Tube copy(TubeCloner cloner);
413: }
|