Search in sources :

Example 6 with Sink

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

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 7 with Sink

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

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)

Example 8 with Sink

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

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.toString(), 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 9 with Sink

use of org.apache.pulsar.io.core.Sink in project 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