001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.ws.rm.persistence.jdbc;
019:
020: import java.io.IOException;
021: import java.math.BigInteger;
022: import java.sql.SQLException;
023: import java.util.ArrayList;
024: import java.util.Collection;
025: import java.util.Date;
026:
027: import org.apache.cxf.ws.addressing.v200408.EndpointReferenceType;
028: import org.apache.cxf.ws.rm.DestinationSequence;
029: import org.apache.cxf.ws.rm.Identifier;
030: import org.apache.cxf.ws.rm.RMConstants;
031: import org.apache.cxf.ws.rm.RMUtils;
032: import org.apache.cxf.ws.rm.SequenceAcknowledgement;
033: import org.apache.cxf.ws.rm.SourceSequence;
034: import org.apache.cxf.ws.rm.persistence.RMMessage;
035: import org.apache.cxf.ws.rm.persistence.RMStoreException;
036: import org.easymock.classextension.EasyMock;
037: import org.easymock.classextension.IMocksControl;
038: import org.junit.AfterClass;
039: import org.junit.Assert;
040: import org.junit.Before;
041: import org.junit.BeforeClass;
042: import org.junit.Test;
043:
044: /**
045: *
046: */
047: public class RMTxStoreTest extends Assert {
048:
049: private static final String CLIENT_ENDPOINT_ID = "celtix.{http://celtix.objectweb.org/greeter_control}GreeterService/GreeterPort";
050: private static final String SERVER_ENDPOINT_ID = "celtix.{http://celtix.objectweb.org/greeter_control}GreeterService";
051: private static final String NON_ANON_ACKS_TO = "http://localhost:9999/decoupled_endpoint";
052:
053: private static RMTxStore store;
054: private static SequenceAcknowledgement ack1;
055: private static SequenceAcknowledgement ack2;
056:
057: private IMocksControl control;
058:
059: @BeforeClass
060: public static void setUpOnce() {
061:
062: RMTxStore.deleteDatabaseFiles();
063:
064: store = new RMTxStore();
065: store
066: .setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver");
067: store.init();
068:
069: ack1 = new SequenceAcknowledgement();
070: SequenceAcknowledgement.AcknowledgementRange range = new SequenceAcknowledgement.AcknowledgementRange();
071: range.setLower(BigInteger.ONE);
072: range.setUpper(BigInteger.ONE);
073: ack1.getAcknowledgementRange().add(range);
074:
075: ack2 = new SequenceAcknowledgement();
076: range = new SequenceAcknowledgement.AcknowledgementRange();
077: range.setLower(BigInteger.ONE);
078: range.setUpper(BigInteger.ONE);
079: ack2.getAcknowledgementRange().add(range);
080: range = new SequenceAcknowledgement.AcknowledgementRange();
081: range.setLower(new BigInteger("3"));
082: range.setUpper(BigInteger.TEN);
083: ack2.getAcknowledgementRange().add(range);
084: }
085:
086: @AfterClass
087: public static void tearDownOnce() {
088: /*
089: try {
090: store.getConnection().close();
091: } catch (SQLException ex) {
092: ex.printStackTrace();
093: }
094: */
095: RMTxStore.deleteDatabaseFiles(RMTxStore.DEFAULT_DATABASE_NAME,
096: false);
097: }
098:
099: @Before
100: public void setUp() {
101: control = EasyMock.createNiceControl();
102: }
103:
104: @Test
105: public void testCreateTables() throws SQLException {
106: // tables should have been created during initialisation
107: // but verify the operation is idempotent
108: store.createTables();
109: }
110:
111: @Test
112: public void testCreateDeleteSrcSequences() {
113: SourceSequence seq = control.createMock(SourceSequence.class);
114: Identifier sid1 = RMUtils.getWSRMFactory().createIdentifier();
115: sid1.setValue("sequence1");
116: EasyMock.expect(seq.getIdentifier()).andReturn(sid1);
117: EasyMock.expect(seq.getExpires()).andReturn(null);
118: EasyMock.expect(seq.getOfferingSequenceIdentifier()).andReturn(
119: null);
120: EasyMock.expect(seq.getEndpointIdentifier()).andReturn(
121: CLIENT_ENDPOINT_ID);
122:
123: control.replay();
124: store.createSourceSequence(seq);
125: control.verify();
126:
127: control.reset();
128: EasyMock.expect(seq.getIdentifier()).andReturn(sid1);
129: EasyMock.expect(seq.getExpires()).andReturn(null);
130: EasyMock.expect(seq.getOfferingSequenceIdentifier()).andReturn(
131: null);
132: EasyMock.expect(seq.getEndpointIdentifier()).andReturn(
133: CLIENT_ENDPOINT_ID);
134:
135: control.replay();
136: try {
137: store.createSourceSequence(seq);
138: fail("Expected RMStoreException was not thrown.");
139: } catch (RMStoreException ex) {
140: SQLException se = (SQLException) ex.getCause();
141: // duplicate key value
142: assertEquals("23505", se.getSQLState());
143: }
144: control.verify();
145:
146: control.reset();
147: Identifier sid2 = RMUtils.getWSRMFactory().createIdentifier();
148: sid2.setValue("sequence2");
149: EasyMock.expect(seq.getIdentifier()).andReturn(sid2);
150: EasyMock.expect(seq.getExpires()).andReturn(new Date());
151: Identifier sid3 = RMUtils.getWSRMFactory().createIdentifier();
152: sid3.setValue("offeringSequence3");
153: EasyMock.expect(seq.getOfferingSequenceIdentifier()).andReturn(
154: sid3);
155: EasyMock.expect(seq.getEndpointIdentifier()).andReturn(
156: SERVER_ENDPOINT_ID);
157:
158: control.replay();
159: store.createSourceSequence(seq);
160: control.verify();
161:
162: store.removeSourceSequence(sid1);
163: store.removeSourceSequence(sid2);
164:
165: // deleting once again is a no-op
166: store.removeSourceSequence(sid2);
167: }
168:
169: @Test
170: public void testCreateDeleteDestSequences() {
171: DestinationSequence seq = control
172: .createMock(DestinationSequence.class);
173: Identifier sid1 = RMUtils.getWSRMFactory().createIdentifier();
174: sid1.setValue("sequence1");
175: EndpointReferenceType epr = RMUtils
176: .createAnonymousReference2004();
177: EasyMock.expect(seq.getIdentifier()).andReturn(sid1);
178: EasyMock.expect(seq.getAcksTo()).andReturn(epr);
179: EasyMock.expect(seq.getEndpointIdentifier()).andReturn(
180: SERVER_ENDPOINT_ID);
181:
182: control.replay();
183: store.createDestinationSequence(seq);
184: control.verify();
185:
186: control.reset();
187: EasyMock.expect(seq.getIdentifier()).andReturn(sid1);
188: EasyMock.expect(seq.getAcksTo()).andReturn(epr);
189: EasyMock.expect(seq.getEndpointIdentifier()).andReturn(
190: SERVER_ENDPOINT_ID);
191:
192: control.replay();
193: try {
194: store.createDestinationSequence(seq);
195: fail("Expected RMStoreException was not thrown.");
196: } catch (RMStoreException ex) {
197: SQLException se = (SQLException) ex.getCause();
198: // duplicate key value
199: assertEquals("23505", se.getSQLState());
200: }
201: control.verify();
202:
203: control.reset();
204: Identifier sid2 = RMUtils.getWSRMFactory().createIdentifier();
205: sid2.setValue("sequence2");
206: EasyMock.expect(seq.getIdentifier()).andReturn(sid2);
207: epr = RMUtils.createReference2004(NON_ANON_ACKS_TO);
208: EasyMock.expect(seq.getAcksTo()).andReturn(epr);
209: EasyMock.expect(seq.getEndpointIdentifier()).andReturn(
210: CLIENT_ENDPOINT_ID);
211:
212: control.replay();
213: store.createDestinationSequence(seq);
214: control.verify();
215:
216: store.removeDestinationSequence(sid1);
217: store.removeDestinationSequence(sid2);
218:
219: // deleting once again is a no-op
220: store.removeDestinationSequence(sid2);
221: }
222:
223: @Test
224: public void testCreateDeleteMessages() throws IOException,
225: SQLException {
226: RMMessage msg = control.createMock(RMMessage.class);
227: Identifier sid1 = RMUtils.getWSRMFactory().createIdentifier();
228: sid1.setValue("sequence1");
229: EasyMock.expect(msg.getMessageNumber()).andReturn(
230: BigInteger.ONE).times(2);
231: byte[] bytes = new byte[89];
232: EasyMock.expect(msg.getContent()).andReturn(bytes).times(2);
233:
234: control.replay();
235: store.beginTransaction();
236: store.storeMessage(sid1, msg, true);
237: store.storeMessage(sid1, msg, false);
238: store.commit();
239: control.verify();
240:
241: control.reset();
242: EasyMock.expect(msg.getMessageNumber()).andReturn(
243: BigInteger.ONE);
244: EasyMock.expect(msg.getContent()).andReturn(bytes);
245:
246: control.replay();
247: store.beginTransaction();
248: try {
249: store.storeMessage(sid1, msg, true);
250: } catch (SQLException ex) {
251: assertEquals("23505", ex.getSQLState());
252: }
253: store.abort();
254: control.verify();
255:
256: control.reset();
257: EasyMock.expect(msg.getMessageNumber()).andReturn(
258: BigInteger.TEN).times(2);
259: EasyMock.expect(msg.getContent()).andReturn(bytes).times(2);
260:
261: control.replay();
262: store.beginTransaction();
263: store.storeMessage(sid1, msg, true);
264: store.storeMessage(sid1, msg, false);
265: store.commit();
266: control.verify();
267:
268: Collection<BigInteger> messageNrs = new ArrayList<BigInteger>();
269: messageNrs.add(BigInteger.ZERO);
270: messageNrs.add(BigInteger.TEN);
271: messageNrs.add(BigInteger.ONE);
272: messageNrs.add(BigInteger.TEN);
273:
274: store.removeMessages(sid1, messageNrs, true);
275: store.removeMessages(sid1, messageNrs, false);
276:
277: Identifier sid2 = RMUtils.getWSRMFactory().createIdentifier();
278: sid1.setValue("sequence2");
279: store.removeMessages(sid2, messageNrs, true);
280: }
281:
282: @Test
283: public void testUpdateDestinationSequence() throws SQLException,
284: IOException {
285: DestinationSequence seq = control
286: .createMock(DestinationSequence.class);
287: Identifier sid1 = RMUtils.getWSRMFactory().createIdentifier();
288: sid1.setValue("sequence1");
289: EndpointReferenceType epr = RMUtils
290: .createAnonymousReference2004();
291: EasyMock.expect(seq.getIdentifier()).andReturn(sid1);
292: EasyMock.expect(seq.getAcksTo()).andReturn(epr);
293: EasyMock.expect(seq.getEndpointIdentifier()).andReturn(
294: SERVER_ENDPOINT_ID);
295:
296: control.replay();
297: store.createDestinationSequence(seq);
298: control.verify();
299:
300: control.reset();
301: EasyMock.expect(seq.getLastMessageNumber()).andReturn(null);
302: EasyMock.expect(seq.getAcknowledgment()).andReturn(ack1);
303: EasyMock.expect(seq.getIdentifier()).andReturn(sid1);
304:
305: control.replay();
306: store.beginTransaction();
307: store.updateDestinationSequence(seq);
308: store.abort();
309:
310: control.reset();
311: EasyMock.expect(seq.getLastMessageNumber()).andReturn(
312: BigInteger.TEN);
313: EasyMock.expect(seq.getAcknowledgment()).andReturn(ack1);
314: EasyMock.expect(seq.getIdentifier()).andReturn(sid1);
315:
316: control.replay();
317: store.beginTransaction();
318: store.updateDestinationSequence(seq);
319: store.abort();
320:
321: store.removeDestinationSequence(sid1);
322: }
323:
324: @Test
325: public void testUpdateSourceSequence() throws SQLException {
326: SourceSequence seq = control.createMock(SourceSequence.class);
327: Identifier sid1 = RMUtils.getWSRMFactory().createIdentifier();
328: sid1.setValue("sequence1");
329: EasyMock.expect(seq.getIdentifier()).andReturn(sid1);
330: EasyMock.expect(seq.getExpires()).andReturn(null);
331: EasyMock.expect(seq.getOfferingSequenceIdentifier()).andReturn(
332: null);
333: EasyMock.expect(seq.getEndpointIdentifier()).andReturn(
334: CLIENT_ENDPOINT_ID);
335:
336: control.replay();
337: store.createSourceSequence(seq);
338: control.verify();
339:
340: control.reset();
341: EasyMock.expect(seq.getCurrentMessageNr()).andReturn(
342: BigInteger.ONE);
343: EasyMock.expect(seq.isLastMessage()).andReturn(false);
344: EasyMock.expect(seq.getIdentifier()).andReturn(sid1);
345:
346: control.replay();
347: store.beginTransaction();
348: store.updateSourceSequence(seq);
349: store.abort();
350:
351: control.reset();
352: EasyMock.expect(seq.getCurrentMessageNr()).andReturn(
353: BigInteger.TEN);
354: EasyMock.expect(seq.isLastMessage()).andReturn(true);
355: EasyMock.expect(seq.getIdentifier()).andReturn(sid1);
356:
357: control.replay();
358: store.beginTransaction();
359: store.updateSourceSequence(seq);
360: store.abort();
361:
362: store.removeSourceSequence(sid1);
363:
364: }
365:
366: @Test
367: public void testGetDestinationSequences() throws SQLException,
368: IOException {
369:
370: Identifier sid1 = null;
371: Identifier sid2 = null;
372:
373: Collection<DestinationSequence> seqs = store
374: .getDestinationSequences("unknown");
375: assertEquals(0, seqs.size());
376:
377: try {
378: sid1 = setupDestinationSequence("sequence1");
379:
380: seqs = store.getDestinationSequences(SERVER_ENDPOINT_ID);
381: assertEquals(1, seqs.size());
382: checkRecoveredDestinationSequences(seqs);
383:
384: sid2 = setupDestinationSequence("sequence2");
385: seqs = store.getDestinationSequences(SERVER_ENDPOINT_ID);
386: assertEquals(2, seqs.size());
387: checkRecoveredDestinationSequences(seqs);
388: } finally {
389: if (null != sid1) {
390: store.removeDestinationSequence(sid1);
391: }
392: if (null != sid2) {
393: store.removeDestinationSequence(sid2);
394: }
395: }
396: }
397:
398: @Test
399: public void testGetSourceSequences() throws SQLException,
400: IOException {
401:
402: Identifier sid1 = null;
403: Identifier sid2 = null;
404:
405: Collection<SourceSequence> seqs = store
406: .getSourceSequences("unknown");
407: assertEquals(0, seqs.size());
408:
409: try {
410: sid1 = setupSourceSequence("sequence1");
411:
412: seqs = store.getSourceSequences(CLIENT_ENDPOINT_ID);
413: assertEquals(1, seqs.size());
414: checkRecoveredSourceSequences(seqs);
415:
416: sid2 = setupSourceSequence("sequence2");
417: seqs = store.getSourceSequences(CLIENT_ENDPOINT_ID);
418: assertEquals(2, seqs.size());
419: checkRecoveredSourceSequences(seqs);
420: } finally {
421: if (null != sid1) {
422: store.removeSourceSequence(sid1);
423: }
424: if (null != sid2) {
425: store.removeSourceSequence(sid2);
426: }
427: }
428: }
429:
430: @Test
431: public void testGetMessages() throws SQLException, IOException {
432:
433: Identifier sid1 = RMUtils.getWSRMFactory().createIdentifier();
434: sid1.setValue("sequence1");
435: Identifier sid2 = RMUtils.getWSRMFactory().createIdentifier();
436: sid2.setValue("sequence2");
437:
438: Collection<RMMessage> out = store.getMessages(sid1, true);
439: assertEquals(0, out.size());
440: Collection<RMMessage> in = store.getMessages(sid1, false);
441: assertEquals(0, out.size());
442:
443: try {
444: setupMessage(sid1, BigInteger.ONE, null, true);
445: setupMessage(sid1, BigInteger.ONE, null, false);
446:
447: out = store.getMessages(sid1, true);
448: assertEquals(1, out.size());
449: checkRecoveredMessages(out);
450:
451: in = store.getMessages(sid1, false);
452: assertEquals(1, in.size());
453: checkRecoveredMessages(in);
454:
455: setupMessage(sid1, BigInteger.TEN, NON_ANON_ACKS_TO, true);
456: setupMessage(sid1, BigInteger.TEN, NON_ANON_ACKS_TO, false);
457:
458: out = store.getMessages(sid1, true);
459: assertEquals(2, out.size());
460: checkRecoveredMessages(out);
461:
462: in = store.getMessages(sid1, false);
463: assertEquals(2, in.size());
464: checkRecoveredMessages(in);
465: } finally {
466: Collection<BigInteger> msgNrs = new ArrayList<BigInteger>();
467: msgNrs.add(BigInteger.ONE);
468: msgNrs.add(BigInteger.TEN);
469:
470: store.removeMessages(sid1, msgNrs, true);
471: store.removeMessages(sid1, msgNrs, false);
472: }
473: }
474:
475: private Identifier setupDestinationSequence(String s)
476: throws IOException, SQLException {
477: DestinationSequence seq = control
478: .createMock(DestinationSequence.class);
479:
480: Identifier sid = RMUtils.getWSRMFactory().createIdentifier();
481: sid.setValue(s);
482: EndpointReferenceType epr = RMUtils
483: .createAnonymousReference2004();
484:
485: SequenceAcknowledgement ack = ack1;
486: BigInteger lmn = null;
487:
488: if ("sequence2".equals(s)) {
489: ack = ack2;
490: lmn = BigInteger.TEN;
491: }
492:
493: EasyMock.expect(seq.getIdentifier()).andReturn(sid);
494: EasyMock.expect(seq.getAcksTo()).andReturn(epr);
495: EasyMock.expect(seq.getEndpointIdentifier()).andReturn(
496: SERVER_ENDPOINT_ID);
497: EasyMock.expect(seq.getLastMessageNumber()).andReturn(lmn);
498: EasyMock.expect(seq.getAcknowledgment()).andReturn(ack);
499: EasyMock.expect(seq.getIdentifier()).andReturn(sid);
500:
501: control.replay();
502: store.createDestinationSequence(seq);
503: store.beginTransaction();
504: store.updateDestinationSequence(seq);
505: store.commit();
506: control.reset();
507:
508: return sid;
509: }
510:
511: private Identifier setupSourceSequence(String s)
512: throws IOException, SQLException {
513: SourceSequence seq = control.createMock(SourceSequence.class);
514: Identifier sid = RMUtils.getWSRMFactory().createIdentifier();
515: sid.setValue(s);
516:
517: Date expiry = null;
518: Identifier osid = null;
519: BigInteger cmn = BigInteger.ONE;
520: boolean lm = false;
521:
522: if ("sequence2".equals(s)) {
523: expiry = new Date(System.currentTimeMillis() + 3600 * 1000);
524: osid = RMUtils.getWSRMFactory().createIdentifier();
525: osid.setValue("offeringSequence");
526: cmn = BigInteger.TEN;
527: lm = true;
528: }
529:
530: EasyMock.expect(seq.getIdentifier()).andReturn(sid);
531: EasyMock.expect(seq.getExpires()).andReturn(expiry);
532: EasyMock.expect(seq.getOfferingSequenceIdentifier()).andReturn(
533: osid);
534: EasyMock.expect(seq.getEndpointIdentifier()).andReturn(
535: CLIENT_ENDPOINT_ID);
536: EasyMock.expect(seq.getCurrentMessageNr()).andReturn(cmn);
537: EasyMock.expect(seq.isLastMessage()).andReturn(lm);
538: EasyMock.expect(seq.getIdentifier()).andReturn(sid);
539:
540: control.replay();
541: store.createSourceSequence(seq);
542: store.beginTransaction();
543: store.updateSourceSequence(seq);
544: store.commit();
545: control.reset();
546:
547: return sid;
548: }
549:
550: private void setupMessage(Identifier sid, BigInteger mn, String to,
551: boolean outbound) throws IOException, SQLException {
552: RMMessage msg = control.createMock(RMMessage.class);
553: EasyMock.expect(msg.getMessageNumber()).andReturn(mn);
554: EasyMock.expect(msg.getTo()).andReturn(to);
555: String value = "Message " + mn.longValue();
556: EasyMock.expect(msg.getContent()).andReturn(value.getBytes());
557:
558: control.replay();
559: store.beginTransaction();
560: store.storeMessage(sid, msg, outbound);
561: store.commit();
562: control.reset();
563: }
564:
565: private void checkRecoveredDestinationSequences(
566: Collection<DestinationSequence> seqs) {
567:
568: for (DestinationSequence recovered : seqs) {
569: assertTrue("sequence1".equals(recovered.getIdentifier()
570: .getValue())
571: || "sequence2".equals(recovered.getIdentifier()
572: .getValue()));
573: assertEquals(RMConstants.getAnonymousAddress(), recovered
574: .getAcksTo().getAddress().getValue());
575: if ("sequence1"
576: .equals(recovered.getIdentifier().getValue())) {
577: assertNull(recovered.getLastMessageNumber());
578: assertEquals(1, recovered.getAcknowledgment()
579: .getAcknowledgementRange().size());
580: SequenceAcknowledgement.AcknowledgementRange r = recovered
581: .getAcknowledgment().getAcknowledgementRange()
582: .get(0);
583: assertEquals(BigInteger.ONE, r.getLower());
584: assertEquals(BigInteger.ONE, r.getUpper());
585: } else {
586: assertEquals(BigInteger.TEN, recovered
587: .getLastMessageNumber());
588: assertEquals(2, recovered.getAcknowledgment()
589: .getAcknowledgementRange().size());
590: SequenceAcknowledgement.AcknowledgementRange r = recovered
591: .getAcknowledgment().getAcknowledgementRange()
592: .get(0);
593: assertEquals(BigInteger.ONE, r.getLower());
594: assertEquals(BigInteger.ONE, r.getUpper());
595: r = recovered.getAcknowledgment()
596: .getAcknowledgementRange().get(1);
597: assertEquals(new BigInteger("3"), r.getLower());
598: assertEquals(BigInteger.TEN, r.getUpper());
599: }
600: }
601: }
602:
603: private void checkRecoveredSourceSequences(
604: Collection<SourceSequence> seqs) {
605:
606: for (SourceSequence recovered : seqs) {
607: assertTrue("sequence1".equals(recovered.getIdentifier()
608: .getValue())
609: || "sequence2".equals(recovered.getIdentifier()
610: .getValue()));
611: if ("sequence1"
612: .equals(recovered.getIdentifier().getValue())) {
613: assertFalse(recovered.isLastMessage());
614: assertEquals(BigInteger.ONE, recovered
615: .getCurrentMessageNr());
616: assertNull(recovered.getExpires());
617: assertNull(recovered.getOfferingSequenceIdentifier());
618: } else {
619: assertTrue(recovered.isLastMessage());
620: assertEquals(BigInteger.TEN, recovered
621: .getCurrentMessageNr());
622: assertNotNull(recovered.getExpires());
623: assertEquals("offeringSequence", recovered
624: .getOfferingSequenceIdentifier().getValue());
625: }
626: }
627: }
628:
629: private void checkRecoveredMessages(Collection<RMMessage> msgs) {
630: for (RMMessage msg : msgs) {
631: BigInteger mn = msg.getMessageNumber();
632: assertTrue(BigInteger.ONE.equals(mn)
633: || BigInteger.TEN.equals(mn));
634: if (BigInteger.TEN.equals(mn)) {
635: assertEquals(NON_ANON_ACKS_TO, msg.getTo());
636: } else {
637: assertNull(msg.getTo());
638: }
639: byte[] actual = msg.getContent();
640: assertEquals(new String("Message " + mn.longValue()),
641: new String(actual));
642: }
643: }
644:
645: }
|