Search in sources :

Example 1 with MessagePublisher

use of co.cask.cdap.api.messaging.MessagePublisher in project cdap by caskdata.

the class AbstractContext method createRuntimeProgramContext.

/**
   * Creates a new instance of {@link RuntimeProgramContext} to be
   * provided to {@link RuntimeProgramContextAware} dataset.
   */
private RuntimeProgramContext createRuntimeProgramContext(final DatasetId datasetId) {
    return new RuntimeProgramContext() {

        @Override
        public void notifyNewPartitions(Collection<? extends PartitionKey> partitionKeys) throws IOException {
            String topic = cConf.get(Constants.Dataset.DATA_EVENT_TOPIC);
            if (Strings.isNullOrEmpty(topic)) {
                // Don't publish if there is no data event topic
                return;
            }
            TopicId dataEventTopic = NamespaceId.SYSTEM.topic(topic);
            MessagePublisher publisher = getMessagingContext().getMessagePublisher();
            byte[] payload = Bytes.toBytes(GSON.toJson(Notification.forPartitions(datasetId, partitionKeys)));
            int failure = 0;
            long startTime = System.currentTimeMillis();
            while (true) {
                try {
                    publisher.publish(dataEventTopic.getNamespace(), dataEventTopic.getTopic(), payload);
                    return;
                } catch (TopicNotFoundException e) {
                    // this shouldn't happen since the TMS creates the data event topic on startup.
                    throw new IOException("Unexpected exception due to missing topic '" + dataEventTopic + "'", e);
                } catch (IOException e) {
                    long sleepTime = retryStrategy.nextRetry(++failure, startTime);
                    if (sleepTime < 0) {
                        throw e;
                    }
                    try {
                        TimeUnit.MILLISECONDS.sleep(sleepTime);
                    } catch (InterruptedException ex) {
                        // If interrupted during sleep, just reset the interrupt flag and return
                        Thread.currentThread().interrupt();
                        return;
                    }
                }
            }
        }

        @Override
        public ProgramRunId getProgramRunId() {
            return programRunId;
        }

        @Nullable
        @Override
        public NamespacedEntityId getComponentId() {
            return AbstractContext.this.getComponentId();
        }
    };
}
Also used : RuntimeProgramContext(co.cask.cdap.data.RuntimeProgramContext) MessagePublisher(co.cask.cdap.api.messaging.MessagePublisher) TopicNotFoundException(co.cask.cdap.api.messaging.TopicNotFoundException) Collection(java.util.Collection) PartitionKey(co.cask.cdap.api.dataset.lib.PartitionKey) TopicId(co.cask.cdap.proto.id.TopicId) IOException(java.io.IOException)

Example 2 with MessagePublisher

use of co.cask.cdap.api.messaging.MessagePublisher in project cdap by caskdata.

the class MessagingAppTestRun method testWithWorker.

@Test
public void testWithWorker() throws Exception {
    ApplicationManager appManager = deployWithArtifact(NAMESPACE, MessagingApp.class, artifactJar);
    final WorkerManager workerManager = appManager.getWorkerManager(MessagingApp.MessagingWorker.class.getSimpleName()).start();
    MessagingContext messagingContext = getMessagingContext();
    final MessagingAdmin messagingAdmin = getMessagingAdmin(NAMESPACE);
    // Wait for the worker to create the topic
    Tasks.waitFor(true, new Callable<Boolean>() {

        @Override
        public Boolean call() throws Exception {
            try {
                messagingAdmin.getTopicProperties(MessagingApp.TOPIC);
                return true;
            } catch (TopicNotFoundException e) {
                return false;
            }
        }
    }, 5, TimeUnit.SECONDS, 100, TimeUnit.MILLISECONDS);
    // Publish a message
    String message = "message";
    MessagePublisher messagePublisher = messagingContext.getMessagePublisher();
    messagePublisher.publish(NAMESPACE.getNamespace(), MessagingApp.TOPIC, message);
    // The worker will publish back a message with payload as concat(message, message)
    final MessageFetcher messageFetcher = messagingContext.getMessageFetcher();
    Tasks.waitFor(message + message, new Callable<String>() {

        @Override
        public String call() throws Exception {
            try (CloseableIterator<Message> iterator = messageFetcher.fetch(NAMESPACE.getNamespace(), MessagingApp.TOPIC, Integer.MAX_VALUE, 0L)) {
                Message message = Iterators.getLast(iterator, null);
                return message == null ? null : message.getPayloadAsString();
            }
        }
    }, 5, TimeUnit.SECONDS, 100, TimeUnit.MILLISECONDS);
    // Publish concat(message + message) to the app
    messagePublisher.publish(NAMESPACE.getNamespace(), MessagingApp.TOPIC, message + message);
    // timeout.
    try {
        Tasks.waitFor(message + message + message + message, new Callable<String>() {

            @Override
            public String call() throws Exception {
                try (CloseableIterator<Message> iterator = messageFetcher.fetch(NAMESPACE.getNamespace(), MessagingApp.TOPIC, Integer.MAX_VALUE, 0L)) {
                    Message message = Iterators.getLast(iterator, null);
                    return message == null ? null : message.getPayloadAsString();
                }
            }
        }, 2, TimeUnit.SECONDS, 100, TimeUnit.MILLISECONDS);
        Assert.fail("Expected timeout exception");
    } catch (TimeoutException e) {
    // expected
    }
    // Now publish a message to the control topic, to unblock the transaction block.
    messagePublisher.publish(NAMESPACE.getNamespace(), MessagingApp.CONTROL_TOPIC, message);
    // Should expect a new message as concat(message, message, message, message)
    Tasks.waitFor(message + message + message + message, new Callable<String>() {

        @Override
        public String call() throws Exception {
            try (CloseableIterator<Message> iterator = messageFetcher.fetch(NAMESPACE.getNamespace(), MessagingApp.TOPIC, Integer.MAX_VALUE, 0L)) {
                Message message = Iterators.getLast(iterator, null);
                return message == null ? null : message.getPayloadAsString();
            }
        }
    }, 5, TimeUnit.SECONDS, 100, TimeUnit.MILLISECONDS);
    // Wait for the worker to finish and verify that it completes successfully.
    workerManager.waitForRun(ProgramRunStatus.COMPLETED, 5, TimeUnit.SECONDS);
}
Also used : ApplicationManager(co.cask.cdap.test.ApplicationManager) MessageFetcher(co.cask.cdap.api.messaging.MessageFetcher) CloseableIterator(co.cask.cdap.api.dataset.lib.CloseableIterator) Message(co.cask.cdap.api.messaging.Message) TopicNotFoundException(co.cask.cdap.api.messaging.TopicNotFoundException) MessagePublisher(co.cask.cdap.api.messaging.MessagePublisher) TopicNotFoundException(co.cask.cdap.api.messaging.TopicNotFoundException) TimeoutException(java.util.concurrent.TimeoutException) WorkerManager(co.cask.cdap.test.WorkerManager) MessagingAdmin(co.cask.cdap.api.messaging.MessagingAdmin) MessagingContext(co.cask.cdap.api.messaging.MessagingContext) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.Test)

Aggregations

MessagePublisher (co.cask.cdap.api.messaging.MessagePublisher)2 TopicNotFoundException (co.cask.cdap.api.messaging.TopicNotFoundException)2 CloseableIterator (co.cask.cdap.api.dataset.lib.CloseableIterator)1 PartitionKey (co.cask.cdap.api.dataset.lib.PartitionKey)1 Message (co.cask.cdap.api.messaging.Message)1 MessageFetcher (co.cask.cdap.api.messaging.MessageFetcher)1 MessagingAdmin (co.cask.cdap.api.messaging.MessagingAdmin)1 MessagingContext (co.cask.cdap.api.messaging.MessagingContext)1 RuntimeProgramContext (co.cask.cdap.data.RuntimeProgramContext)1 TopicId (co.cask.cdap.proto.id.TopicId)1 ApplicationManager (co.cask.cdap.test.ApplicationManager)1 WorkerManager (co.cask.cdap.test.WorkerManager)1 IOException (java.io.IOException)1 Collection (java.util.Collection)1 TimeoutException (java.util.concurrent.TimeoutException)1 Test (org.junit.Test)1