KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > drda > DRDAXAProtocol


1 /*
2
3    Derby - Class org.apache.derby.impl.drda.DRDAXAProtocol.java
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 /**
23  * This class translates DRDA XA protocol from an application requester to XA
24  * calls for Derby and then translates the results from Derby to DRDA
25  * for return to the application requester.
26  * This class requires the use of javax.transaction.xa classes from j2ee,
27  * so is separated from DRDAConnThread, because of the additional
28  * library requirements
29  * @author kmarsden@Sourcery.Org
30  */

31
32
33 package org.apache.derby.impl.drda;
34 import org.apache.derby.iapi.services.sanity.SanityManager;
35 import javax.transaction.xa.*;
36
37
38 class DRDAXAProtocol {
39
40     private DRDAConnThread connThread;
41     private DDMReader reader;
42     private DDMWriter writer;
43
44
45     DRDAXAProtocol(DRDAConnThread connThread)
46     {
47         this.connThread = connThread;
48         reader = connThread.getReader();
49         writer = connThread.getWriter();
50
51     }
52
53
54
55     /**
56      * Parse SYNCCTL - Parse SYNCCTL command for XAMGR lvl 7
57      *
58      */

59     protected void parseSYNCCTL() throws DRDAProtocolException
60     {
61         
62         reader.markCollection();
63         
64         int codePoint = reader.getCodePoint(CodePoint.SYNCTYPE);
65         int syncType = parseSYNCTYPE();
66         
67         int xaflags = 0;
68         boolean readXAFlags = false;
69         Xid xid = null;
70
71         codePoint = reader.getCodePoint();
72         while (codePoint != -1)
73         {
74             switch(codePoint)
75             {
76                 case CodePoint.XID:
77                     xid = parseXID();
78                     break;
79                 case CodePoint.XAFLAGS:
80                     xaflags = parseXAFlags();
81                     readXAFlags =true;
82                     break;
83                 case CodePoint.TIMEOUT:
84                     // optional/ignorable.
85
reader.skipBytes();
86                     break;
87                 case CodePoint.RLSCONV:
88                     connThread.codePointNotSupported(codePoint);
89                 default:
90                     connThread.invalidCodePoint(codePoint);
91             }
92
93             codePoint = reader.getCodePoint();
94         }
95
96
97         {
98             connThread.trace("syncType = " + syncTypeToString(syncType));
99             connThread.trace("xid = " + xid);
100             connThread.trace("xaflags =" + xaflagsToString(xaflags));
101         }
102
103         if (syncType != CodePoint.SYNCTYPE_INDOUBT)
104         {
105             if (xid == null)
106                 connThread.missingCodePoint(CodePoint.XID);
107             
108             // All but Recover and forget require xaFlags
109
if (syncType != CodePoint.SYNCTYPE_REQ_FORGET &&
110                 ! readXAFlags)
111                 if (SanityManager.DEBUG)
112                     connThread.missingCodePoint(CodePoint.XAFLAGS);
113         }
114
115         switch (syncType)
116         {
117             case CodePoint.SYNCTYPE_NEW_UOW:
118                 // new unit of work for XA
119
// formatId -1 is just a local connection
120
startXATransaction(xid,xaflags);
121                 break;
122             case CodePoint.SYNCTYPE_END_UOW:
123                 // End unit of work
124
endXA(xid,xaflags);
125                 break;
126             case CodePoint.SYNCTYPE_PREPARE:
127                 prepareXATransaction(xid);
128                 // Prepare to commit
129
break;
130             case CodePoint.SYNCTYPE_MIGRATE:
131                 // migrate to resync server sync type
132
connThread.codePointNotSupported(codePoint);
133                 break;
134             case CodePoint.SYNCTYPE_REQ_COMMIT:
135                 // request to commit sync type
136
commitTransaction(xid,xaflags);
137                 break;
138             case CodePoint.SYNCTYPE_COMMITTED:
139                 // commit sync type
140
commitTransaction(xid, xaflags);
141                 break;
142             case CodePoint.SYNCTYPE_REQ_FORGET:
143                 // request to forget sync type
144
forgetXATransaction(xid);
145                 break;
146             case CodePoint.SYNCTYPE_ROLLBACK:
147                 //rollback sync type
148
rollbackTransaction(xid);
149                 break;
150             case CodePoint.SYNCTYPE_INDOUBT:
151                 //recover sync type
152
if (readXAFlags)
153                     recoverXA(xaflags);
154                 else
155                     recoverXA();
156                 break;
157             default:
158                 connThread.invalidCodePoint(codePoint);
159         }
160
161     }
162
163     /**
164      * parse SYNCTYPE for XAMGR lvl 7
165      * return synctype value
166      * CodePoint.SYNCTYPE_NEW_UOW -> XAResource.start()
167      * CodePoint.SYNCTYPE_END_UOW -> XAResource.end()
168      * CodePoint.SYNCTYPE_PREPARE -> XAResource.prepare()
169      * CodePoint.SYNCTYPE_MIGRATE -> not supported //SYNCPT MGR LEVEL 5
170      * CodePoint.SYNCTYPE_REQ_COMMIT -> not supported //SYNCPT MGR LEVEL 5
171      * CodePoint.SYNCTYPE_COMMITTED -> XAResource.commit()
172      * or local commit for null XID
173      * CodePoint.SYNCTYPE_REQ_LOG -> not supported
174      * CodePoint.SYNCTYPE_REQ_FORGET -> XAResource.forget()
175      * CodePoint.SYNCTYPE_ROLLBACK -> XAResource.rollback()
176      * CodePoint.SYNCTYPE_MIGRATED -> not supported
177      * CodePoint.SYNCTYPE_INDOUBT -> XAResource.recover();
178      *
179      */

180     protected int parseSYNCTYPE() throws DRDAProtocolException
181     {
182         return reader.readUnsignedByte();
183         
184     }
185     
186
187     /** Parse XID
188      * formatId -1 translates into a null XID and a local transaction
189      */

190     private Xid parseXID () throws DRDAProtocolException
191     {
192         int formatId = reader.readNetworkInt();
193         byte[] gtrid = null;
194         byte[] bqual = null;
195         if (formatId != -1)
196         {
197             int gtridLen = reader.readNetworkInt();
198             int bqualLen = reader.readNetworkInt();
199             
200             gtrid = reader.readBytes(gtridLen);
201             bqual = reader.readBytes(bqualLen);
202         }
203         return new DRDAXid(formatId, gtrid, bqual);
204     }
205
206
207     /**
208      * parse XIDSHR
209      *
210      * @return XIDSHR value
211      * @throws DRDAProtocolException
212      */

213     private int parseXIDSHR() throws DRDAProtocolException
214     {
215         return reader.readUnsignedByte();
216     }
217
218     /**
219      * parse XAFlags
220      *
221      * @return XAFlags value
222      * @throws DRDAProtocolException
223      */

224     private int parseXAFlags() throws DRDAProtocolException
225     {
226         return reader.readNetworkInt();
227     }
228
229
230     /**
231      * Start the xa transaction. Send SYNCRRD response
232      *
233      * @param xid - XID (formatId = -1 for local transaction)
234      * @param xaflags - xaflags
235      * @throws DRDAProtocolException
236      */

237     private void startXATransaction(Xid xid, int xaflags) throws DRDAProtocolException
238     {
239         XAResource xaResource = getXAResource();
240         int xaRetVal = xaResource.XA_OK;
241
242         try {
243             if (xid.getFormatId() != -1)
244                 xaResource.start(xid,xaflags);
245         } catch (XAException xe)
246         {
247             xaRetVal = processXAException(xe);
248         }
249         writeSYNCCRD(CodePoint.SYNCTYPE_NEW_UOW,
250                      xaRetVal, null);
251         
252     }
253     
254
255     /**
256      * Commit the xa transaction. Send SYNCCRD response
257      *
258      * @param xid - XID (formatId = -1 for local transaction)
259      * @param xaflags - xaflags
260      * @throws DRDAProtocolException
261      */

262     private void commitTransaction(Xid xid, int xaflags) throws DRDAProtocolException
263     {
264         boolean local = ( xid.getFormatId() == -1);
265         if (local)
266             commitLocalTransaction();
267         else
268             commitXATransaction(xid, xaflags);
269     }
270
271     /**
272      * Commit local transaction. Send SYNCCRD response.
273      *
274      * @throws DRDAProtocolException
275      */

276     private void commitLocalTransaction() throws DRDAProtocolException
277     {
278         int xaRetVal = XAResource.XA_OK;
279         try {
280             connThread.getDatabase().commit();
281         }
282         catch (Exception JavaDoc e)
283         {
284             xaRetVal = XAException.XAER_RMFAIL;
285             if (SanityManager.DEBUG)
286             {
287                 connThread.getServer().consoleExceptionPrint(e);
288             }
289
290         }
291         writeSYNCCRD(CodePoint.SYNCTYPE_COMMITTED,
292                      xaRetVal, null);
293
294     }
295
296     
297     /**
298      * Commit the xa transaction. Send SYNCCRD response.
299      *
300      * @param xid - XID
301      * @param xaflags - xaflags
302      * @throws DRDAProtocolException
303      */

304     private void commitXATransaction(Xid xid, int xaflags) throws DRDAProtocolException
305     {
306         XAResource xaResource = getXAResource();
307         int xaRetVal = xaResource.XA_OK;
308         // check this
309
boolean isOnePhase = (xaflags & XAResource.TMONEPHASE) != 0;
310         try {
311             xaResource.commit(xid, isOnePhase);
312             if (SanityManager.DEBUG)
313                 connThread.trace("committed XA transaction: xaRetVal=" + xaRetVal);
314
315         } catch (XAException xe)
316         {
317             xaRetVal = processXAException(xe);
318         }
319         writeSYNCCRD(CodePoint.SYNCTYPE_COMMITTED,
320                      xaRetVal, null);
321         
322     }
323
324     /**
325      * Rollback transaction
326      * @param xid Xid for rollback for global transaction.
327      * If xid formatid is -1 it represents a local transaction
328      */

329     private void rollbackTransaction(Xid xid) throws DRDAProtocolException
330     {
331         boolean local = ( xid.getFormatId() == -1);
332         if (local)
333             rollbackLocalTransaction();
334         else
335             rollbackXATransaction(xid);
336     }
337     
338     /**
339      * Rollback a local transaction
340      *
341      */

342     private void rollbackLocalTransaction() throws DRDAProtocolException
343     {
344         int xaRetVal = XAResource.XA_OK;
345         try {
346             connThread.getDatabase().rollback();
347         }
348         catch (Exception JavaDoc e)
349         {
350             xaRetVal = XAException.XAER_RMFAIL;
351             if (SanityManager.DEBUG)
352             {
353                 connThread.getServer().consoleExceptionPrint(e);
354             }
355             
356         }
357         writeSYNCCRD(CodePoint.SYNCTYPE_COMMITTED,
358                      xaRetVal, null);
359
360     }
361
362     /**
363      * Rollback the xa transaction. Send SYNCCRD response.
364      *
365      * @param xid - XID
366      * @throws DRDAProtocolException
367      */

368     private void rollbackXATransaction(Xid xid) throws DRDAProtocolException
369     {
370         XAResource xaResource = getXAResource();
371         int xaRetVal = xaResource.XA_OK;
372
373         try {
374             xaResource.rollback(xid);
375             if (SanityManager.DEBUG)
376             {
377                 connThread.trace("rollback XA transaction: xaRetVal=" + xaRetVal);
378             }
379         } catch (XAException xe)
380         {
381             xaRetVal = processXAException(xe);
382         }
383         writeSYNCCRD(CodePoint.SYNCTYPE_ROLLBACK,
384                      xaRetVal, null);
385         
386     }
387
388     /**
389      * End the xa transaction. Send SYNCRRD response
390      *
391      * @param xid - XID
392      * @param xaflags - xaflags
393      * @throws DRDAProtocolException
394      */

395     private void endXA(Xid xid, int xaflags) throws DRDAProtocolException
396     {
397         XAResource xaResource = getXAResource();
398         int xaRetVal = xaResource.XA_OK;
399
400         try {
401             xaResource.end(xid,xaflags);
402             if (SanityManager.DEBUG)
403             {
404                 connThread.trace("ended XA transaction. xid = " + xid +
405                                " xaflags =" + xaflags +
406                                  "xaRetVal=" + xaRetVal);
407             }
408         } catch (XAException xe)
409         {
410             xaRetVal = processXAException(xe);
411         }
412         writeSYNCCRD(CodePoint.SYNCTYPE_END_UOW,
413                      xaRetVal, null);
414     }
415
416
417     /**
418      * Prepare the xa transaction. Send SYNCCRD response.
419      *
420      * @param xid - XID
421      * @throws DRDAProtocolException
422      */

423     private void prepareXATransaction(Xid xid) throws DRDAProtocolException
424     {
425         XAResource xaResource = getXAResource();
426         int xaRetVal = xaResource.XA_OK;
427
428         try {
429             xaRetVal = xaResource.prepare(xid);
430             if (SanityManager.DEBUG)
431             {
432                 connThread.trace("prepared xa transaction: xaRetVal=" +
433                                 xaRetVal);
434             }
435         } catch (XAException xe)
436         {
437             xaRetVal = processXAException(xe);
438         }
439         writeSYNCCRD(CodePoint.SYNCTYPE_PREPARE,
440                      xaRetVal, null);
441     }
442
443     /**
444      * Forget the xa transaction. Send SYNCCRD response.
445      *
446      * @param xid - XID
447      * @throws DRDAProtocolException
448      */

449     private void forgetXATransaction(Xid xid) throws DRDAProtocolException
450     {
451         XAResource xaResource = getXAResource();
452         int xaRetVal = xaResource.XA_OK;
453
454         try {
455             xaResource.forget(xid);
456             if (SanityManager.DEBUG)
457             {
458                 connThread.trace("forgot xa transaction: xaRetVal=" + xaRetVal);
459             }
460         } catch (XAException xe)
461         {
462             xaRetVal = processXAException(xe);
463         }
464         writeSYNCCRD(CodePoint.SYNCTYPE_REQ_FORGET,
465                      xaRetVal, null);
466     }
467
468     // JCC doesn't send xaflags but always wants TMSTARTRSCAN.
469
//So default to that if we got no xaflags
470
private void recoverXA() throws DRDAProtocolException
471     {
472         recoverXA(XAResource.TMSTARTRSCAN);
473     }
474
475     /**
476      * Call recover. Send SYNCCRD response with indoubt list
477      *
478      * @throws DRDAProtocolException
479      */

480     private void recoverXA(int xaflags) throws DRDAProtocolException
481     {
482         XAResource xaResource = getXAResource();
483         int xaRetVal = xaResource.XA_OK;
484         Xid[] indoubtXids = null;
485         try {
486             indoubtXids = xaResource.recover(xaflags);
487         } catch (XAException xe)
488         {
489             xaRetVal = processXAException(xe);
490         }
491         writeSYNCCRD(CodePoint.SYNCTYPE_INDOUBT,
492                      xaRetVal, indoubtXids);
493     }
494
495     /** Write SYNCCRD (SYNCCTL response)
496      * @param synctype - XA Command to send response for see parseSYNCTYPE
497      * @param xaRetVal - return value from XA command
498      * @param xids - list of xids to return for recover.
499      * null for other commands
500      * @throws DRDAProtocolException
501      */

502     private void writeSYNCCRD (int synctype, int xaRetVal, Xid[] xids) throws DRDAProtocolException
503     {
504         writer.createDssReply();
505         writer.startDdm(CodePoint.SYNCCRD);
506         writer.startDdm(CodePoint.XARETVAL);
507         writer.writeInt(xaRetVal);
508         writer.endDdm();
509         if (xids != null)
510             writePRPHRCLST(xids);
511         writer.endDdmAndDss();
512     }
513
514     /** write PRPHRCLST (indoubt list)
515      *
516      * @param xids - list of indoubt xa transactions obtained from recover
517      * @throws DRDAProtocolException
518      */

519     private void writePRPHRCLST(Xid[] xids) throws DRDAProtocolException
520     {
521         int xidcnt = (xids == null ? 0 : xids.length);
522         writer.startDdm(CodePoint.PRPHRCLST);
523         writer.writeScalar2Bytes(CodePoint.XIDCNT, xidcnt);
524         for (int i = 0; i < xidcnt; i++)
525             writeXID(xids[i]);
526         writer.endDdm();
527     }
528
529     /** write XID
530      *
531      * @param xid - XID to write
532      * @throws DRDAProtocolException
533      */

534     
535     private void writeXID(Xid xid) throws DRDAProtocolException
536     {
537         writer.startDdm(CodePoint.XID);
538         int formatId = xid.getFormatId();
539         byte[] gtrid = xid.getGlobalTransactionId();
540         byte[] bqual = xid.getBranchQualifier();
541         
542         writer.writeInt(formatId);
543         writer.writeInt(gtrid.length);
544         writer.writeInt(bqual.length);
545         writer.writeBytes(gtrid);
546         writer.writeBytes(bqual);
547         writer.endDdm();
548     }
549     
550
551     /** get XAResource for the connection
552      *
553      * @return XAResource
554      */

555     private XAResource getXAResource()
556     {
557         return ((XADatabase) connThread.getDatabase()).getXAResource();
558         
559     }
560     
561     /** printable syncType for debug output
562      * @param syncType
563      * @return - sync type meaning
564      */

565     private String JavaDoc syncTypeToString(int syncType)
566     {
567         switch (syncType)
568         {
569             case CodePoint.SYNCTYPE_NEW_UOW:
570                 return "SYNCTYPE_NEW_UOW";
571                 
572             case CodePoint.SYNCTYPE_END_UOW:
573                 return "SYNCTYPE_END_UOW";
574                 
575             case CodePoint.SYNCTYPE_PREPARE:
576                 return "SYNCTYPE_PREPARE";
577                 
578             case CodePoint.SYNCTYPE_MIGRATE:
579                 return "SYNCTYPE_MIGRATE";
580                             
581             case CodePoint.SYNCTYPE_REQ_COMMIT:
582                 return "SYNCTYPE_REQ_COMMIT";
583                 
584             case CodePoint.SYNCTYPE_COMMITTED:
585                 return "SYNCTYPE_COMMITTED";
586                 
587             case CodePoint.SYNCTYPE_REQ_FORGET:
588                 return "SYNCTYPE_FORGET";
589                 
590             case CodePoint.SYNCTYPE_ROLLBACK:
591                 return "SYNCTYPE_ROLLBACK";
592                 
593             case CodePoint.SYNCTYPE_REQ_LOG:
594                 return "SYNCTYPE_REQ_LOG";
595                 
596             case CodePoint.SYNCTYPE_MIGRATED:
597                 return "SYNCTYPE_MIGRATED";
598                 
599             case CodePoint.SYNCTYPE_INDOUBT:
600                 return "SYNCTYPE_INDOUBT";
601                 
602             default:
603                 return "UNKNOWN SYNCTYPE";
604         }
605     }
606
607     /**
608      * printable xaflags
609      * @param xaflags
610      * @return printable xaflags for debug output
611      */

612     private String JavaDoc xaflagsToString(int xaflags)
613     {
614         switch (xaflags)
615         {
616             case XAResource.TMENDRSCAN :
617                 return "XAResource.TMENDRSCAN";
618                 
619             case XAResource.TMFAIL:
620                 return "XAResource.TMFAIL";
621                 
622             case XAResource.TMNOFLAGS:
623                 return "XAResource.TMNOFLAGS";
624                 
625             case XAResource.TMJOIN:
626                 return "XAResource.TMJOIN";
627                 
628             case XAResource.TMONEPHASE:
629                 return "XAResource.TMONEPHASE";
630                 
631             case XAResource.TMRESUME:
632                 return "XAResource.TMRESUME";
633                 
634             case XAResource.TMSTARTRSCAN:
635                 return "XAResource.TMSTARTRSCAN";
636                 
637             case XAResource.TMSUCCESS:
638                 return "XAResource.TMSUCCESS";
639                 
640             case XAResource.TMSUSPEND:
641                 return "XAResource.TMSUSPEND";
642                 
643             default:
644                 return "UNRECOGNIZED flags:" + xaflags;
645                 
646         }
647     }
648
649     /**
650      * return xa exception errorCode.
651      * print to console for debug output.
652      * @param xe - XA Exception
653      */

654     private int processXAException(XAException xe)
655     {
656         int xaRetVal = xe.errorCode;
657         if (SanityManager.DEBUG)
658         {
659             connThread.getServer().consoleExceptionPrint(xe);
660         }
661         return xaRetVal;
662     }
663
664 }
665
666
667
668
669
670
671
672
673
674
675
676
Popular Tags