Search in sources :

Example 16 with TopicMetadata

use of io.cdap.cdap.messaging.TopicMetadata in project cdap by caskdata.

the class DataCleanupTest method testPayloadTTLCleanup.

@Test
public void testPayloadTTLCleanup() throws Exception {
    TopicId topicId = NamespaceId.DEFAULT.topic("t2");
    TopicMetadata topic = new TopicMetadata(topicId, "ttl", "3", TopicMetadata.GENERATION_KEY, Integer.toString(GENERATION));
    try (MetadataTable metadataTable = getMetadataTable();
        PayloadTable payloadTable = getPayloadTable(topic);
        MessageTable messageTable = getMessageTable(topic)) {
        Assert.assertNotNull(messageTable);
        metadataTable.createTopic(topic);
        List<PayloadTable.Entry> entries = new ArrayList<>();
        entries.add(new TestPayloadEntry(topicId, GENERATION, "payloaddata", 101, (short) 0));
        payloadTable.store(entries.iterator());
        byte[] messageId = new byte[MessageId.RAW_ID_SIZE];
        MessageId.putRawId(0L, (short) 0, 0L, (short) 0, messageId, 0);
        CloseableIterator<PayloadTable.Entry> iterator = payloadTable.fetch(topic, 101L, new MessageId(messageId), true, Integer.MAX_VALUE);
        Assert.assertTrue(iterator.hasNext());
        PayloadTable.Entry entry = iterator.next();
        Assert.assertFalse(iterator.hasNext());
        Assert.assertEquals("payloaddata", Bytes.toString(entry.getPayload()));
        Assert.assertEquals(101L, entry.getTransactionWritePointer());
        iterator.close();
        forceFlushAndCompact(Table.PAYLOAD);
        // Entry should still be there since ttl has not expired
        iterator = payloadTable.fetch(topic, 101L, new MessageId(messageId), true, Integer.MAX_VALUE);
        Assert.assertTrue(iterator.hasNext());
        entry = iterator.next();
        Assert.assertFalse(iterator.hasNext());
        Assert.assertEquals("payloaddata", Bytes.toString(entry.getPayload()));
        Assert.assertEquals(101L, entry.getTransactionWritePointer());
        iterator.close();
        TimeUnit.SECONDS.sleep(3 * METADATA_CACHE_EXPIRY);
        forceFlushAndCompact(Table.PAYLOAD);
        iterator = payloadTable.fetch(topic, 101L, new MessageId(messageId), true, Integer.MAX_VALUE);
        Assert.assertFalse(iterator.hasNext());
        iterator.close();
        metadataTable.deleteTopic(topicId);
    }
}
Also used : ArrayList(java.util.ArrayList) TopicMetadata(io.cdap.cdap.messaging.TopicMetadata) TopicId(io.cdap.cdap.proto.id.TopicId) MessageId(io.cdap.cdap.messaging.data.MessageId) Test(org.junit.Test)

Example 17 with TopicMetadata

use of io.cdap.cdap.messaging.TopicMetadata in project cdap by caskdata.

the class MessageTableTest method testEmptyPayload.

@Test
public void testEmptyPayload() throws Exception {
    TopicId topicId = NamespaceId.DEFAULT.topic("testEmptyPayload");
    TopicMetadata metadata = new TopicMetadata(topicId, DEFAULT_PROPERTY);
    // stores only a reference to the payload table
    try (MessageTable table = getMessageTable(metadata);
        MetadataTable metadataTable = getMetadataTable()) {
        metadataTable.createTopic(metadata);
        try {
            table.store(Collections.singleton(new TestMessageEntry(topicId, GENERATION, 1L, 0, null, null)).iterator());
            Assert.fail("Expected IllegalArgumentException");
        } catch (IllegalArgumentException e) {
        // Expected as non-transactional message cannot have null payload
        }
        // For transactional message, ok to have null payload
        table.store(Collections.singleton(new TestMessageEntry(topicId, GENERATION, 1L, 0, 2L, null)).iterator());
        // Fetch the entry to validate
        List<MessageTable.Entry> entries = new ArrayList<>();
        try (CloseableIterator<MessageTable.Entry> iterator = table.fetch(metadata, 0L, Integer.MAX_VALUE, null)) {
            Iterators.addAll(entries, iterator);
        }
        Assert.assertEquals(1, entries.size());
        MessageTable.Entry entry = entries.get(0);
        Assert.assertEquals(1L, entry.getPublishTimestamp());
        Assert.assertEquals(0, entry.getSequenceId());
        Assert.assertTrue(entry.isTransactional());
        Assert.assertEquals(2L, entry.getTransactionWritePointer());
        Assert.assertNull(entry.getPayload());
        Assert.assertTrue(entry.isPayloadReference());
    }
}
Also used : ArrayList(java.util.ArrayList) TopicId(io.cdap.cdap.proto.id.TopicId) TopicMetadata(io.cdap.cdap.messaging.TopicMetadata) Test(org.junit.Test)

Example 18 with TopicMetadata

use of io.cdap.cdap.messaging.TopicMetadata in project cdap by caskdata.

the class MessageTableTest method testSingleMessage.

@Test
public void testSingleMessage() throws Exception {
    TopicId topicId = NamespaceId.DEFAULT.topic("singleMessage");
    TopicMetadata metadata = new TopicMetadata(topicId, DEFAULT_PROPERTY);
    String payload = "data";
    long txWritePtr = 123L;
    try (MessageTable table = getMessageTable(metadata);
        MetadataTable metadataTable = getMetadataTable()) {
        metadataTable.createTopic(metadata);
        List<MessageTable.Entry> entryList = new ArrayList<>();
        entryList.add(new TestMessageEntry(topicId, GENERATION, 0L, 0, txWritePtr, Bytes.toBytes(payload)));
        table.store(entryList.iterator());
        byte[] messageId = new byte[MessageId.RAW_ID_SIZE];
        MessageId.putRawId(0L, (short) 0, 0L, (short) 0, messageId, 0);
        try (CloseableIterator<MessageTable.Entry> iterator = table.fetch(metadata, new MessageId(messageId), false, 50, null)) {
            // Fetch not including the first message, expect empty
            Assert.assertFalse(iterator.hasNext());
        }
        try (CloseableIterator<MessageTable.Entry> iterator = table.fetch(metadata, new MessageId(messageId), true, 50, null)) {
            // Fetch including the first message, should get the message
            Assert.assertTrue(iterator.hasNext());
            MessageTable.Entry entry = iterator.next();
            Assert.assertArrayEquals(Bytes.toBytes(payload), entry.getPayload());
            Assert.assertFalse(iterator.hasNext());
        }
        try (CloseableIterator<MessageTable.Entry> iterator = table.fetch(metadata, 0, 50, null)) {
            // Fetch by time, should get the entry
            MessageTable.Entry entry = iterator.next();
            Assert.assertArrayEquals(Bytes.toBytes(payload), entry.getPayload());
            Assert.assertFalse(iterator.hasNext());
        }
        RollbackDetail rollbackDetail = new TestRollbackDetail(123L, 0, (short) 0, 0L, (short) 0);
        table.rollback(metadata, rollbackDetail);
        try (CloseableIterator<MessageTable.Entry> iterator = table.fetch(metadata, new MessageId(messageId), true, 50, null)) {
            // Fetching the message non-tx should provide a result even after deletion
            MessageTable.Entry entry = iterator.next();
            Assert.assertArrayEquals(Bytes.toBytes(payload), entry.getPayload());
            Assert.assertFalse(iterator.hasNext());
        }
        Transaction tx = new Transaction(200, 200, new long[0], new long[0], -1);
        try (CloseableIterator<MessageTable.Entry> iterator = table.fetch(metadata, new MessageId(messageId), true, 50, tx)) {
            // Fetching messages transactionally should not return any entry
            Assert.assertFalse(iterator.hasNext());
        }
    }
}
Also used : RollbackDetail(io.cdap.cdap.messaging.RollbackDetail) ArrayList(java.util.ArrayList) TopicMetadata(io.cdap.cdap.messaging.TopicMetadata) Transaction(org.apache.tephra.Transaction) TopicId(io.cdap.cdap.proto.id.TopicId) MessageId(io.cdap.cdap.messaging.data.MessageId) Test(org.junit.Test)

Example 19 with TopicMetadata

use of io.cdap.cdap.messaging.TopicMetadata in project cdap by caskdata.

the class MetadataTableTest method testCRUD.

@Test
public void testCRUD() throws Exception {
    try (MetadataTable table = createMetadataTable()) {
        TopicId topicId = NamespaceId.DEFAULT.topic("topic");
        // Update a non-existing topic should fail.
        try {
            table.updateTopic(new TopicMetadata(topicId, "ttl", 10));
            Assert.fail("Expected TopicNotFoundException");
        } catch (TopicNotFoundException e) {
        // Expected
        }
        // Create a topic and validate
        table.createTopic(new TopicMetadata(topicId, "ttl", 10));
        Assert.assertEquals(10, table.getMetadata(topicId).getTTL());
        // Update the property and validate
        table.updateTopic(new TopicMetadata(topicId, "ttl", 30));
        Assert.assertEquals(30, table.getMetadata(topicId).getTTL());
        // Create the same topic again should fail
        try {
            table.createTopic(new TopicMetadata(topicId, "ttl", 10));
            Assert.fail("Expected TopicAlreadyExistsException");
        } catch (TopicAlreadyExistsException e) {
        // Expected
        }
        // It shouldn't affect the topic at all if creation failed
        Assert.assertEquals(30, table.getMetadata(topicId).getTTL());
        // Delete the topic
        table.deleteTopic(topicId);
        try {
            table.getMetadata(topicId);
            Assert.fail("Expected TopicNotFoundException");
        } catch (TopicNotFoundException e) {
        // Expected
        }
        // Delete again should raise a TopicNotFoundException
        try {
            table.deleteTopic(topicId);
            Assert.fail("Expected TopicNotFoundException");
        } catch (TopicNotFoundException e) {
        // Expected
        }
    }
}
Also used : TopicNotFoundException(io.cdap.cdap.api.messaging.TopicNotFoundException) TopicId(io.cdap.cdap.proto.id.TopicId) TopicAlreadyExistsException(io.cdap.cdap.api.messaging.TopicAlreadyExistsException) TopicMetadata(io.cdap.cdap.messaging.TopicMetadata) Test(org.junit.Test)

Example 20 with TopicMetadata

use of io.cdap.cdap.messaging.TopicMetadata in project cdap by caskdata.

the class LevelDBMetadataTable method createTopic.

@Override
public void createTopic(TopicMetadata topicMetadata) throws TopicAlreadyExistsException, IOException {
    try {
        TopicId topicId = topicMetadata.getTopicId();
        byte[] key = MessagingUtils.toMetadataRowKey(topicId);
        TreeMap<String, String> properties = new TreeMap<>(topicMetadata.getProperties());
        properties.put(TopicMetadata.GENERATION_KEY, MessagingUtils.Constants.DEFAULT_GENERATION);
        synchronized (this) {
            byte[] tableValue = levelDB.get(key);
            if (tableValue != null) {
                Map<String, String> oldProperties = GSON.fromJson(Bytes.toString(tableValue), MAP_TYPE);
                TopicMetadata metadata = new TopicMetadata(topicId, oldProperties);
                if (metadata.exists()) {
                    throw new TopicAlreadyExistsException(topicId.getNamespace(), topicId.getTopic());
                }
                int newGenerationId = (metadata.getGeneration() * -1) + 1;
                properties.put(TopicMetadata.GENERATION_KEY, Integer.toString(newGenerationId));
            }
            byte[] value = Bytes.toBytes(GSON.toJson(properties, MAP_TYPE));
            levelDB.put(key, value, WRITE_OPTIONS);
        }
    } catch (DBException e) {
        throw new IOException(e);
    }
}
Also used : DBException(org.iq80.leveldb.DBException) TopicId(io.cdap.cdap.proto.id.TopicId) IOException(java.io.IOException) TreeMap(java.util.TreeMap) TopicAlreadyExistsException(io.cdap.cdap.api.messaging.TopicAlreadyExistsException) TopicMetadata(io.cdap.cdap.messaging.TopicMetadata)

Aggregations

TopicMetadata (io.cdap.cdap.messaging.TopicMetadata)114 TopicId (io.cdap.cdap.proto.id.TopicId)82 Test (org.junit.Test)64 ArrayList (java.util.ArrayList)46 IOException (java.io.IOException)34 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)32 TopicNotFoundException (io.cdap.cdap.api.messaging.TopicNotFoundException)28 MessageId (io.cdap.cdap.messaging.data.MessageId)24 RawMessage (io.cdap.cdap.messaging.data.RawMessage)24 TopicAlreadyExistsException (io.cdap.cdap.api.messaging.TopicAlreadyExistsException)14 TreeMap (java.util.TreeMap)14 MessageTable (io.cdap.cdap.messaging.store.MessageTable)12 CConfiguration (io.cdap.cdap.common.conf.CConfiguration)10 TimeProvider (io.cdap.cdap.common.utils.TimeProvider)10 MessagingService (io.cdap.cdap.messaging.MessagingService)10 DBException (org.iq80.leveldb.DBException)10 AbstractModule (com.google.inject.AbstractModule)8 Injector (com.google.inject.Injector)8 ConfigModule (io.cdap.cdap.common.guice.ConfigModule)8 InMemoryDiscoveryModule (io.cdap.cdap.common.guice.InMemoryDiscoveryModule)8