Search in sources :

Example 1 with Sink

use of org.apache.pulsar.io.core.Sink in project pulsar by apache.

the class PulsarFunctionLocalRunTest method testE2EPulsarFunctionLocalRun.

/**
 * Validates pulsar sink e2e functionality on functions.
 *
 * @throws Exception
 */
private void testE2EPulsarFunctionLocalRun(String jarFilePathUrl, int parallelism) throws Exception {
    final String namespacePortion = "io";
    final String replNamespace = tenant + "/" + namespacePortion;
    final String sourceTopic = "persistent://" + replNamespace + "/my-topic1";
    final String sinkTopic = "persistent://" + replNamespace + "/output";
    final String propertyKey = "key";
    final String propertyValue = "value";
    final String functionName = "PulsarFunction-test";
    final String subscriptionName = "test-sub";
    admin.namespaces().createNamespace(replNamespace);
    Set<String> clusters = Sets.newHashSet(Lists.newArrayList(CLUSTER));
    admin.namespaces().setNamespaceReplicationClusters(replNamespace, clusters);
    // create a producer that creates a topic at broker
    Producer<String> producer = pulsarClient.newProducer(Schema.STRING).topic(sourceTopic).create();
    Consumer<String> consumer = pulsarClient.newConsumer(Schema.STRING).topic(sinkTopic).subscriptionName("sub").subscribe();
    FunctionConfig functionConfig = createFunctionConfig(tenant, namespacePortion, functionName, sourceTopic, sinkTopic, subscriptionName);
    functionConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE);
    functionConfig.setJar(jarFilePathUrl);
    functionConfig.setParallelism(parallelism);
    int metricsPort = FunctionCommon.findAvailablePort();
    @Cleanup LocalRunner localRunner = LocalRunner.builder().functionConfig(functionConfig).clientAuthPlugin(AuthenticationTls.class.getName()).clientAuthParams(String.format("tlsCertFile:%s,tlsKeyFile:%s", TLS_CLIENT_CERT_FILE_PATH, TLS_CLIENT_KEY_FILE_PATH)).useTls(true).tlsTrustCertFilePath(TLS_TRUST_CERT_FILE_PATH).tlsAllowInsecureConnection(true).tlsHostNameVerificationEnabled(false).metricsPortStart(metricsPort).brokerServiceUrl(pulsar.getBrokerServiceUrlTls()).build();
    localRunner.start(false);
    Assert.assertTrue(retryStrategically((test) -> {
        try {
            boolean result = false;
            TopicStats topicStats = admin.topics().getStats(sourceTopic);
            if (topicStats.getSubscriptions().containsKey(subscriptionName) && topicStats.getSubscriptions().get(subscriptionName).getConsumers().size() == parallelism) {
                for (ConsumerStats consumerStats : topicStats.getSubscriptions().get(subscriptionName).getConsumers()) {
                    result = consumerStats.getAvailablePermits() == 1000 && consumerStats.getMetadata() != null && consumerStats.getMetadata().containsKey("id") && consumerStats.getMetadata().get("id").equals(String.format("%s/%s/%s", tenant, namespacePortion, functionName));
                }
            }
            return result;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 50, 150));
    // validate pulsar sink consumer has started on the topic
    TopicStats stats = admin.topics().getStats(sourceTopic);
    assertTrue(stats.getSubscriptions().get(subscriptionName) != null && !stats.getSubscriptions().get(subscriptionName).getConsumers().isEmpty());
    int totalMsgs = 5;
    for (int i = 0; i < totalMsgs; i++) {
        String data = "my-message-" + i;
        producer.newMessage().property(propertyKey, propertyValue).value(data).send();
    }
    retryStrategically((test) -> {
        try {
            SubscriptionStats subStats = admin.topics().getStats(sourceTopic).getSubscriptions().get(subscriptionName);
            return subStats.getUnackedMessages() == 0;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 50, 150);
    for (int i = 0; i < totalMsgs; i++) {
        Message<String> msg = consumer.receive(5, TimeUnit.SECONDS);
        String receivedPropertyValue = msg.getProperty(propertyKey);
        assertEquals(propertyValue, receivedPropertyValue);
        assertEquals(msg.getValue(), "my-message-" + i + "!");
    }
    // validate pulsar-sink consumer has consumed all messages and delivered to Pulsar sink but unacked messages
    // due to publish failure
    assertNotEquals(admin.topics().getStats(sourceTopic).getSubscriptions().values().iterator().next().getUnackedMessages(), totalMsgs);
    // validate prometheus metrics
    String prometheusMetrics = PulsarFunctionTestUtils.getPrometheusMetrics(metricsPort);
    log.info("prometheus metrics: {}", prometheusMetrics);
    Map<String, PulsarFunctionTestUtils.Metric> metricsMap = new HashMap<>();
    Arrays.asList(prometheusMetrics.split("\n")).forEach(line -> {
        if (line.startsWith("pulsar_function_processed_successfully_total")) {
            Map<String, PulsarFunctionTestUtils.Metric> metrics = PulsarFunctionTestUtils.parseMetrics(line);
            assertFalse(metrics.isEmpty());
            PulsarFunctionTestUtils.Metric m = metrics.get("pulsar_function_processed_successfully_total");
            if (m != null) {
                metricsMap.put(m.tags.get("instance_id"), m);
            }
        }
    });
    Assert.assertEquals(metricsMap.size(), parallelism);
    double totalMsgRecv = 0.0;
    for (int i = 0; i < parallelism; i++) {
        PulsarFunctionTestUtils.Metric m = metricsMap.get(String.valueOf(i));
        Assert.assertNotNull(m);
        assertEquals(m.tags.get("cluster"), config.getClusterName());
        assertEquals(m.tags.get("instance_id"), String.valueOf(i));
        assertEquals(m.tags.get("name"), functionName);
        assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
        assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
        totalMsgRecv += m.value;
    }
    Assert.assertEquals(totalMsgRecv, totalMsgs);
    // stop functions
    localRunner.stop();
    retryStrategically((test) -> {
        try {
            TopicStats topicStats = admin.topics().getStats(sourceTopic);
            return topicStats.getSubscriptions().get(subscriptionName) != null && topicStats.getSubscriptions().get(subscriptionName).getConsumers().isEmpty();
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 20, 150);
    TopicStats topicStats = admin.topics().getStats(sourceTopic);
    assertTrue(topicStats.getSubscriptions().get(subscriptionName) != null && topicStats.getSubscriptions().get(subscriptionName).getConsumers().isEmpty());
    retryStrategically((test) -> {
        try {
            return (admin.topics().getStats(sinkTopic).getPublishers().size() == 0);
        } catch (PulsarAdminException e) {
            if (e.getStatusCode() == 404) {
                return true;
            }
            return false;
        }
    }, 10, 150);
    try {
        assertEquals(admin.topics().getStats(sinkTopic).getPublishers().size(), 0);
    } catch (PulsarAdminException e) {
        if (e.getStatusCode() != 404) {
            fail();
        }
    }
}
Also used : FunctionConfig(org.apache.pulsar.common.functions.FunctionConfig) LocalRunner(org.apache.pulsar.functions.LocalRunner) SubscriptionStats(org.apache.pulsar.common.policies.data.SubscriptionStats) Arrays(java.util.Arrays) URL(java.net.URL) ObjectMapperFactory(org.apache.pulsar.common.util.ObjectMapperFactory) Producer(org.apache.pulsar.client.api.Producer) LoggerFactory(org.slf4j.LoggerFactory) Cleanup(lombok.Cleanup) Test(org.testng.annotations.Test) ClusterData(org.apache.pulsar.common.policies.data.ClusterData) Sink(org.apache.pulsar.io.core.Sink) AfterMethod(org.testng.annotations.AfterMethod) ByteBuffer(java.nio.ByteBuffer) URLClassLoader(java.net.URLClassLoader) NarClassLoader(org.apache.pulsar.common.nar.NarClassLoader) Map(java.util.Map) MockedPulsarServiceBaseTest.retryStrategically(org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest.retryStrategically) FunctionConfig(org.apache.pulsar.common.functions.FunctionConfig) ThreadRuntimeFactoryConfig(org.apache.pulsar.functions.runtime.thread.ThreadRuntimeFactoryConfig) Assert.assertFalse(org.testng.Assert.assertFalse) Method(java.lang.reflect.Method) Record(org.apache.pulsar.functions.api.Record) Assert.assertNotEquals(org.testng.Assert.assertNotEquals) BeforeClass(org.testng.annotations.BeforeClass) BeforeMethod(org.testng.annotations.BeforeMethod) Set(java.util.Set) Sets(com.google.common.collect.Sets) Objects(java.util.Objects) Consumer(org.apache.pulsar.client.api.Consumer) FutureUtil(org.apache.pulsar.common.util.FutureUtil) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) LocalBookkeeperEnsemble(org.apache.pulsar.zookeeper.LocalBookkeeperEnsemble) ServiceConfigurationUtils(org.apache.pulsar.broker.ServiceConfigurationUtils) AuthenticationProviderTls(org.apache.pulsar.broker.authentication.AuthenticationProviderTls) PulsarAuthorizationProvider(org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider) ClientBuilder(org.apache.pulsar.client.api.ClientBuilder) Optional(java.util.Optional) SimpleLoadManagerImpl(org.apache.pulsar.broker.loadbalance.impl.SimpleLoadManagerImpl) PublisherStats(org.apache.pulsar.common.policies.data.PublisherStats) Utils(org.apache.pulsar.common.functions.Utils) DataProvider(org.testng.annotations.DataProvider) TopicStats(org.apache.pulsar.common.policies.data.TopicStats) Assert.assertEquals(org.testng.Assert.assertEquals) HashMap(java.util.HashMap) PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) Message(org.apache.pulsar.client.api.Message) Mockito.spy(org.mockito.Mockito.spy) HashSet(java.util.HashSet) AuthenticationTls(org.apache.pulsar.client.impl.auth.AuthenticationTls) Lists(com.google.common.collect.Lists) NarClassLoaderBuilder(org.apache.pulsar.common.nar.NarClassLoaderBuilder) ThreadRuntimeFactory(org.apache.pulsar.functions.runtime.thread.ThreadRuntimeFactory) Assert(org.testng.Assert) SchemaDefinition(org.apache.pulsar.client.api.schema.SchemaDefinition) PulsarClient(org.apache.pulsar.client.api.PulsarClient) TenantInfo(org.apache.pulsar.common.policies.data.TenantInfo) AfterClass(org.testng.annotations.AfterClass) SourceConfig(org.apache.pulsar.common.io.SourceConfig) Logger(org.slf4j.Logger) MalformedURLException(java.net.MalformedURLException) Files(java.nio.file.Files) JAVA_INSTANCE_JAR_PROPERTY(org.apache.pulsar.functions.utils.functioncache.FunctionCacheEntry.JAVA_INSTANCE_JAR_PROPERTY) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) Assert.fail(org.testng.Assert.fail) ConsumerConfig(org.apache.pulsar.common.functions.ConsumerConfig) SinkConfig(org.apache.pulsar.common.io.SinkConfig) IOException(java.io.IOException) PulsarService(org.apache.pulsar.broker.PulsarService) File(java.io.File) Schema(org.apache.pulsar.client.api.Schema) TimeUnit(java.util.concurrent.TimeUnit) GenericRecord(org.apache.pulsar.client.api.schema.GenericRecord) FunctionCommon(org.apache.pulsar.functions.utils.FunctionCommon) SinkContext(org.apache.pulsar.io.core.SinkContext) Authentication(org.apache.pulsar.client.api.Authentication) Assert.assertTrue(org.testng.Assert.assertTrue) ConsumerStats(org.apache.pulsar.common.policies.data.ConsumerStats) BrokerStats(org.apache.pulsar.client.admin.BrokerStats) Collections(java.util.Collections) LocalRunner(org.apache.pulsar.functions.LocalRunner) SubscriptionStats(org.apache.pulsar.common.policies.data.SubscriptionStats) HashMap(java.util.HashMap) ConsumerStats(org.apache.pulsar.common.policies.data.ConsumerStats) Cleanup(lombok.Cleanup) AuthenticationTls(org.apache.pulsar.client.impl.auth.AuthenticationTls) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) TopicStats(org.apache.pulsar.common.policies.data.TopicStats)

Example 2 with Sink

use of org.apache.pulsar.io.core.Sink in project pulsar by yahoo.

the class PulsarFunctionLocalRunTest method testE2EPulsarFunctionLocalRun.

/**
 * Validates pulsar sink e2e functionality on functions.
 *
 * @throws Exception
 */
private void testE2EPulsarFunctionLocalRun(String jarFilePathUrl, int parallelism) throws Exception {
    final String namespacePortion = "io";
    final String replNamespace = tenant + "/" + namespacePortion;
    final String sourceTopic = "persistent://" + replNamespace + "/my-topic1";
    final String sinkTopic = "persistent://" + replNamespace + "/output";
    final String propertyKey = "key";
    final String propertyValue = "value";
    final String functionName = "PulsarFunction-test";
    final String subscriptionName = "test-sub";
    admin.namespaces().createNamespace(replNamespace);
    Set<String> clusters = Sets.newHashSet(Lists.newArrayList(CLUSTER));
    admin.namespaces().setNamespaceReplicationClusters(replNamespace, clusters);
    // create a producer that creates a topic at broker
    Producer<String> producer = pulsarClient.newProducer(Schema.STRING).topic(sourceTopic).create();
    Consumer<String> consumer = pulsarClient.newConsumer(Schema.STRING).topic(sinkTopic).subscriptionName("sub").subscribe();
    FunctionConfig functionConfig = createFunctionConfig(tenant, namespacePortion, functionName, sourceTopic, sinkTopic, subscriptionName);
    functionConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE);
    functionConfig.setJar(jarFilePathUrl);
    functionConfig.setParallelism(parallelism);
    int metricsPort = FunctionCommon.findAvailablePort();
    @Cleanup LocalRunner localRunner = LocalRunner.builder().functionConfig(functionConfig).clientAuthPlugin(AuthenticationTls.class.getName()).clientAuthParams(String.format("tlsCertFile:%s,tlsKeyFile:%s", TLS_CLIENT_CERT_FILE_PATH, TLS_CLIENT_KEY_FILE_PATH)).useTls(true).tlsTrustCertFilePath(TLS_TRUST_CERT_FILE_PATH).tlsAllowInsecureConnection(true).tlsHostNameVerificationEnabled(false).metricsPortStart(metricsPort).brokerServiceUrl(pulsar.getBrokerServiceUrlTls()).build();
    localRunner.start(false);
    Assert.assertTrue(retryStrategically((test) -> {
        try {
            boolean result = false;
            TopicStats topicStats = admin.topics().getStats(sourceTopic);
            if (topicStats.getSubscriptions().containsKey(subscriptionName) && topicStats.getSubscriptions().get(subscriptionName).getConsumers().size() == parallelism) {
                for (ConsumerStats consumerStats : topicStats.getSubscriptions().get(subscriptionName).getConsumers()) {
                    result = consumerStats.getAvailablePermits() == 1000 && consumerStats.getMetadata() != null && consumerStats.getMetadata().containsKey("id") && consumerStats.getMetadata().get("id").equals(String.format("%s/%s/%s", tenant, namespacePortion, functionName));
                }
            }
            return result;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 50, 150));
    // validate pulsar sink consumer has started on the topic
    TopicStats stats = admin.topics().getStats(sourceTopic);
    assertTrue(stats.getSubscriptions().get(subscriptionName) != null && !stats.getSubscriptions().get(subscriptionName).getConsumers().isEmpty());
    int totalMsgs = 5;
    for (int i = 0; i < totalMsgs; i++) {
        String data = "my-message-" + i;
        producer.newMessage().property(propertyKey, propertyValue).value(data).send();
    }
    retryStrategically((test) -> {
        try {
            SubscriptionStats subStats = admin.topics().getStats(sourceTopic).getSubscriptions().get(subscriptionName);
            return subStats.getUnackedMessages() == 0;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 50, 150);
    for (int i = 0; i < totalMsgs; i++) {
        Message<String> msg = consumer.receive(5, TimeUnit.SECONDS);
        String receivedPropertyValue = msg.getProperty(propertyKey);
        assertEquals(propertyValue, receivedPropertyValue);
        assertEquals(msg.getValue(), "my-message-" + i + "!");
    }
    // validate pulsar-sink consumer has consumed all messages and delivered to Pulsar sink but unacked messages
    // due to publish failure
    assertNotEquals(admin.topics().getStats(sourceTopic).getSubscriptions().values().iterator().next().getUnackedMessages(), totalMsgs);
    // validate prometheus metrics
    String prometheusMetrics = PulsarFunctionTestUtils.getPrometheusMetrics(metricsPort);
    log.info("prometheus metrics: {}", prometheusMetrics);
    Map<String, PulsarFunctionTestUtils.Metric> metricsMap = new HashMap<>();
    Arrays.asList(prometheusMetrics.split("\n")).forEach(line -> {
        if (line.startsWith("pulsar_function_processed_successfully_total")) {
            Map<String, PulsarFunctionTestUtils.Metric> metrics = PulsarFunctionTestUtils.parseMetrics(line);
            assertFalse(metrics.isEmpty());
            PulsarFunctionTestUtils.Metric m = metrics.get("pulsar_function_processed_successfully_total");
            if (m != null) {
                metricsMap.put(m.tags.get("instance_id"), m);
            }
        }
    });
    Assert.assertEquals(metricsMap.size(), parallelism);
    double totalMsgRecv = 0.0;
    for (int i = 0; i < parallelism; i++) {
        PulsarFunctionTestUtils.Metric m = metricsMap.get(String.valueOf(i));
        Assert.assertNotNull(m);
        assertEquals(m.tags.get("cluster"), config.getClusterName());
        assertEquals(m.tags.get("instance_id"), String.valueOf(i));
        assertEquals(m.tags.get("name"), functionName);
        assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
        assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
        totalMsgRecv += m.value;
    }
    Assert.assertEquals(totalMsgRecv, totalMsgs);
    // stop functions
    localRunner.stop();
    retryStrategically((test) -> {
        try {
            TopicStats topicStats = admin.topics().getStats(sourceTopic);
            return topicStats.getSubscriptions().get(subscriptionName) != null && topicStats.getSubscriptions().get(subscriptionName).getConsumers().isEmpty();
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 20, 150);
    TopicStats topicStats = admin.topics().getStats(sourceTopic);
    assertTrue(topicStats.getSubscriptions().get(subscriptionName) != null && topicStats.getSubscriptions().get(subscriptionName).getConsumers().isEmpty());
    retryStrategically((test) -> {
        try {
            return (admin.topics().getStats(sinkTopic).getPublishers().size() == 0);
        } catch (PulsarAdminException e) {
            if (e.getStatusCode() == 404) {
                return true;
            }
            return false;
        }
    }, 10, 150);
    try {
        assertEquals(admin.topics().getStats(sinkTopic).getPublishers().size(), 0);
    } catch (PulsarAdminException e) {
        if (e.getStatusCode() != 404) {
            fail();
        }
    }
}
Also used : FunctionConfig(org.apache.pulsar.common.functions.FunctionConfig) LocalRunner(org.apache.pulsar.functions.LocalRunner) SubscriptionStats(org.apache.pulsar.common.policies.data.SubscriptionStats) Arrays(java.util.Arrays) URL(java.net.URL) ObjectMapperFactory(org.apache.pulsar.common.util.ObjectMapperFactory) Producer(org.apache.pulsar.client.api.Producer) LoggerFactory(org.slf4j.LoggerFactory) Cleanup(lombok.Cleanup) Test(org.testng.annotations.Test) ClusterData(org.apache.pulsar.common.policies.data.ClusterData) Sink(org.apache.pulsar.io.core.Sink) AfterMethod(org.testng.annotations.AfterMethod) ByteBuffer(java.nio.ByteBuffer) URLClassLoader(java.net.URLClassLoader) NarClassLoader(org.apache.pulsar.common.nar.NarClassLoader) Map(java.util.Map) MockedPulsarServiceBaseTest.retryStrategically(org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest.retryStrategically) FunctionConfig(org.apache.pulsar.common.functions.FunctionConfig) ThreadRuntimeFactoryConfig(org.apache.pulsar.functions.runtime.thread.ThreadRuntimeFactoryConfig) Assert.assertFalse(org.testng.Assert.assertFalse) Method(java.lang.reflect.Method) Record(org.apache.pulsar.functions.api.Record) Assert.assertNotEquals(org.testng.Assert.assertNotEquals) BeforeClass(org.testng.annotations.BeforeClass) BeforeMethod(org.testng.annotations.BeforeMethod) Set(java.util.Set) Sets(com.google.common.collect.Sets) Objects(java.util.Objects) Consumer(org.apache.pulsar.client.api.Consumer) FutureUtil(org.apache.pulsar.common.util.FutureUtil) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) LocalBookkeeperEnsemble(org.apache.pulsar.zookeeper.LocalBookkeeperEnsemble) ServiceConfigurationUtils(org.apache.pulsar.broker.ServiceConfigurationUtils) AuthenticationProviderTls(org.apache.pulsar.broker.authentication.AuthenticationProviderTls) PulsarAuthorizationProvider(org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider) ClientBuilder(org.apache.pulsar.client.api.ClientBuilder) Optional(java.util.Optional) SimpleLoadManagerImpl(org.apache.pulsar.broker.loadbalance.impl.SimpleLoadManagerImpl) PublisherStats(org.apache.pulsar.common.policies.data.PublisherStats) Utils(org.apache.pulsar.common.functions.Utils) DataProvider(org.testng.annotations.DataProvider) TopicStats(org.apache.pulsar.common.policies.data.TopicStats) Assert.assertEquals(org.testng.Assert.assertEquals) HashMap(java.util.HashMap) PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) Message(org.apache.pulsar.client.api.Message) Mockito.spy(org.mockito.Mockito.spy) HashSet(java.util.HashSet) AuthenticationTls(org.apache.pulsar.client.impl.auth.AuthenticationTls) Lists(com.google.common.collect.Lists) NarClassLoaderBuilder(org.apache.pulsar.common.nar.NarClassLoaderBuilder) ThreadRuntimeFactory(org.apache.pulsar.functions.runtime.thread.ThreadRuntimeFactory) Assert(org.testng.Assert) SchemaDefinition(org.apache.pulsar.client.api.schema.SchemaDefinition) PulsarClient(org.apache.pulsar.client.api.PulsarClient) TenantInfo(org.apache.pulsar.common.policies.data.TenantInfo) AfterClass(org.testng.annotations.AfterClass) SourceConfig(org.apache.pulsar.common.io.SourceConfig) Logger(org.slf4j.Logger) MalformedURLException(java.net.MalformedURLException) Files(java.nio.file.Files) JAVA_INSTANCE_JAR_PROPERTY(org.apache.pulsar.functions.utils.functioncache.FunctionCacheEntry.JAVA_INSTANCE_JAR_PROPERTY) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) Assert.fail(org.testng.Assert.fail) ConsumerConfig(org.apache.pulsar.common.functions.ConsumerConfig) SinkConfig(org.apache.pulsar.common.io.SinkConfig) IOException(java.io.IOException) PulsarService(org.apache.pulsar.broker.PulsarService) File(java.io.File) Schema(org.apache.pulsar.client.api.Schema) TimeUnit(java.util.concurrent.TimeUnit) GenericRecord(org.apache.pulsar.client.api.schema.GenericRecord) FunctionCommon(org.apache.pulsar.functions.utils.FunctionCommon) SinkContext(org.apache.pulsar.io.core.SinkContext) Authentication(org.apache.pulsar.client.api.Authentication) Assert.assertTrue(org.testng.Assert.assertTrue) ConsumerStats(org.apache.pulsar.common.policies.data.ConsumerStats) BrokerStats(org.apache.pulsar.client.admin.BrokerStats) Collections(java.util.Collections) LocalRunner(org.apache.pulsar.functions.LocalRunner) SubscriptionStats(org.apache.pulsar.common.policies.data.SubscriptionStats) HashMap(java.util.HashMap) ConsumerStats(org.apache.pulsar.common.policies.data.ConsumerStats) Cleanup(lombok.Cleanup) AuthenticationTls(org.apache.pulsar.client.impl.auth.AuthenticationTls) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) TopicStats(org.apache.pulsar.common.policies.data.TopicStats)

Example 3 with Sink

use of org.apache.pulsar.io.core.Sink in project pulsar by yahoo.

the class JavaInstanceRunnable method setupOutput.

private void setupOutput(ContextImpl contextImpl) throws Exception {
    SinkSpec sinkSpec = this.instanceConfig.getFunctionDetails().getSink();
    Object object;
    // If sink classname is not set, we default pulsar sink
    if (sinkSpec.getClassName().isEmpty()) {
        if (StringUtils.isEmpty(sinkSpec.getTopic())) {
            object = PulsarSinkDisable.INSTANCE;
        } else {
            PulsarSinkConfig pulsarSinkConfig = new PulsarSinkConfig();
            pulsarSinkConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.valueOf(this.instanceConfig.getFunctionDetails().getProcessingGuarantees().name()));
            pulsarSinkConfig.setTopic(sinkSpec.getTopic());
            pulsarSinkConfig.setForwardSourceMessageProperty(this.instanceConfig.getFunctionDetails().getSink().getForwardSourceMessageProperty());
            if (!StringUtils.isEmpty(sinkSpec.getSchemaType())) {
                pulsarSinkConfig.setSchemaType(sinkSpec.getSchemaType());
            } else if (!StringUtils.isEmpty(sinkSpec.getSerDeClassName())) {
                pulsarSinkConfig.setSerdeClassName(sinkSpec.getSerDeClassName());
            }
            pulsarSinkConfig.setTypeClassName(sinkSpec.getTypeClassName());
            pulsarSinkConfig.setSchemaProperties(sinkSpec.getSchemaPropertiesMap());
            if (this.instanceConfig.getFunctionDetails().getSink().getProducerSpec() != null) {
                org.apache.pulsar.functions.proto.Function.ProducerSpec conf = this.instanceConfig.getFunctionDetails().getSink().getProducerSpec();
                ProducerConfig.ProducerConfigBuilder builder = ProducerConfig.builder().maxPendingMessages(conf.getMaxPendingMessages()).maxPendingMessagesAcrossPartitions(conf.getMaxPendingMessagesAcrossPartitions()).batchBuilder(conf.getBatchBuilder()).useThreadLocalProducers(conf.getUseThreadLocalProducers()).cryptoConfig(CryptoUtils.convertFromSpec(conf.getCryptoSpec()));
                pulsarSinkConfig.setProducerConfig(builder.build());
            }
            object = new PulsarSink(this.client, pulsarSinkConfig, this.properties, this.stats, this.functionClassLoader);
        }
    } else {
        object = Reflections.createInstance(sinkSpec.getClassName(), this.functionClassLoader);
    }
    if (object instanceof Sink) {
        this.sink = (Sink) object;
    } else {
        throw new RuntimeException("Sink does not implement correct interface");
    }
    if (componentType == org.apache.pulsar.functions.proto.Function.FunctionDetails.ComponentType.SINK) {
        Thread.currentThread().setContextClassLoader(this.functionClassLoader);
    }
    try {
        if (sinkSpec.getConfigs().isEmpty()) {
            if (log.isDebugEnabled()) {
                log.debug("Opening Sink with empty hashmap with contextImpl: {} ", contextImpl.toString());
            }
            this.sink.open(new HashMap<>(), contextImpl);
        } else {
            if (log.isDebugEnabled()) {
                log.debug("Opening Sink with SinkSpec {} and contextImpl: {} ", sinkSpec, contextImpl.toString());
            }
            this.sink.open(ObjectMapperFactory.getThreadLocal().readValue(sinkSpec.getConfigs(), new TypeReference<Map<String, Object>>() {
            }), contextImpl);
        }
    } catch (Exception e) {
        log.error("Sink open produced uncaught exception: ", e);
        throw e;
    } finally {
        Thread.currentThread().setContextClassLoader(this.instanceClassLoader);
    }
}
Also used : PulsarSinkConfig(org.apache.pulsar.functions.sink.PulsarSinkConfig) PulsarSink(org.apache.pulsar.functions.sink.PulsarSink) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) IOException(java.io.IOException) Function(org.apache.pulsar.functions.api.Function) Sink(org.apache.pulsar.io.core.Sink) PulsarSink(org.apache.pulsar.functions.sink.PulsarSink) ProducerConfig(org.apache.pulsar.common.functions.ProducerConfig) TypeReference(com.fasterxml.jackson.core.type.TypeReference) SinkSpec(org.apache.pulsar.functions.proto.Function.SinkSpec)

Example 4 with Sink

use of org.apache.pulsar.io.core.Sink in project incubator-pulsar by apache.

the class PulsarFunctionLocalRunTest method testE2EPulsarFunctionLocalRun.

/**
 * Validates pulsar sink e2e functionality on functions.
 *
 * @throws Exception
 */
private void testE2EPulsarFunctionLocalRun(String jarFilePathUrl, int parallelism) throws Exception {
    final String namespacePortion = "io";
    final String replNamespace = tenant + "/" + namespacePortion;
    final String sourceTopic = "persistent://" + replNamespace + "/my-topic1";
    final String sinkTopic = "persistent://" + replNamespace + "/output";
    final String propertyKey = "key";
    final String propertyValue = "value";
    final String functionName = "PulsarFunction-test";
    final String subscriptionName = "test-sub";
    admin.namespaces().createNamespace(replNamespace);
    Set<String> clusters = Sets.newHashSet(Lists.newArrayList(CLUSTER));
    admin.namespaces().setNamespaceReplicationClusters(replNamespace, clusters);
    // create a producer that creates a topic at broker
    Producer<String> producer = pulsarClient.newProducer(Schema.STRING).topic(sourceTopic).create();
    Consumer<String> consumer = pulsarClient.newConsumer(Schema.STRING).topic(sinkTopic).subscriptionName("sub").subscribe();
    FunctionConfig functionConfig = createFunctionConfig(tenant, namespacePortion, functionName, sourceTopic, sinkTopic, subscriptionName);
    functionConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE);
    functionConfig.setJar(jarFilePathUrl);
    functionConfig.setParallelism(parallelism);
    int metricsPort = FunctionCommon.findAvailablePort();
    @Cleanup LocalRunner localRunner = LocalRunner.builder().functionConfig(functionConfig).clientAuthPlugin(AuthenticationTls.class.getName()).clientAuthParams(String.format("tlsCertFile:%s,tlsKeyFile:%s", TLS_CLIENT_CERT_FILE_PATH, TLS_CLIENT_KEY_FILE_PATH)).useTls(true).tlsTrustCertFilePath(TLS_TRUST_CERT_FILE_PATH).tlsAllowInsecureConnection(true).tlsHostNameVerificationEnabled(false).metricsPortStart(metricsPort).brokerServiceUrl(pulsar.getBrokerServiceUrlTls()).build();
    localRunner.start(false);
    Assert.assertTrue(retryStrategically((test) -> {
        try {
            boolean result = false;
            TopicStats topicStats = admin.topics().getStats(sourceTopic);
            if (topicStats.getSubscriptions().containsKey(subscriptionName) && topicStats.getSubscriptions().get(subscriptionName).getConsumers().size() == parallelism) {
                for (ConsumerStats consumerStats : topicStats.getSubscriptions().get(subscriptionName).getConsumers()) {
                    result = consumerStats.getAvailablePermits() == 1000 && consumerStats.getMetadata() != null && consumerStats.getMetadata().containsKey("id") && consumerStats.getMetadata().get("id").equals(String.format("%s/%s/%s", tenant, namespacePortion, functionName));
                }
            }
            return result;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 50, 150));
    // validate pulsar sink consumer has started on the topic
    TopicStats stats = admin.topics().getStats(sourceTopic);
    assertTrue(stats.getSubscriptions().get(subscriptionName) != null && !stats.getSubscriptions().get(subscriptionName).getConsumers().isEmpty());
    int totalMsgs = 5;
    for (int i = 0; i < totalMsgs; i++) {
        String data = "my-message-" + i;
        producer.newMessage().property(propertyKey, propertyValue).value(data).send();
    }
    retryStrategically((test) -> {
        try {
            SubscriptionStats subStats = admin.topics().getStats(sourceTopic).getSubscriptions().get(subscriptionName);
            return subStats.getUnackedMessages() == 0;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 50, 150);
    for (int i = 0; i < totalMsgs; i++) {
        Message<String> msg = consumer.receive(5, TimeUnit.SECONDS);
        String receivedPropertyValue = msg.getProperty(propertyKey);
        assertEquals(propertyValue, receivedPropertyValue);
        assertEquals(msg.getValue(), "my-message-" + i + "!");
    }
    // validate pulsar-sink consumer has consumed all messages and delivered to Pulsar sink but unacked messages
    // due to publish failure
    assertNotEquals(admin.topics().getStats(sourceTopic).getSubscriptions().values().iterator().next().getUnackedMessages(), totalMsgs);
    // validate prometheus metrics
    String prometheusMetrics = PulsarFunctionTestUtils.getPrometheusMetrics(metricsPort);
    log.info("prometheus metrics: {}", prometheusMetrics);
    Map<String, PulsarFunctionTestUtils.Metric> metricsMap = new HashMap<>();
    Arrays.asList(prometheusMetrics.split("\n")).forEach(line -> {
        if (line.startsWith("pulsar_function_processed_successfully_total")) {
            Map<String, PulsarFunctionTestUtils.Metric> metrics = PulsarFunctionTestUtils.parseMetrics(line);
            assertFalse(metrics.isEmpty());
            PulsarFunctionTestUtils.Metric m = metrics.get("pulsar_function_processed_successfully_total");
            if (m != null) {
                metricsMap.put(m.tags.get("instance_id"), m);
            }
        }
    });
    Assert.assertEquals(metricsMap.size(), parallelism);
    double totalMsgRecv = 0.0;
    for (int i = 0; i < parallelism; i++) {
        PulsarFunctionTestUtils.Metric m = metricsMap.get(String.valueOf(i));
        Assert.assertNotNull(m);
        assertEquals(m.tags.get("cluster"), config.getClusterName());
        assertEquals(m.tags.get("instance_id"), String.valueOf(i));
        assertEquals(m.tags.get("name"), functionName);
        assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
        assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
        totalMsgRecv += m.value;
    }
    Assert.assertEquals(totalMsgRecv, totalMsgs);
    // stop functions
    localRunner.stop();
    retryStrategically((test) -> {
        try {
            TopicStats topicStats = admin.topics().getStats(sourceTopic);
            return topicStats.getSubscriptions().get(subscriptionName) != null && topicStats.getSubscriptions().get(subscriptionName).getConsumers().isEmpty();
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 20, 150);
    TopicStats topicStats = admin.topics().getStats(sourceTopic);
    assertTrue(topicStats.getSubscriptions().get(subscriptionName) != null && topicStats.getSubscriptions().get(subscriptionName).getConsumers().isEmpty());
    retryStrategically((test) -> {
        try {
            return (admin.topics().getStats(sinkTopic).getPublishers().size() == 0);
        } catch (PulsarAdminException e) {
            if (e.getStatusCode() == 404) {
                return true;
            }
            return false;
        }
    }, 10, 150);
    try {
        assertEquals(admin.topics().getStats(sinkTopic).getPublishers().size(), 0);
    } catch (PulsarAdminException e) {
        if (e.getStatusCode() != 404) {
            fail();
        }
    }
}
Also used : FunctionConfig(org.apache.pulsar.common.functions.FunctionConfig) LocalRunner(org.apache.pulsar.functions.LocalRunner) SubscriptionStats(org.apache.pulsar.common.policies.data.SubscriptionStats) Arrays(java.util.Arrays) URL(java.net.URL) ObjectMapperFactory(org.apache.pulsar.common.util.ObjectMapperFactory) Producer(org.apache.pulsar.client.api.Producer) LoggerFactory(org.slf4j.LoggerFactory) Cleanup(lombok.Cleanup) Test(org.testng.annotations.Test) ClusterData(org.apache.pulsar.common.policies.data.ClusterData) Sink(org.apache.pulsar.io.core.Sink) AfterMethod(org.testng.annotations.AfterMethod) ByteBuffer(java.nio.ByteBuffer) URLClassLoader(java.net.URLClassLoader) NarClassLoader(org.apache.pulsar.common.nar.NarClassLoader) Map(java.util.Map) MockedPulsarServiceBaseTest.retryStrategically(org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest.retryStrategically) FunctionConfig(org.apache.pulsar.common.functions.FunctionConfig) ThreadRuntimeFactoryConfig(org.apache.pulsar.functions.runtime.thread.ThreadRuntimeFactoryConfig) Assert.assertFalse(org.testng.Assert.assertFalse) Method(java.lang.reflect.Method) Record(org.apache.pulsar.functions.api.Record) Assert.assertNotEquals(org.testng.Assert.assertNotEquals) BeforeClass(org.testng.annotations.BeforeClass) BeforeMethod(org.testng.annotations.BeforeMethod) Set(java.util.Set) Sets(com.google.common.collect.Sets) Objects(java.util.Objects) Consumer(org.apache.pulsar.client.api.Consumer) FutureUtil(org.apache.pulsar.common.util.FutureUtil) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) LocalBookkeeperEnsemble(org.apache.pulsar.zookeeper.LocalBookkeeperEnsemble) ServiceConfigurationUtils(org.apache.pulsar.broker.ServiceConfigurationUtils) AuthenticationProviderTls(org.apache.pulsar.broker.authentication.AuthenticationProviderTls) PulsarAuthorizationProvider(org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider) ClientBuilder(org.apache.pulsar.client.api.ClientBuilder) Optional(java.util.Optional) SimpleLoadManagerImpl(org.apache.pulsar.broker.loadbalance.impl.SimpleLoadManagerImpl) PublisherStats(org.apache.pulsar.common.policies.data.PublisherStats) Utils(org.apache.pulsar.common.functions.Utils) DataProvider(org.testng.annotations.DataProvider) TopicStats(org.apache.pulsar.common.policies.data.TopicStats) Assert.assertEquals(org.testng.Assert.assertEquals) HashMap(java.util.HashMap) PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) Message(org.apache.pulsar.client.api.Message) Mockito.spy(org.mockito.Mockito.spy) HashSet(java.util.HashSet) AuthenticationTls(org.apache.pulsar.client.impl.auth.AuthenticationTls) Lists(com.google.common.collect.Lists) NarClassLoaderBuilder(org.apache.pulsar.common.nar.NarClassLoaderBuilder) ThreadRuntimeFactory(org.apache.pulsar.functions.runtime.thread.ThreadRuntimeFactory) Assert(org.testng.Assert) SchemaDefinition(org.apache.pulsar.client.api.schema.SchemaDefinition) PulsarClient(org.apache.pulsar.client.api.PulsarClient) TenantInfo(org.apache.pulsar.common.policies.data.TenantInfo) AfterClass(org.testng.annotations.AfterClass) SourceConfig(org.apache.pulsar.common.io.SourceConfig) Logger(org.slf4j.Logger) MalformedURLException(java.net.MalformedURLException) Files(java.nio.file.Files) JAVA_INSTANCE_JAR_PROPERTY(org.apache.pulsar.functions.utils.functioncache.FunctionCacheEntry.JAVA_INSTANCE_JAR_PROPERTY) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) Assert.fail(org.testng.Assert.fail) ConsumerConfig(org.apache.pulsar.common.functions.ConsumerConfig) SinkConfig(org.apache.pulsar.common.io.SinkConfig) IOException(java.io.IOException) PulsarService(org.apache.pulsar.broker.PulsarService) File(java.io.File) Schema(org.apache.pulsar.client.api.Schema) TimeUnit(java.util.concurrent.TimeUnit) GenericRecord(org.apache.pulsar.client.api.schema.GenericRecord) FunctionCommon(org.apache.pulsar.functions.utils.FunctionCommon) SinkContext(org.apache.pulsar.io.core.SinkContext) Authentication(org.apache.pulsar.client.api.Authentication) Assert.assertTrue(org.testng.Assert.assertTrue) ConsumerStats(org.apache.pulsar.common.policies.data.ConsumerStats) BrokerStats(org.apache.pulsar.client.admin.BrokerStats) Collections(java.util.Collections) LocalRunner(org.apache.pulsar.functions.LocalRunner) SubscriptionStats(org.apache.pulsar.common.policies.data.SubscriptionStats) HashMap(java.util.HashMap) ConsumerStats(org.apache.pulsar.common.policies.data.ConsumerStats) Cleanup(lombok.Cleanup) AuthenticationTls(org.apache.pulsar.client.impl.auth.AuthenticationTls) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) TopicStats(org.apache.pulsar.common.policies.data.TopicStats)

Example 5 with Sink

use of org.apache.pulsar.io.core.Sink in project incubator-pulsar by apache.

the class PulsarFunctionLocalRunTest method testPulsarSinkLocalRun.

private void testPulsarSinkLocalRun(String jarFilePathUrl, int parallelism, String className) throws Exception {
    final String namespacePortion = "io";
    final String replNamespace = tenant + "/" + namespacePortion;
    final String sourceTopic = "persistent://" + replNamespace + "/input";
    final String sinkName = "PulsarSink-test";
    final String propertyKey = "key";
    final String propertyValue = "value";
    final String subscriptionName = "test-sub";
    admin.namespaces().createNamespace(replNamespace);
    Set<String> clusters = Sets.newHashSet(Lists.newArrayList("local"));
    admin.namespaces().setNamespaceReplicationClusters(replNamespace, clusters);
    // create a producer that creates a topic at broker
    Producer<String> producer = pulsarClient.newProducer(Schema.STRING).topic(sourceTopic).create();
    SinkConfig sinkConfig = createSinkConfig(tenant, namespacePortion, sinkName, sourceTopic, subscriptionName);
    sinkConfig.setInputSpecs(Collections.singletonMap(sourceTopic, ConsumerConfig.builder().receiverQueueSize(1000).build()));
    if (className != null) {
        sinkConfig.setClassName(className);
    } else if (jarFilePathUrl == null || !jarFilePathUrl.endsWith(".nar")) {
        sinkConfig.setClassName("org.apache.pulsar.io.datagenerator.DataGeneratorPrintSink");
    }
    sinkConfig.setArchive(jarFilePathUrl);
    sinkConfig.setParallelism(parallelism);
    int metricsPort = FunctionCommon.findAvailablePort();
    @Cleanup LocalRunner localRunner = LocalRunner.builder().sinkConfig(sinkConfig).clientAuthPlugin(AuthenticationTls.class.getName()).clientAuthParams(String.format("tlsCertFile:%s,tlsKeyFile:%s", TLS_CLIENT_CERT_FILE_PATH, TLS_CLIENT_KEY_FILE_PATH)).useTls(true).tlsTrustCertFilePath(TLS_TRUST_CERT_FILE_PATH).tlsAllowInsecureConnection(true).tlsHostNameVerificationEnabled(false).brokerServiceUrl(pulsar.getBrokerServiceUrlTls()).connectorsDirectory(workerConfig.getConnectorsDirectory()).metricsPortStart(metricsPort).build();
    localRunner.start(false);
    Assert.assertTrue(retryStrategically((test) -> {
        try {
            boolean result = false;
            TopicStats topicStats = admin.topics().getStats(sourceTopic);
            if (topicStats.getSubscriptions().containsKey(subscriptionName) && topicStats.getSubscriptions().get(subscriptionName).getConsumers().size() == parallelism) {
                for (ConsumerStats consumerStats : topicStats.getSubscriptions().get(subscriptionName).getConsumers()) {
                    result = consumerStats.getAvailablePermits() == 1000;
                }
            }
            return result;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 20, 150));
    int totalMsgs = 10;
    for (int i = 0; i < totalMsgs; i++) {
        String data = "my-message-" + i;
        producer.newMessage().property(propertyKey, propertyValue).value(data).send();
    }
    Assert.assertTrue(retryStrategically((test) -> {
        try {
            SubscriptionStats subStats = admin.topics().getStats(sourceTopic).getSubscriptions().get(subscriptionName);
            return subStats.getUnackedMessages() == 0 && subStats.getMsgThroughputOut() == totalMsgs;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 5, 200));
    // validate prometheus metrics
    String prometheusMetrics = PulsarFunctionTestUtils.getPrometheusMetrics(metricsPort);
    log.info("prometheus metrics: {}", prometheusMetrics);
    Map<String, PulsarFunctionTestUtils.Metric> metricsMap = new HashMap<>();
    Arrays.asList(prometheusMetrics.split("\n")).forEach(line -> {
        if (line.startsWith("pulsar_sink_written_total")) {
            Map<String, PulsarFunctionTestUtils.Metric> metrics = PulsarFunctionTestUtils.parseMetrics(line);
            assertFalse(metrics.isEmpty());
            PulsarFunctionTestUtils.Metric m = metrics.get("pulsar_sink_written_total");
            if (m != null) {
                metricsMap.put(m.tags.get("instance_id"), m);
            }
        } else if (line.startsWith("pulsar_sink_sink_exceptions_total")) {
            Map<String, PulsarFunctionTestUtils.Metric> metrics = PulsarFunctionTestUtils.parseMetrics(line);
            assertFalse(metrics.isEmpty());
            PulsarFunctionTestUtils.Metric m = metrics.get("pulsar_sink_sink_exceptions_total");
            if (m == null) {
                m = metrics.get("pulsar_sink_sink_exceptions_total_1min");
            }
            assertEquals(m.value, 0);
        }
    });
    Assert.assertEquals(metricsMap.size(), parallelism);
    double totalNumRecvMsg = 0;
    for (int i = 0; i < parallelism; i++) {
        PulsarFunctionTestUtils.Metric m = metricsMap.get(String.valueOf(i));
        Assert.assertNotNull(m);
        assertEquals(m.tags.get("cluster"), config.getClusterName());
        assertEquals(m.tags.get("instance_id"), String.valueOf(i));
        assertEquals(m.tags.get("name"), sinkName);
        assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
        assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, sinkName));
        totalNumRecvMsg += m.value;
    }
    assertEquals(totalNumRecvMsg, totalMsgs);
    // stop sink
    localRunner.stop();
    Assert.assertTrue(retryStrategically((test) -> {
        try {
            TopicStats stats = admin.topics().getStats(sourceTopic);
            return stats.getSubscriptions().get(subscriptionName) != null && stats.getSubscriptions().get(subscriptionName).getConsumers().isEmpty();
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 20, 150));
    TopicStats topicStats = admin.topics().getStats(sourceTopic);
    assertTrue(topicStats.getSubscriptions().get(subscriptionName) != null && topicStats.getSubscriptions().get(subscriptionName).getConsumers().isEmpty());
}
Also used : LocalRunner(org.apache.pulsar.functions.LocalRunner) SubscriptionStats(org.apache.pulsar.common.policies.data.SubscriptionStats) Arrays(java.util.Arrays) URL(java.net.URL) ObjectMapperFactory(org.apache.pulsar.common.util.ObjectMapperFactory) Producer(org.apache.pulsar.client.api.Producer) LoggerFactory(org.slf4j.LoggerFactory) Cleanup(lombok.Cleanup) Test(org.testng.annotations.Test) ClusterData(org.apache.pulsar.common.policies.data.ClusterData) Sink(org.apache.pulsar.io.core.Sink) AfterMethod(org.testng.annotations.AfterMethod) ByteBuffer(java.nio.ByteBuffer) URLClassLoader(java.net.URLClassLoader) NarClassLoader(org.apache.pulsar.common.nar.NarClassLoader) Map(java.util.Map) MockedPulsarServiceBaseTest.retryStrategically(org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest.retryStrategically) FunctionConfig(org.apache.pulsar.common.functions.FunctionConfig) ThreadRuntimeFactoryConfig(org.apache.pulsar.functions.runtime.thread.ThreadRuntimeFactoryConfig) Assert.assertFalse(org.testng.Assert.assertFalse) Method(java.lang.reflect.Method) Record(org.apache.pulsar.functions.api.Record) Assert.assertNotEquals(org.testng.Assert.assertNotEquals) BeforeClass(org.testng.annotations.BeforeClass) BeforeMethod(org.testng.annotations.BeforeMethod) Set(java.util.Set) Sets(com.google.common.collect.Sets) Objects(java.util.Objects) Consumer(org.apache.pulsar.client.api.Consumer) FutureUtil(org.apache.pulsar.common.util.FutureUtil) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) LocalBookkeeperEnsemble(org.apache.pulsar.zookeeper.LocalBookkeeperEnsemble) ServiceConfigurationUtils(org.apache.pulsar.broker.ServiceConfigurationUtils) AuthenticationProviderTls(org.apache.pulsar.broker.authentication.AuthenticationProviderTls) PulsarAuthorizationProvider(org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider) ClientBuilder(org.apache.pulsar.client.api.ClientBuilder) Optional(java.util.Optional) SimpleLoadManagerImpl(org.apache.pulsar.broker.loadbalance.impl.SimpleLoadManagerImpl) PublisherStats(org.apache.pulsar.common.policies.data.PublisherStats) Utils(org.apache.pulsar.common.functions.Utils) DataProvider(org.testng.annotations.DataProvider) TopicStats(org.apache.pulsar.common.policies.data.TopicStats) Assert.assertEquals(org.testng.Assert.assertEquals) HashMap(java.util.HashMap) PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) Message(org.apache.pulsar.client.api.Message) Mockito.spy(org.mockito.Mockito.spy) HashSet(java.util.HashSet) AuthenticationTls(org.apache.pulsar.client.impl.auth.AuthenticationTls) Lists(com.google.common.collect.Lists) NarClassLoaderBuilder(org.apache.pulsar.common.nar.NarClassLoaderBuilder) ThreadRuntimeFactory(org.apache.pulsar.functions.runtime.thread.ThreadRuntimeFactory) Assert(org.testng.Assert) SchemaDefinition(org.apache.pulsar.client.api.schema.SchemaDefinition) PulsarClient(org.apache.pulsar.client.api.PulsarClient) TenantInfo(org.apache.pulsar.common.policies.data.TenantInfo) AfterClass(org.testng.annotations.AfterClass) SourceConfig(org.apache.pulsar.common.io.SourceConfig) Logger(org.slf4j.Logger) MalformedURLException(java.net.MalformedURLException) Files(java.nio.file.Files) JAVA_INSTANCE_JAR_PROPERTY(org.apache.pulsar.functions.utils.functioncache.FunctionCacheEntry.JAVA_INSTANCE_JAR_PROPERTY) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) Assert.fail(org.testng.Assert.fail) ConsumerConfig(org.apache.pulsar.common.functions.ConsumerConfig) SinkConfig(org.apache.pulsar.common.io.SinkConfig) IOException(java.io.IOException) PulsarService(org.apache.pulsar.broker.PulsarService) File(java.io.File) Schema(org.apache.pulsar.client.api.Schema) TimeUnit(java.util.concurrent.TimeUnit) GenericRecord(org.apache.pulsar.client.api.schema.GenericRecord) FunctionCommon(org.apache.pulsar.functions.utils.FunctionCommon) SinkContext(org.apache.pulsar.io.core.SinkContext) Authentication(org.apache.pulsar.client.api.Authentication) Assert.assertTrue(org.testng.Assert.assertTrue) ConsumerStats(org.apache.pulsar.common.policies.data.ConsumerStats) BrokerStats(org.apache.pulsar.client.admin.BrokerStats) Collections(java.util.Collections) LocalRunner(org.apache.pulsar.functions.LocalRunner) SubscriptionStats(org.apache.pulsar.common.policies.data.SubscriptionStats) HashMap(java.util.HashMap) ConsumerStats(org.apache.pulsar.common.policies.data.ConsumerStats) Cleanup(lombok.Cleanup) SinkConfig(org.apache.pulsar.common.io.SinkConfig) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) Map(java.util.Map) HashMap(java.util.HashMap) TopicStats(org.apache.pulsar.common.policies.data.TopicStats)

Aggregations

IOException (java.io.IOException)9 Sink (org.apache.pulsar.io.core.Sink)9 Lists (com.google.common.collect.Lists)6 Sets (com.google.common.collect.Sets)6 File (java.io.File)6 Method (java.lang.reflect.Method)6 MalformedURLException (java.net.MalformedURLException)6 URL (java.net.URL)6 URLClassLoader (java.net.URLClassLoader)6 ByteBuffer (java.nio.ByteBuffer)6 Files (java.nio.file.Files)6 Arrays (java.util.Arrays)6 Collections (java.util.Collections)6 HashMap (java.util.HashMap)6 HashSet (java.util.HashSet)6 Map (java.util.Map)6 Objects (java.util.Objects)6 Optional (java.util.Optional)6 Set (java.util.Set)6 TimeUnit (java.util.concurrent.TimeUnit)6