KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > extensions > wsrm > ReliableMessagingHandler


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2002 The Apache Software Foundation. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution,
20  * if any, must include the following acknowledgment:
21  * "This product includes software developed by the
22  * Apache Software Foundation (http://www.apache.org/)."
23  * Alternately, this acknowledgment may appear in the software itself,
24  * if and wherever such third-party acknowledgments normally appear.
25  *
26  * 4. The names "Axis" and "Apache Software Foundation" must
27  * not be used to endorse or promote products derived from this
28  * software without prior written permission. For written
29  * permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache",
32  * nor may "Apache" appear in their name, without prior written
33  * permission of the Apache Software Foundation.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation. For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  */

54 package extensions.wsrm;
55
56 import org.apache.axis.handlers.BasicHandler;
57 import org.apache.axis.MessageContext;
58 import org.apache.axis.AxisFault;
59 import org.apache.axis.Message;
60 import org.apache.axis.message.SOAPHeaderElement;
61 import org.apache.axis.message.MessageElement;
62 import org.apache.axis.message.SOAPEnvelope;
63 import org.apache.axis.message.PrefixedQName;
64
65 import javax.xml.soap.SOAPException JavaDoc;
66 import java.util.Iterator JavaDoc;
67 import java.util.Map JavaDoc;
68 import java.util.HashMap JavaDoc;
69 import java.util.Date JavaDoc;
70
71 public class ReliableMessagingHandler extends BasicHandler implements RMConstants {
72     static Map JavaDoc sequences = new HashMap JavaDoc();
73
74     public ReliableMessagingHandler() {
75     }
76
77     /**
78      * Invoke is called to do the actual work of the Handler object.
79      * If there is a fault during the processing of this method it is
80      * invoke's job to catch the exception and undo any partial work
81      * that has been completed. Once we leave 'invoke' if a fault
82      * is thrown, this classes 'onFault' method will be called.
83      * Invoke should rethrow any exceptions it catches, wrapped in
84      * an AxisFault.
85      */

86     public void invoke(MessageContext msgContext) throws AxisFault {
87         SOAPEnvelope req = msgContext.getRequestMessage().getSOAPEnvelope();
88         SOAPHeaderElement header = req.getHeaderByName(NS_URI_WSRM, "Sequence");
89         if (header == null)
90             return;
91
92         Iterator JavaDoc i = header.getChildElements(new PrefixedQName(NS_URI_WSU, "Identifier", null));
93         if (!i.hasNext()) {
94             // return fault
95
throw new AxisFault("WSRM.Fault", "Missing identifier in Sequence", null, null);
96         }
97
98         MessageElement el = (MessageElement)i.next();
99         String JavaDoc id = el.getValue();
100         Sequence seq = (Sequence)sequences.get(id);
101         if (seq == null) {
102             seq = new Sequence(id);
103             sequences.put(id, seq);
104         }
105
106         i = header.getChildElements(new PrefixedQName(NS_URI_WSRM, "MessageNumber", null));
107         el = (MessageElement)i.next();
108
109         // We've received a message with a given ID.
110
int seqNum = Integer.parseInt(el.getValue());
111         int nextSeq = seq.maxReceived + 1;
112         if (seqNum < nextSeq) {
113             Integer JavaDoc s = new Integer JavaDoc(seqNum);
114             if (seq.missing.contains(s)) {
115                 seq.missing.remove(s);
116             }
117         } else {
118             if (seqNum > nextSeq) {
119                 // Missing everything between maxReceived and this
120
for (int n = nextSeq; n < seqNum; n++) {
121                     seq.missing.add(new Integer JavaDoc(n));
122                 }
123             }
124             seq.maxReceived = seqNum;
125         }
126
127         header.setProcessed(true);
128
129         String JavaDoc from = null;
130         header = req.getHeaderByName(NS_URI_WSA, "From");
131         if (header != null) {
132             i = header.getChildElements(new PrefixedQName(NS_URI_WSA, "Address", null));
133             if (!i.hasNext()) {
134                 throw new AxisFault("WSRM.NoAddress", "No <Address> element in <From> header", null, null);
135             }
136             el = (MessageElement)i.next();
137             from = el.getValue();
138             header.setProcessed(true);
139         }
140
141         msgContext.setProperty("wsrm.From", from);
142
143         // Always schedule an async ack if there's a valid From
144
boolean doSynchronousAcks = (URI_ANONYMOUS.equals(from));
145
146         if (seq.endpoint == null)
147             seq.endpoint = from;
148
149         if (!doSynchronousAcks) {
150             AckTask.getSingleton().scheduleAck(seq);
151         } else {
152             Message respMsg = msgContext.getResponseMessage();
153             if (respMsg == null) {
154                 respMsg = new Message(new SOAPEnvelope());
155                 msgContext.setResponseMessage(respMsg);
156             }
157             SOAPEnvelope env = respMsg.getSOAPEnvelope();
158             try {
159                 generateAck(env, seq);
160             } catch (SOAPException JavaDoc e) {
161                 e.printStackTrace(); //To change body of catch statement use Options | File Templates.
162
}
163         }
164
165         header = req.getHeaderByName(NS_URI_WSA, "To");
166         if (header != null) {
167             header.setProcessed(true);
168         }
169
170         header = req.getHeaderByName(NS_URI_WSA, "MessageID");
171         if (header != null) {
172             header.setProcessed(true);
173         }
174
175         header = req.getHeaderByName(NS_URI_WSA, "Action");
176         if (header != null) {
177             header.setProcessed(true);
178         }
179
180     }
181
182     public static void generateAck(SOAPEnvelope env, Sequence seq) throws SOAPException JavaDoc {
183         SOAPHeaderElement seqHeader = new SOAPHeaderElement(NS_URI_WSRM, "SequenceAcknowledgement");
184         seqHeader.setMustUnderstand(true);
185         MessageElement el = new MessageElement(IDENTIFIER_QNAME, seq.id);
186         seqHeader.addChild(el);
187
188         Iterator JavaDoc i = seq.missing.iterator();
189         int lastMissing = 1;
190         while (i.hasNext()) {
191             int id = ((Integer JavaDoc)i.next()).intValue();
192             ackRange(lastMissing, id - 1, seqHeader);
193             lastMissing = id + 1;
194         }
195         ackRange(lastMissing, seq.maxReceived, seqHeader);
196
197         env.addHeader(seqHeader);
198         SOAPHeaderElement actionHeader = new SOAPHeaderElement(NS_URI_WSA, "Action", URI_ACK);
199         actionHeader.setMustUnderstand(true);
200         env.addHeader(actionHeader);
201
202         SOAPHeaderElement toHeader = new SOAPHeaderElement(NS_URI_WSA, "To", seq.endpoint);
203         env.addHeader(toHeader);
204
205         SOAPHeaderElement idHeader = new SOAPHeaderElement(NS_URI_WSA, "MessageID", generateNewMsgID());
206         idHeader.setMustUnderstand(true);
207         env.addHeader(idHeader);
208     }
209
210     public static void ackRange(int start, int end, SOAPHeaderElement seqHeader) throws SOAPException JavaDoc {
211         if (start > end) return;
212
213         MessageElement rangeEl = new MessageElement(NS_URI_WSRM, "AcknowledgementRange");
214         rangeEl.addAttribute("", "Upper", String.valueOf(end));
215         rangeEl.addAttribute("", "Lower", String.valueOf(start));
216         seqHeader.addChild(rangeEl);
217     }
218
219     public static synchronized String JavaDoc generateNewMsgID() {
220         return "urn:messageID-" + new Date JavaDoc().getTime();
221     }
222
223     public static synchronized String JavaDoc generateNewIdentifier() {
224         return "urn:identifier-" + new Date JavaDoc().getTime();
225     }
226
227 }
228
Popular Tags