Search in sources :

Example 11 with MessageId

use of io.cdap.cdap.messaging.data.MessageId in project cdap by caskdata.

the class CachingMessageTableTest method testCachePruning.

@Test
public void testCachePruning() throws Exception {
    long txGracePeriod = 6;
    CConfiguration cConf = CConfiguration.create();
    cConf.setLong(CachingMessageTable.PRUNE_GRACE_PERIOD, txGracePeriod);
    // Insert 10 entries, with different publish time
    TopicMetadata metadata = new TopicMetadata(NamespaceId.DEFAULT.topic("test"), TopicMetadata.GENERATION_KEY, 1, TopicMetadata.TTL_KEY, 86400);
    // Creates a CachingMessageTable with a controlled time provider
    final AtomicLong currentTimeMillis = new AtomicLong(0);
    MessageTable messageTable = new CachingMessageTable(cConf, super.getMessageTable(metadata), cacheProvider, new TimeProvider() {

        @Override
        public long currentTimeMillis() {
            return currentTimeMillis.get();
        }
    });
    for (int i = 0; i < 10; i++) {
        // Key is (topic, generation, publish time, sequence id)
        byte[] key = Bytes.concat(MessagingUtils.toDataKeyPrefix(metadata.getTopicId(), metadata.getGeneration()), Bytes.toBytes((long) i), Bytes.toBytes((short) 0));
        // Store a message with a write pointer
        messageTable.store(Collections.singleton(new ImmutableMessageTableEntry(key, Bytes.toBytes("Payload " + i), Bytes.toBytes((long) i))).iterator());
    }
    // Update the current time to 11
    currentTimeMillis.set(11);
    // Fetch from the table without transaction, should get all entries.
    try (CloseableIterator<MessageTable.Entry> iter = messageTable.fetch(metadata, 0, 100, null)) {
        List<MessageTable.Entry> entries = Lists.newArrayList(iter);
        Assert.assertEquals(10, entries.size());
        // All entries must be from the cache
        for (MessageTable.Entry entry : entries) {
            Assert.assertTrue(entry instanceof CachingMessageTable.CacheMessageTableEntry);
        }
    }
    // Fetch with a transaction, with start time older than tx grace period / 2
    Transaction tx = new Transaction(10, 11, new long[0], new long[0], 11);
    long startTime = currentTimeMillis.get() - txGracePeriod / 2 - 1;
    try (CloseableIterator<MessageTable.Entry> iter = messageTable.fetch(metadata, startTime, 100, tx)) {
        List<MessageTable.Entry> entries = Lists.newArrayList(iter);
        // Should get three entries (7, 8, 9)
        Assert.assertEquals(3, entries.size());
        // The first entry should be from the table, while the last two entries (timestamp 8 and 9) should be
        // from cache (current time = 11, grace period = 3)
        Iterator<MessageTable.Entry> iterator = entries.iterator();
        Assert.assertFalse(iterator.next() instanceof CachingMessageTable.CacheMessageTableEntry);
        Assert.assertTrue(iterator.next() instanceof CachingMessageTable.CacheMessageTableEntry);
        Assert.assertTrue(iterator.next() instanceof CachingMessageTable.CacheMessageTableEntry);
    }
    // Fetch with a transaction, with start messageId publish time older than tx grace period / 2
    byte[] rawId = new byte[MessageId.RAW_ID_SIZE];
    MessageId.putRawId(startTime, (short) 0, 0L, (short) 0, rawId, 0);
    MessageId messageId = new MessageId(rawId);
    try (CloseableIterator<MessageTable.Entry> iter = messageTable.fetch(metadata, messageId, true, 100, tx)) {
        List<MessageTable.Entry> entries = Lists.newArrayList(iter);
        // Should get three entries (7, 8, 9)
        Assert.assertEquals(3, entries.size());
        // The first entry should be from the table, while the last two entries (timestamp 8 and 9) should be
        // from cache (current time = 11, grace period = 3)
        Iterator<MessageTable.Entry> iterator = entries.iterator();
        Assert.assertFalse(iterator.next() instanceof CachingMessageTable.CacheMessageTableEntry);
        Assert.assertTrue(iterator.next() instanceof CachingMessageTable.CacheMessageTableEntry);
        Assert.assertTrue(iterator.next() instanceof CachingMessageTable.CacheMessageTableEntry);
    }
}
Also used : TimeProvider(io.cdap.cdap.common.utils.TimeProvider) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) TopicMetadata(io.cdap.cdap.messaging.TopicMetadata) AtomicLong(java.util.concurrent.atomic.AtomicLong) ImmutableMessageTableEntry(io.cdap.cdap.messaging.store.ImmutableMessageTableEntry) Transaction(org.apache.tephra.Transaction) MessageTable(io.cdap.cdap.messaging.store.MessageTable) ImmutableMessageTableEntry(io.cdap.cdap.messaging.store.ImmutableMessageTableEntry) MessageId(io.cdap.cdap.messaging.data.MessageId) LevelDBMessageTableTest(io.cdap.cdap.messaging.store.leveldb.LevelDBMessageTableTest) Test(org.junit.Test)

Example 12 with MessageId

use of io.cdap.cdap.messaging.data.MessageId in project cdap by caskdata.

the class PayloadTableTest method testConsumption.

@Test
public void testConsumption() throws Exception {
    try (MetadataTable metadataTable = getMetadataTable();
        PayloadTable table1 = getPayloadTable(M1);
        PayloadTable table2 = getPayloadTable(M2)) {
        metadataTable.createTopic(M1);
        metadataTable.createTopic(M2);
        List<PayloadTable.Entry> entryList = new ArrayList<>();
        populateList(entryList);
        table1.store(entryList.iterator());
        table2.store(entryList.iterator());
        byte[] messageId = new byte[MessageId.RAW_ID_SIZE];
        MessageId.putRawId(0L, (short) 0, 0L, (short) 0, messageId, 0);
        // Fetch data with 100 write pointer
        try (CloseableIterator<PayloadTable.Entry> iterator = table1.fetch(M1, 100, new MessageId(messageId), true, Integer.MAX_VALUE)) {
            checkData(iterator, 123, ImmutableSet.of(100L), 50);
        }
        // Fetch only 10 items with 101 write pointer
        try (CloseableIterator<PayloadTable.Entry> iterator = table1.fetch(M1, 101, new MessageId(messageId), true, 1)) {
            checkData(iterator, 123, ImmutableSet.of(101L), 1);
        }
        // Fetch items with 102 write pointer
        try (CloseableIterator<PayloadTable.Entry> iterator = table1.fetch(M1, 102, new MessageId(messageId), true, Integer.MAX_VALUE)) {
            checkData(iterator, 123, ImmutableSet.of(102L), 50);
        }
        // Fetch from t2 with 101 write pointer
        try (CloseableIterator<PayloadTable.Entry> iterator = table2.fetch(M2, 101, new MessageId(messageId), true, Integer.MAX_VALUE)) {
            checkData(iterator, 123, ImmutableSet.of(101L), 50);
        }
    }
}
Also used : ArrayList(java.util.ArrayList) MessageId(io.cdap.cdap.messaging.data.MessageId) Test(org.junit.Test)

Example 13 with MessageId

use of io.cdap.cdap.messaging.data.MessageId in project cdap by caskdata.

the class ConcurrentMessageWriterTest method testMaxSequence.

@Test
public void testMaxSequence() throws IOException {
    // This test the case when a single StoreRequest has more than SEQUENCE_ID_LIMIT (65536) payload.
    // Expected entries beyond the max seqId will be rolled to the next timestamp with seqId reset to start from 0
    // Generate SEQUENCE_ID_LIMIT + 1 payloads
    int msgCount = StoreRequestWriter.SEQUENCE_ID_LIMIT + 1;
    List<String> payloads = new ArrayList<>(msgCount);
    for (int i = 0; i < msgCount; i++) {
        payloads.add(Integer.toString(i));
    }
    TopicId topicId = new NamespaceId("ns1").topic("t1");
    TopicMetadata metadata = new TopicMetadata(topicId, new HashMap<String, String>(), 1);
    // Write the payloads
    TestStoreRequestWriter testWriter = new TestStoreRequestWriter(new TimeProvider.IncrementalTimeProvider());
    ConcurrentMessageWriter writer = new ConcurrentMessageWriter(testWriter);
    writer.persist(new TestStoreRequest(topicId, payloads), metadata);
    List<RawMessage> messages = testWriter.getMessages().get(topicId);
    Assert.assertEquals(msgCount, messages.size());
    // The first SEQUENCE_ID_LIMIT messages should be with the same timestamp, with seqId from 0 to SEQUENCE_ID_LIMIT
    for (int i = 0; i < StoreRequestWriter.SEQUENCE_ID_LIMIT; i++) {
        MessageId id = new MessageId(messages.get(i).getId());
        Assert.assertEquals(0L, id.getPublishTimestamp());
        Assert.assertEquals((short) i, id.getSequenceId());
    }
    // The (SEQUENCE_ID_LIMIT + 1)th message should have a different timestamp and seqId = 0
    MessageId id = new MessageId(messages.get(msgCount - 1).getId());
    Assert.assertEquals(1L, id.getPublishTimestamp());
    Assert.assertEquals(0, id.getPayloadSequenceId());
}
Also used : TimeProvider(io.cdap.cdap.common.utils.TimeProvider) ArrayList(java.util.ArrayList) TopicMetadata(io.cdap.cdap.messaging.TopicMetadata) TopicId(io.cdap.cdap.proto.id.TopicId) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) RawMessage(io.cdap.cdap.messaging.data.RawMessage) MessageId(io.cdap.cdap.messaging.data.MessageId) Test(org.junit.Test)

Example 14 with MessageId

use of io.cdap.cdap.messaging.data.MessageId in project cdap by caskdata.

the class LevelDBMessageTableTest method testUpgrade.

@Test
public void testUpgrade() throws Exception {
    File baseDir = tmpFolder.newFolder();
    String tableName = "tms.messages";
    CConfiguration cConf = CConfiguration.create();
    cConf.set(Constants.MessagingSystem.LOCAL_DATA_DIR, baseDir.getAbsolutePath());
    cConf.set(Constants.MessagingSystem.MESSAGE_TABLE_NAME, tableName);
    cConf.set(Constants.MessagingSystem.LOCAL_DATA_PARTITION_SECONDS, Integer.toString(1));
    LevelDBTableFactory tableFactory = new LevelDBTableFactory(cConf);
    TopicId topicId = new TopicId("default", "preview");
    int generation = 1;
    TopicMetadata topicMetadata = new TopicMetadata(topicId, Collections.singletonMap(TopicMetadata.GENERATION_KEY, String.valueOf(generation)));
    // write a message to a table, then rename the underlying directory to the old format
    long publishTime = 1000;
    try (MessageTable table = tableFactory.createMessageTable(topicMetadata)) {
        List<MessageTable.Entry> writes = new ArrayList<>();
        writes.add(new TestMessageEntry(topicId, generation, publishTime, 0, null, new byte[] { 0 }));
        table.store(writes.iterator());
    }
    tableFactory.close();
    File topicDir = LevelDBTableFactory.getMessageTablePath(baseDir, topicId, generation, tableName);
    File partitionDir = LevelDBPartitionManager.getPartitionDir(topicDir, 0, publishTime + 1000);
    File oldDir = new File(baseDir, topicDir.getName().substring(LevelDBTableFactory.MESSAGE_TABLE_VERSION.length() + 1));
    Files.move(partitionDir.toPath(), oldDir.toPath());
    Files.delete(topicDir.toPath());
    // now run the upgrade and make sure the table is readable.
    tableFactory = new LevelDBTableFactory(cConf);
    tableFactory.init();
    try (MessageTable table = tableFactory.createMessageTable(topicMetadata)) {
        byte[] messageId = new byte[MessageId.RAW_ID_SIZE];
        MessageId.putRawId(0L, (short) 0, 0L, (short) 0, messageId, 0);
        try (CloseableIterator<MessageTable.Entry> iter = table.fetch(topicMetadata, new MessageId(messageId), true, 100, null)) {
            Assert.assertTrue(iter.hasNext());
            MessageTable.Entry entry = iter.next();
            Assert.assertEquals(publishTime, entry.getPublishTimestamp());
            Assert.assertFalse(iter.hasNext());
        }
    }
}
Also used : ArrayList(java.util.ArrayList) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) TopicMetadata(io.cdap.cdap.messaging.TopicMetadata) TestMessageEntry(io.cdap.cdap.messaging.store.TestMessageEntry) MessageTable(io.cdap.cdap.messaging.store.MessageTable) TopicId(io.cdap.cdap.proto.id.TopicId) File(java.io.File) TestMessageEntry(io.cdap.cdap.messaging.store.TestMessageEntry) MessageId(io.cdap.cdap.messaging.data.MessageId) Test(org.junit.Test) MessageTableTest(io.cdap.cdap.messaging.store.MessageTableTest)

Example 15 with MessageId

use of io.cdap.cdap.messaging.data.MessageId in project cdap by caskdata.

the class CoreSchedulerServiceTest method getLastMessageId.

@Nullable
private MessageId getLastMessageId(final TopicId topic) {
    return TransactionRunners.run(transactionRunner, context -> {
        JobQueueTable jobQueue = JobQueueTable.getJobQueue(context, cConf);
        String id = jobQueue.retrieveSubscriberState(topic.getTopic());
        if (id == null) {
            return null;
        }
        byte[] bytes = Bytes.fromHexString(id);
        return new MessageId(bytes);
    });
}
Also used : JobQueueTable(io.cdap.cdap.internal.app.runtime.schedule.queue.JobQueueTable) MessageId(io.cdap.cdap.messaging.data.MessageId) Nullable(javax.annotation.Nullable)

Aggregations

MessageId (io.cdap.cdap.messaging.data.MessageId)15 Test (org.junit.Test)13 TopicMetadata (io.cdap.cdap.messaging.TopicMetadata)12 TopicId (io.cdap.cdap.proto.id.TopicId)12 ArrayList (java.util.ArrayList)11 TimeProvider (io.cdap.cdap.common.utils.TimeProvider)4 RawMessage (io.cdap.cdap.messaging.data.RawMessage)4 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)4 MessageTable (io.cdap.cdap.messaging.store.MessageTable)3 HashMap (java.util.HashMap)3 Transaction (org.apache.tephra.Transaction)3 CConfiguration (io.cdap.cdap.common.conf.CConfiguration)2 RollbackDetail (io.cdap.cdap.messaging.RollbackDetail)2 MessageTableTest (io.cdap.cdap.messaging.store.MessageTableTest)2 TestMessageEntry (io.cdap.cdap.messaging.store.TestMessageEntry)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 AbstractIterator (com.google.common.collect.AbstractIterator)1 ListeningExecutorService (com.google.common.util.concurrent.ListeningExecutorService)1 TopicNotFoundException (io.cdap.cdap.api.messaging.TopicNotFoundException)1 MetricsCollector (io.cdap.cdap.api.metrics.MetricsCollector)1