Search in sources :

Example 1 with TopicMetadata

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

the class TetheringRuntimeJobManagerTest method setUp.

@BeforeClass
public static void setUp() throws IOException, TopicAlreadyExistsException {
    CConfiguration cConf = CConfiguration.create();
    cConf.set(Constants.Tethering.TOPIC_PREFIX, "prefix-");
    cConf.set(Constants.CFG_LOCAL_DATA_DIR, TEMP_FOLDER.newFolder().getAbsolutePath());
    Injector injector = Guice.createInjector(new ConfigModule(cConf), new InMemoryDiscoveryModule(), new LocalLocationModule(), new MessagingServerRuntimeModule().getInMemoryModules(), new AbstractModule() {

        @Override
        protected void configure() {
            bind(MetricsCollectionService.class).to(NoOpMetricsCollectionService.class).in(Scopes.SINGLETON);
        }
    });
    messagingService = injector.getInstance(MessagingService.class);
    if (messagingService instanceof Service) {
        ((Service) messagingService).startAndWait();
    }
    TetheringConf conf = TetheringConf.fromProperties(PROPERTIES);
    topicId = new TopicId(NamespaceId.SYSTEM.getNamespace(), cConf.get(Constants.Tethering.TOPIC_PREFIX) + TETHERED_INSTANCE_NAME);
    messagingService.createTopic(new TopicMetadata(topicId, Collections.emptyMap()));
    messageFetcher = new MultiThreadMessagingContext(messagingService).getMessageFetcher();
    runtimeJobManager = new TetheringRuntimeJobManager(conf, cConf, messagingService);
}
Also used : InMemoryDiscoveryModule(io.cdap.cdap.common.guice.InMemoryDiscoveryModule) NoOpMetricsCollectionService(io.cdap.cdap.common.metrics.NoOpMetricsCollectionService) MetricsCollectionService(io.cdap.cdap.api.metrics.MetricsCollectionService) ConfigModule(io.cdap.cdap.common.guice.ConfigModule) NoOpMetricsCollectionService(io.cdap.cdap.common.metrics.NoOpMetricsCollectionService) MessagingService(io.cdap.cdap.messaging.MessagingService) Service(com.google.common.util.concurrent.Service) MetricsCollectionService(io.cdap.cdap.api.metrics.MetricsCollectionService) MessagingServerRuntimeModule(io.cdap.cdap.messaging.guice.MessagingServerRuntimeModule) MultiThreadMessagingContext(io.cdap.cdap.messaging.context.MultiThreadMessagingContext) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) AbstractModule(com.google.inject.AbstractModule) MessagingService(io.cdap.cdap.messaging.MessagingService) TopicMetadata(io.cdap.cdap.messaging.TopicMetadata) LocalLocationModule(io.cdap.cdap.common.guice.LocalLocationModule) TetheringConf(io.cdap.cdap.internal.tethering.runtime.spi.provisioner.TetheringConf) Injector(com.google.inject.Injector) TopicId(io.cdap.cdap.proto.id.TopicId) BeforeClass(org.junit.BeforeClass)

Example 2 with TopicMetadata

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

the class ConcurrentMessageWriterTest method testMultiMaxSequence.

@Test
public void testMultiMaxSequence() throws IOException, InterruptedException {
    TopicId topicId = new NamespaceId("ns1").topic("t1");
    final TopicMetadata metadata = new TopicMetadata(topicId, new HashMap<String, String>(), 1);
    // This test the case when multiple StoreRequests combined exceeding the 65536 payload.
    // See testMaxSequence() for more details when it matters
    // Generate 3 StoreRequests, each with 43690 messages
    int msgCount = StoreRequestWriter.SEQUENCE_ID_LIMIT / 3 * 2;
    int requestCount = 3;
    List<StoreRequest> requests = new ArrayList<>();
    for (int i = 0; i < requestCount; i++) {
        List<String> payloads = new ArrayList<>(msgCount);
        for (int j = 0; j < msgCount; j++) {
            payloads.add(Integer.toString(j));
        }
        requests.add(new TestStoreRequest(topicId, payloads));
    }
    TestStoreRequestWriter testWriter = new TestStoreRequestWriter(new TimeProvider.IncrementalTimeProvider());
    // We use a custom metrics collector here to make all the persist calls reached the same latch,
    // since we know that the ConcurrentMessageWriter will emit a metrics "persist.requested" after enqueued but
    // before flushing.
    // This will make all requests batched together
    final CountDownLatch latch = new CountDownLatch(requestCount);
    final ConcurrentMessageWriter writer = new ConcurrentMessageWriter(testWriter, new MetricsCollector() {

        @Override
        public void increment(String metricName, long value) {
            if ("persist.requested".equals(metricName)) {
                latch.countDown();
                Uninterruptibles.awaitUninterruptibly(latch);
            }
        }

        @Override
        public void gauge(String metricName, long value) {
            LOG.info("MetricsContext.gauge: {} = {}", metricName, value);
        }
    });
    ExecutorService executor = Executors.newFixedThreadPool(3);
    for (final StoreRequest request : requests) {
        executor.submit(new Runnable() {

            @Override
            public void run() {
                try {
                    writer.persist(request, metadata);
                } catch (IOException e) {
                    LOG.error("Failed to persist", e);
                }
            }
        });
    }
    executor.shutdown();
    Assert.assertTrue(executor.awaitTermination(1, TimeUnit.MINUTES));
    // Validates all messages are being written
    List<RawMessage> messages = testWriter.getMessages().get(topicId);
    Assert.assertEquals(requestCount * msgCount, messages.size());
    // We expect the payload is in repeated sequence of [0..msgCount-1]
    int expectedPayload = 0;
    // The sequenceId should be (i % SEQUENCE_ID_LIMIT)
    for (int i = 0; i < messages.size(); i++) {
        RawMessage message = messages.get(i);
        MessageId messageId = new MessageId(message.getId());
        Assert.assertEquals(i / StoreRequestWriter.SEQUENCE_ID_LIMIT, messageId.getPublishTimestamp());
        Assert.assertEquals((short) (i % StoreRequestWriter.SEQUENCE_ID_LIMIT), messageId.getSequenceId());
        Assert.assertEquals(expectedPayload, Integer.parseInt(Bytes.toString(message.getPayload())));
        expectedPayload = (expectedPayload + 1) % msgCount;
    }
}
Also used : ArrayList(java.util.ArrayList) TopicId(io.cdap.cdap.proto.id.TopicId) RawMessage(io.cdap.cdap.messaging.data.RawMessage) MetricsCollector(io.cdap.cdap.api.metrics.MetricsCollector) TimeProvider(io.cdap.cdap.common.utils.TimeProvider) StoreRequest(io.cdap.cdap.messaging.StoreRequest) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) TopicMetadata(io.cdap.cdap.messaging.TopicMetadata) ExecutorService(java.util.concurrent.ExecutorService) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) MessageId(io.cdap.cdap.messaging.data.MessageId) Test(org.junit.Test)

Example 3 with TopicMetadata

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

the class ConcurrentMessageWriterTest method testBasic.

@Test
public void testBasic() throws IOException {
    TopicId topicId1 = new NamespaceId("ns1").topic("t1");
    TopicId topicId2 = new NamespaceId("ns2").topic("t2");
    TopicMetadata metadata1 = new TopicMetadata(topicId1, new HashMap<String, String>(), 1);
    TopicMetadata metadata2 = new TopicMetadata(topicId2, new HashMap<String, String>(), 1);
    TestStoreRequestWriter testWriter = new TestStoreRequestWriter(new TimeProvider.IncrementalTimeProvider());
    ConcurrentMessageWriter writer = new ConcurrentMessageWriter(testWriter);
    writer.persist(new TestStoreRequest(topicId1, Arrays.asList("1", "2", "3")), metadata1);
    // There should be 3 messages being written
    List<RawMessage> messages = testWriter.getMessages().get(topicId1);
    Assert.assertEquals(3, messages.size());
    // All messages should be written with timestamp 0
    List<String> payloads = new ArrayList<>();
    for (RawMessage message : messages) {
        Assert.assertEquals(0L, new MessageId(message.getId()).getPublishTimestamp());
        payloads.add(Bytes.toString(message.getPayload()));
    }
    Assert.assertEquals(Arrays.asList("1", "2", "3"), payloads);
    // Write to another topic
    writer.persist(new TestStoreRequest(topicId2, Arrays.asList("a", "b", "c")), metadata2);
    // There should be 3 messages being written to topic2
    messages = testWriter.getMessages().get(topicId2);
    Assert.assertEquals(3, messages.size());
    // All messages should be written with timestamp 1
    payloads.clear();
    for (RawMessage message : messages) {
        Assert.assertEquals(1L, new MessageId(message.getId()).getPublishTimestamp());
        payloads.add(Bytes.toString(message.getPayload()));
    }
    Assert.assertEquals(Arrays.asList("a", "b", "c"), payloads);
}
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 4 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 5 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)

Aggregations

TopicMetadata (io.cdap.cdap.messaging.TopicMetadata)57 TopicId (io.cdap.cdap.proto.id.TopicId)41 Test (org.junit.Test)32 ArrayList (java.util.ArrayList)23 IOException (java.io.IOException)17 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)16 TopicNotFoundException (io.cdap.cdap.api.messaging.TopicNotFoundException)14 MessageId (io.cdap.cdap.messaging.data.MessageId)12 RawMessage (io.cdap.cdap.messaging.data.RawMessage)12 TopicAlreadyExistsException (io.cdap.cdap.api.messaging.TopicAlreadyExistsException)7 TreeMap (java.util.TreeMap)7 MessageTable (io.cdap.cdap.messaging.store.MessageTable)6 CConfiguration (io.cdap.cdap.common.conf.CConfiguration)5 TimeProvider (io.cdap.cdap.common.utils.TimeProvider)5 MessagingService (io.cdap.cdap.messaging.MessagingService)5 AbstractModule (com.google.inject.AbstractModule)4 Injector (com.google.inject.Injector)4 ConfigModule (io.cdap.cdap.common.guice.ConfigModule)4 InMemoryDiscoveryModule (io.cdap.cdap.common.guice.InMemoryDiscoveryModule)4 NoOpMetricsCollectionService (io.cdap.cdap.common.metrics.NoOpMetricsCollectionService)4