diff --git a/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/BlockManager.java b/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/BlockManager.java index d47ab906..3537f4db 100644 --- a/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/BlockManager.java +++ b/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/BlockManager.java @@ -56,6 +56,14 @@ public void addBlock(ContiguousIdBlock block) { availableRanges.add(new MonotonicRange(block.getLastCommitted() + 1, block.getLastValue())); } + /** + * Add a newly created block (all ids are available) + */ + public void addNewBlock(ContiguousIdBlock block) { + assignedBlocks.add(block); + availableRanges.add(new MonotonicRange(block.getFirstValue(), block.getLastValue())); + } + public MonotonicRangePriorityQueue getAvailableRanges() { return availableRanges; } @@ -111,28 +119,59 @@ private void assertAccessionsArePending(long[] accessions) throws AccessionIsNot } private Set doCommit(long[] accessions) { - Set blocksToUpdate = new HashSet<>(); + //Add all previously existing blocks to be updated in the contiguous_id_blocks table in the DB + Set blocksToUpdate = assignedBlocks.stream() + .filter(block -> !isNewBlock(block)) + .collect(Collectors.toSet()); + if (accessions == null || accessions.length == 0) { return blocksToUpdate; } addToCommitted(accessions); + if (assignedBlocks.size() == 0) { + return blocksToUpdate; + } + ContiguousIdBlock block = assignedBlocks.peek(); - while (block != null && committedAccessions.peek() != null && - committedAccessions.peek() == block.getLastCommitted() + 1) { + long lastCommitted = calculateLastCommitted(block); + while (block != null && committedAccessions.peek() != null && committedAccessions.peek() == lastCommitted + 1) { //Next value continues sequence, change last committed value block.setLastCommitted(committedAccessions.poll()); + lastCommitted = block.getLastCommitted(); blocksToUpdate.add(block); - if (!block.isNotFull()) { + if (isBlockFull(block)) { assignedBlocks.poll(); block = assignedBlocks.peek(); + if (block != null) { + lastCommitted = calculateLastCommitted(block); + } } } return blocksToUpdate; } + /** + * Existing blocks have the actual last_committed accession in the block manager but not in the db table + * New blocks are all marked as used in both the block manager and db table + */ + private long calculateLastCommitted(ContiguousIdBlock block) { + return (isNewBlock(block)) ? (block.getFirstValue() - 1) : block.getLastCommitted(); + } + + /** + * New block have the same last_committed and last_value in the block manager + */ + private boolean isNewBlock(ContiguousIdBlock block) { + return block.getLastCommitted() == block.getLastValue(); + } + + private boolean isBlockFull(ContiguousIdBlock block) { + return !block.isNotFull(); + } + private void addToCommitted(long[] accessions) { for (long accession : accessions) { committedAccessions.add(accession); diff --git a/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/MonotonicAccessionGenerator.java b/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/MonotonicAccessionGenerator.java index 16e7836f..d37b4e7c 100644 --- a/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/MonotonicAccessionGenerator.java +++ b/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/MonotonicAccessionGenerator.java @@ -27,7 +27,6 @@ import uk.ac.ebi.ampt2d.commons.accession.persistence.jpa.monotonic.service.ContiguousIdBlockService; import uk.ac.ebi.ampt2d.commons.accession.persistence.jpa.monotonic.service.MonotonicDatabaseService; import uk.ac.ebi.ampt2d.commons.accession.utils.ExponentialBackOff; -import uk.ac.ebi.ampt2d.commons.accession.utils.exceptions.ExponentialBackOffMaxRetriesRuntimeException; import java.util.ArrayList; import java.util.List; @@ -85,6 +84,7 @@ private static BlockManager initializeBlockManager(ContiguousIdBlockService bloc //Insert as available ranges for (ContiguousIdBlock block : uncompletedBlocks) { blockManager.addBlock(block); + blockService.markBlockAsUsed(block); } return blockManager; } @@ -135,7 +135,7 @@ private synchronized void reserveNewBlocksUntilSizeIs(int totalAccessionsToGener } private synchronized void reserveNewBlock(String categoryId, String instanceId) { - blockManager.addBlock(blockService.reserveNewBlock(categoryId, instanceId)); + blockManager.addNewBlock(blockService.reserveNewBlock(categoryId, instanceId)); } public synchronized void commit(long... accessions) throws AccessionIsNotPendingException { diff --git a/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/entities/ContiguousIdBlock.java b/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/entities/ContiguousIdBlock.java index dc40c1b3..a373ad22 100644 --- a/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/entities/ContiguousIdBlock.java +++ b/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/entities/ContiguousIdBlock.java @@ -74,7 +74,7 @@ public ContiguousIdBlock(String categoryId, String applicationInstanceId, long f this.applicationInstanceId = applicationInstanceId; this.firstValue = firstValue; this.lastValue = firstValue + size - 1; - this.lastCommitted = firstValue - 1; + this.lastCommitted = firstValue + size - 1; } /** diff --git a/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/service/ContiguousIdBlockService.java b/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/service/ContiguousIdBlockService.java index 9030bb16..e2d24ee5 100644 --- a/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/service/ContiguousIdBlockService.java +++ b/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/service/ContiguousIdBlockService.java @@ -69,6 +69,18 @@ public ContiguousIdBlock reserveNewBlock(String categoryId, String instanceId) { return reservedBlock; } + /** + * Mark the block as completely used in the contiguous_id_blocks tables but in the block manager keep last_committed + * value before the beginning of the block + */ + @Transactional(isolation = Isolation.SERIALIZABLE) + public void markBlockAsUsed(ContiguousIdBlock block) { + long lastCommitted = block.getLastCommitted(); + block.setLastCommitted(block.getLastValue()); + repository.save(block); + block.setLastCommitted(lastCommitted); + } + public BlockParameters getBlockParameters(String categoryId) { return categoryBlockInitializations.get(categoryId); } diff --git a/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/core/BasicMonotonicAccessioningWithAlternateRangesTest.java b/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/core/BasicMonotonicAccessioningWithAlternateRangesTest.java index f234888b..cb8fbf53 100644 --- a/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/core/BasicMonotonicAccessioningWithAlternateRangesTest.java +++ b/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/core/BasicMonotonicAccessioningWithAlternateRangesTest.java @@ -75,6 +75,7 @@ public void testAlternateRangesWithDifferentGenerators() throws AccessionCouldNo assertEquals(0, evaAccessions.get(0).getAccession().longValue()); assertEquals(8, evaAccessions.get(8).getAccession().longValue()); //BlockSize of 10 was reserved but only 9 elements have been accessioned + //All accessions were marked as used assertEquals(1, contiguousIdBlockService .getUncompletedBlocksByCategoryIdAndApplicationInstanceIdOrderByEndAsc(categoryId, INSTANCE_ID) .size()); diff --git a/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/BlockManagerTest.java b/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/BlockManagerTest.java index 0ba9a4dd..709dc1c5 100644 --- a/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/BlockManagerTest.java +++ b/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/BlockManagerTest.java @@ -22,6 +22,9 @@ import uk.ac.ebi.ampt2d.commons.accession.core.exceptions.AccessionIsNotPendingException; import uk.ac.ebi.ampt2d.commons.accession.persistence.jpa.monotonic.entities.ContiguousIdBlock; +import java.util.Arrays; +import java.util.Set; + import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -41,7 +44,7 @@ public void noAvailableAccessionsIfNoBlocks() { @Test public void availableAccessionWhenBlockHashBeenAdded() { BlockManager manager = new BlockManager(); - manager.addBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 100)); + manager.addNewBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 100)); assertTrue(manager.hasAvailableAccessions(10)); assertFalse(manager.hasAvailableAccessions(101)); } @@ -67,7 +70,7 @@ public void pollNextWhenNoValues() throws AccessionCouldNotBeGeneratedException @Test public void generateAccessions() throws AccessionCouldNotBeGeneratedException { BlockManager manager = new BlockManager(); - manager.addBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 100)); + manager.addNewBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 100)); long[] accessions = manager.pollNext(10); assertEquals(10, accessions.length); assertArrayEquals(new long[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, accessions); @@ -76,7 +79,7 @@ public void generateAccessions() throws AccessionCouldNotBeGeneratedException { @Test public void generateAccessionsAndRelease() throws AccessionCouldNotBeGeneratedException { BlockManager manager = new BlockManager(); - manager.addBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 100)); + manager.addNewBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 100)); long[] accessions = manager.pollNext(10); assertEquals(10, accessions.length); assertArrayEquals(new long[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, accessions); @@ -89,7 +92,7 @@ public void generateAccessionsAndRelease() throws AccessionCouldNotBeGeneratedEx @Test public void generateAccessionsAndReleaseSome() throws AccessionCouldNotBeGeneratedException { BlockManager manager = new BlockManager(); - manager.addBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 100)); + manager.addNewBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 100)); long[] accessions = manager.pollNext(10); assertEquals(10, accessions.length); assertArrayEquals(new long[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, accessions); @@ -105,7 +108,7 @@ public void generateAccessionsAndReleaseSome() throws AccessionCouldNotBeGenerat @Test public void generateAccessionsAndConfirmSome() throws AccessionCouldNotBeGeneratedException { BlockManager manager = new BlockManager(); - manager.addBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 100)); + manager.addNewBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 100)); long[] accessions = manager.pollNext(10); assertEquals(10, accessions.length); assertArrayEquals(new long[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, accessions); @@ -118,7 +121,7 @@ public void generateAccessionsAndConfirmSome() throws AccessionCouldNotBeGenerat @Test public void recoverState() throws AccessionCouldNotBeGeneratedException { BlockManager manager = new BlockManager(); - manager.addBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 100)); + manager.addNewBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 100)); manager.recoverState(new long[]{0, 1, 2, 6, 7, 8, 9}); long[] accessions = manager.pollNext(10); assertEquals(3, accessions.length); @@ -131,8 +134,8 @@ public void recoverState() throws AccessionCouldNotBeGeneratedException { @Test public void multipleContinuousBlocks() throws AccessionCouldNotBeGeneratedException { BlockManager manager = new BlockManager(); - manager.addBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 10)); - manager.addBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 10, 10)); + manager.addNewBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 10)); + manager.addNewBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 10, 10)); manager.recoverState(new long[]{0, 1, 2, 6, 7, 8, 9}); long[] accessions = manager.pollNext(10); assertEquals(3, accessions.length); @@ -145,12 +148,39 @@ public void multipleContinuousBlocks() throws AccessionCouldNotBeGeneratedExcept @Test public void commitAllValuesOnBlockManager() throws AccessionCouldNotBeGeneratedException { BlockManager manager = new BlockManager(); - manager.addBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 10)); - manager.addBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 10, 10)); + manager.addNewBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 10)); + manager.addNewBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 10, 10)); long[] accessions1 = manager.pollNext(10); long[] accessions2 = manager.pollNext(10); manager.commit(accessions1); manager.commit(accessions2); } + @Test + public void commitMoreAccessionsThanMaxPerBlock() throws AccessionCouldNotBeGeneratedException { + BlockManager manager = new BlockManager(); + manager.addNewBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 10)); + manager.addNewBlock(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 10, 10)); + long[] accessions1 = manager.pollNext(10); + long[] accessions2 = manager.pollNext(2); + long[] all = Arrays.copyOf(accessions1, accessions1.length + accessions2.length); + System.arraycopy(accessions2, 0, all, accessions1.length, accessions2.length); + + Set blocksToUpdate = manager.commit(all); + + //Entire first block should be marked as used + //Second should only mark 2 accessions as used (accession 10 and 11) + assertEquals(2, blocksToUpdate.size()); + for (ContiguousIdBlock currentBlock : blocksToUpdate) { + switch ((int) currentBlock.getFirstValue()) { + case 0: + assertEquals(9, currentBlock.getLastCommitted()); + break; + case 10: + assertEquals(11, currentBlock.getLastCommitted()); + break; + default: + } + } + } } diff --git a/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/MonotonicAccessionGeneratorTest.java b/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/MonotonicAccessionGeneratorTest.java index ee2d68b4..ed7488cc 100644 --- a/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/MonotonicAccessionGeneratorTest.java +++ b/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/generators/monotonic/MonotonicAccessionGeneratorTest.java @@ -35,6 +35,7 @@ import uk.ac.ebi.ampt2d.commons.accession.utils.exceptions.ExponentialBackOffMaxRetriesRuntimeException; import uk.ac.ebi.ampt2d.test.configuration.MonotonicAccessionGeneratorTestConfiguration; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -83,7 +84,7 @@ public void assertBlockGeneratedAtGenerateOperationIfNoBlockExists() throws Exce ContiguousIdBlock block = repository.findFirstByCategoryIdOrderByLastValueDesc(CATEGORY_ID); assertEquals(0, block.getFirstValue()); assertEquals(BLOCK_SIZE - 1, block.getLastValue()); - assertEquals(-1, block.getLastCommitted()); + assertEquals(block.getLastValue(), block.getLastCommitted()); } @Test @@ -112,14 +113,14 @@ public void assertNewBlockGeneratedInSecondInstance() throws Exception { block = repository.findFirstByCategoryIdAndApplicationInstanceIdOrderByLastValueDesc(CATEGORY_ID, INSTANCE_ID); assertEquals(0, block.getFirstValue()); assertEquals(BLOCK_SIZE - 1, block.getLastValue()); - assertEquals(-1, block.getLastCommitted()); + assertEquals(block.getLastValue(), block.getLastCommitted()); generator2.generateAccessions(TENTH_BLOCK_SIZE); assertEquals(2, repository.count()); block = repository.findFirstByCategoryIdAndApplicationInstanceIdOrderByLastValueDesc(CATEGORY_ID, INSTANCE_2_ID); assertEquals(BLOCK_SIZE, block.getFirstValue()); assertEquals(2 * BLOCK_SIZE - 1, block.getLastValue()); - assertEquals(BLOCK_SIZE - 1, block.getLastCommitted()); + assertEquals(block.getLastValue(), block.getLastCommitted()); } @Test @@ -167,11 +168,11 @@ public void assertCommitModifiesLastCommitted() throws Exception { @Test public void assertNotCommittingDoesNotModifyLastCommitted() throws Exception { MonotonicAccessionGenerator generator = getMonotonicAccessionGenerator(); - long[] accessions = generator.generateAccessions(TENTH_BLOCK_SIZE); + generator.generateAccessions(TENTH_BLOCK_SIZE); ContiguousIdBlock block = repository.findFirstByCategoryIdAndApplicationInstanceIdOrderByLastValueDesc(CATEGORY_ID, INSTANCE_ID); - assertEquals(-1, block.getLastCommitted()); + assertEquals(block.getLastValue(), block.getLastCommitted()); } @Test @@ -184,7 +185,7 @@ public void assertCommitOutOfOrderDoesNotModifyLastCommittedUntilTheSequenceIsCo ContiguousIdBlock block = repository.findFirstByCategoryIdAndApplicationInstanceIdOrderByLastValueDesc(CATEGORY_ID, INSTANCE_ID); - assertEquals(-1, block.getLastCommitted()); + assertEquals(block.getLastValue(), block.getLastCommitted()); generator.commit(accessions1); @@ -204,7 +205,8 @@ public void assertCommitOutOfOrderDoesNotModifyLastCommittedUntilTheSequenceIsCo ContiguousIdBlock block = repository.findFirstByCategoryIdAndApplicationInstanceIdOrderByLastValueDesc(CATEGORY_ID, INSTANCE_ID); assertEquals(BLOCK_SIZE, block.getFirstValue()); - assertEquals(BLOCK_SIZE - 1, block.getLastCommitted()); + //Last committed should be at the end of the second block (999 to 1999) + assertEquals(block.getLastValue(), block.getLastCommitted()); generator.commit(accessions1); @@ -273,7 +275,7 @@ public void assertMultipleReleaseAndCommitsWorks() throws Exception { //999 is waiting somewhere taking a big nap and no elements have been confirmed due to element 0 being released ContiguousIdBlock block = repository.findFirstByCategoryIdAndApplicationInstanceIdOrderByLastValueDesc(CATEGORY_ID, INSTANCE_ID); - assertEquals(-1, block.getLastCommitted()); + assertEquals(999, block.getLastCommitted()); long[] accessions2 = generator.generateAccessions(BLOCK_SIZE); assertEquals(0, accessions2[0]); @@ -298,26 +300,35 @@ public void assertMultipleReleaseAndCommitsWorks() throws Exception { assertEquals(1991, block.getLastCommitted()); } + /** + * New block created and marked as used (first_value = 0, last_committed = 999, last_value = 999) + * Application failed -> No updated performed in contiguous_id_blocks tables (the whole block remain as used) + * + * Application run again using the same category and instance + * ids (2, 3, 5) were used in the previous run + * The last block (0 to 999) is marked as used so there are no available ranges + */ @Test public void assertRecoverNoPendingCommit() throws Exception { MonotonicAccessionGenerator generator = getMonotonicAccessionGenerator(); - long[] accessions1 = generator.generateAccessions(BLOCK_SIZE); + generator.generateAccessions(BLOCK_SIZE); // Now assume that the db layer has stored some elements and that the application has died and restarted. MonotonicAccessionGenerator generatorRecovering = new MonotonicAccessionGenerator(CATEGORY_ID, INSTANCE_ID, service, new long[]{2, 3, 5}); ContiguousIdBlock block = repository.findFirstByCategoryIdAndApplicationInstanceIdOrderByLastValueDesc(CATEGORY_ID, INSTANCE_ID); - assertEquals(-1, block.getLastCommitted()); - assertFalse(generatorRecovering.getAvailableRanges().isEmpty()); - assertThat(generatorRecovering.getAvailableRanges(), - contains(new MonotonicRange(0, 1), new MonotonicRange(4, 4), new MonotonicRange(6, BLOCK_SIZE - 1))); + + //New generated block marked as used + assertEquals(block.getLastValue(), block.getLastCommitted()); + //Last block is marked as used and can't be recovered so there are no ranges available + assertTrue(generatorRecovering.getAvailableRanges().isEmpty()); } @Test public void assertRecoverPendingCommit() throws Exception { MonotonicAccessionGenerator generator = getMonotonicAccessionGenerator(); - long[] accessions1 = generator.generateAccessions(BLOCK_SIZE); + generator.generateAccessions(BLOCK_SIZE); generator.commit(0, 1); // Now assume that the db layer has stored some elements and that the application has died and restarted. @@ -416,18 +427,25 @@ public void assertReleaseInAlternateRanges() throws Exception { assertEquals(11, accessions2[3]); } + /** + * Block (1 to 5) was marked and used + * generatorRecovering can't recover the unused ids + * A new block (11 to 15) is created to issue requested ids + */ @Test public void assertRecoverInAlternateRanges() throws Exception { MonotonicAccessionGenerator generator = getMonotonicAccessionGeneratorForCategoryHavingBlockInterval(); - long[] accessions1 = generator.generateAccessions(NUM_OF_ACCESSIONS); + generator.generateAccessions(NUM_OF_ACCESSIONS); // Now assume that the db layer has stored some elements and that the application has died and restarted. + MonotonicAccessionGenerator generatorRecovering = new MonotonicAccessionGenerator(CATEGORY_ID_2, INSTANCE_ID, service, new long[]{2, 3}); long[] accessions2 = generatorRecovering.generateAccessions(NUM_OF_ACCESSIONS); - assertEquals(1, accessions2[0]); - assertEquals(4, accessions2[1]); - assertEquals(5, accessions2[2]); - assertEquals(11, accessions2[3]); + + assertEquals(11, accessions2[0]); + assertEquals(12, accessions2[1]); + assertEquals(13, accessions2[2]); + assertEquals(14, accessions2[3]); } private MonotonicAccessionGenerator getMonotonicAccessionGenerator() throws Exception { diff --git a/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/service/ContiguousIdBlockServiceTest.java b/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/service/ContiguousIdBlockServiceTest.java index 47959ed6..f13f8b48 100644 --- a/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/service/ContiguousIdBlockServiceTest.java +++ b/accession-commons-monotonic-generator-jpa/src/test/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/service/ContiguousIdBlockServiceTest.java @@ -35,6 +35,7 @@ import java.util.List; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; @@ -57,16 +58,19 @@ public class ContiguousIdBlockServiceTest { @PersistenceContext EntityManager entityManager; + /** + * When reserving, block should be marked as used + */ @Test public void testReserveNewBlocks() { ContiguousIdBlock block = service.reserveNewBlock(CATEGORY_ID, INSTANCE_ID); assertEquals(0, block.getFirstValue()); assertEquals(999, block.getLastValue()); - assertTrue(block.isNotFull()); + assertFalse(block.isNotFull()); ContiguousIdBlock block2 = service.reserveNewBlock(CATEGORY_ID, INSTANCE_ID); assertEquals(1000, block2.getFirstValue()); assertEquals(1999, block2.getLastValue()); - assertTrue(block.isNotFull()); + assertFalse(block.isNotFull()); } @Test @@ -76,7 +80,7 @@ public void testReserveWithExistingData() { ContiguousIdBlock block = service.reserveNewBlock(CATEGORY_ID, INSTANCE_ID); assertEquals(5, block.getFirstValue()); assertEquals(1004, block.getLastValue()); - assertTrue(block.isNotFull()); + assertFalse(block.isNotFull()); } @Test @@ -84,27 +88,33 @@ public void testReserveNewBlocksWithMultipleInstances() { ContiguousIdBlock block = service.reserveNewBlock(CATEGORY_ID, INSTANCE_ID); assertEquals(0, block.getFirstValue()); assertEquals(999, block.getLastValue()); - assertTrue(block.isNotFull()); + assertFalse(block.isNotFull()); ContiguousIdBlock block2 = service.reserveNewBlock(CATEGORY_ID, INSTANCE_ID_2); assertEquals(1000, block2.getFirstValue()); assertEquals(1999, block2.getLastValue()); - assertTrue(block.isNotFull()); + assertFalse(block.isNotFull()); ContiguousIdBlock block3 = service.reserveNewBlock(CATEGORY_ID, INSTANCE_ID); assertEquals(2000, block3.getFirstValue()); assertEquals(2999, block3.getLastValue()); - assertTrue(block.isNotFull()); + assertFalse(block.isNotFull()); } @Test public void testGetUncompleteBlocks() { ContiguousIdBlock uncompletedBlock = new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 0, 5); - ContiguousIdBlock completedBlock = new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 10, 5); - completedBlock.setLastCommitted(14); - + uncompletedBlock.setLastCommitted(-1); service.save(Arrays.asList(uncompletedBlock)); - service.save(Arrays.asList(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID_2, 5, 5))); + + ContiguousIdBlock uncompletedBlockDifferentInstance = new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID_2, 5, 5); + uncompletedBlockDifferentInstance.setLastCommitted(4); + service.save(Arrays.asList(uncompletedBlockDifferentInstance)); + + ContiguousIdBlock completedBlock = new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 10, 5); service.save(Arrays.asList(completedBlock)); - service.save(Arrays.asList(new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 15, 5))); + + ContiguousIdBlock uncompletedBlock2 = new ContiguousIdBlock(CATEGORY_ID, INSTANCE_ID, 15, 5); + service.save(Arrays.asList(uncompletedBlock2)); + uncompletedBlock2.setLastCommitted(14); List contiguousBlocks = service.getUncompletedBlocksByCategoryIdAndApplicationInstanceIdOrderByEndAsc(CATEGORY_ID, INSTANCE_ID); @@ -127,9 +137,8 @@ public void testBlockSizeAndIntervalForCategory() { List contiguousBlocks = service .getUncompletedBlocksByCategoryIdAndApplicationInstanceIdOrderByEndAsc(CATEGORY_ID_2, INSTANCE_ID); - assertEquals(2, contiguousBlocks.size()); - assertTrue(contiguousBlocks.get(0).isNotFull()); - assertTrue(contiguousBlocks.get(1).isNotFull()); + //There are no contiguous blocks since all were marked as used + assertEquals(0, contiguousBlocks.size()); } @Test