Add docs for Pulsar headers (#157)
Resolves #153 - Also temporarily disable broken observation tests
This commit is contained in:
@@ -172,7 +172,7 @@ Here is another `PulsarListener` method, that takes an `Integer`.
|
||||
[source, java]
|
||||
----
|
||||
@PulsarListener(subscriptionName = "my-subscription-1", topics = "my-topic-1")
|
||||
public void listen2(Integer message) {
|
||||
public void listen(Integer message) {
|
||||
System.out.println(message);
|
||||
}
|
||||
----
|
||||
@@ -184,7 +184,7 @@ The following `PulsarListener` method shows how we can consume complex types fro
|
||||
[source, java]
|
||||
----
|
||||
@PulsarListener(subscriptionName = "my-subscription-2", topics = "my-topic-2", schemaType = SchemaType.JSON)
|
||||
public void listen3(Foo message) {
|
||||
public void listen(Foo message) {
|
||||
System.out.println(message);
|
||||
}
|
||||
----
|
||||
@@ -193,13 +193,40 @@ public void listen3(Foo message) {
|
||||
Note the addition of a `schemaType` property on `PulsarListener`.
|
||||
That is because the library is not capable of inferring the schema type from the provided type `Foo`, we must tell the framework what schema to use.
|
||||
|
||||
Here is an example of using `PulsarListener` to consume records in batches.
|
||||
Let us look at a few more ways.
|
||||
|
||||
You can consume the Pulsar message directly as shown below:
|
||||
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
@PulsarListener(subscriptionName = "my-subscription", topics = "my-topic")
|
||||
public void listen(org.apache.pulsar.client.api.Message<String> message) {
|
||||
System.out.println(message.getValue());
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
If you want to consume the record using the Spring messaging envelope, you can do it like this:
|
||||
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
@PulsarListener(subscriptionName = "my-subscription", topics = "my-topic")
|
||||
public void listen(org.springframework.messaging.Message<String> message) {
|
||||
System.out.println(message.getPayload());
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
Now let's see how we can consume records in batches.
|
||||
Here is an example of using `PulsarListener` to consume records in batches as POJO's.
|
||||
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
@PulsarListener(subscriptionName = "hello-batch-subscription", topics = "hello-batch", schemaType = SchemaType.JSON, batch = true)
|
||||
public void listen4(List<Foo> messages) {
|
||||
public void listen(List<Foo> messages) {
|
||||
System.out.println("records received :" + messages.size());
|
||||
messages.forEach((message) -> System.out.println("record : " + message));
|
||||
}
|
||||
@@ -218,13 +245,40 @@ The following also should work in which we use the `Message` envelope provided b
|
||||
[source, java]
|
||||
----
|
||||
@PulsarListener(subscriptionName = "hello-batch-subscription", topics = "hello-batch", schemaType = SchemaType.JSON, batch = true)
|
||||
public void listen4(List<Message<Foo>> messages) {
|
||||
public void listen(List<Message<Foo>> messages) {
|
||||
System.out.println("records received :" + messages.size());
|
||||
messages.forEach((message) -> System.out.println("record : " + message));
|
||||
messages.forEach((message) -> System.out.println("record : " + message.getValue()));
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
Here is another example of consuming batch records with the envelope of Spring messaging Message type.
|
||||
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
@PulsarListener(subscriptionName = "hello-batch-subscription", topics = "hello-batch", schemaType = SchemaType.JSON, batch = true)
|
||||
public void listen(List<org.springframework.messaging.Message<Foo>> messages) {
|
||||
System.out.println("records received :" + messages.size());
|
||||
messages.forEach((message) -> System.out.println("record : " + message.getPayload()));
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
And finally, let us also see how the `Messages` holder object from Pulsar can be used for the batch listener.
|
||||
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
@PulsarListener(subscriptionName = "hello-batch-subscription", topics = "hello-batch", schemaType = SchemaType.JSON, batch = true)
|
||||
public void listen(org.apache.pulsar.client.api.Messages<Foo>> messages) {
|
||||
System.out.println("records received :" + messages.size());
|
||||
messages.forEach((message) -> System.out.println("record : " + message.getValue()));
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
When using `PulsarListener`, you can provide Pulsar consumer properties directly on the annotation itself.
|
||||
This is convenient, if you do not want to use the Boot configuration properties mentioned above or have multiple `PulsarListener` methods.
|
||||
|
||||
@@ -1222,6 +1276,64 @@ PulsarTopic partitionedTopic {
|
||||
----
|
||||
====
|
||||
|
||||
[[pulsar-headers]]
|
||||
==== Pulsar Headers
|
||||
|
||||
In this section, we will see how we can use the Pulsar message metadata as Pulsar headers in a Spring application.
|
||||
First, let's examine all the available Pulsar headers from the message metadata.
|
||||
|
||||
.[.underline]#Aailable **Pulsar Message Metadata as Spring Headers**#
|
||||
[%collapsible]
|
||||
====
|
||||
https://github.com/spring-projects-experimental/spring-pulsar/blob/main/spring-pulsar/src/main/java/org/springframework/pulsar/support/PulsarHeaders.java[Click here] to see the available Pulsar headers.
|
||||
====
|
||||
|
||||
===== Accessing Pulsar Headers in Single Record based Consumer
|
||||
|
||||
Here is an example of how you can access the various Pulsar Headers in an application that is using single record mode of consuming.
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@PulsarListener(topics = "simpleListenerWithHeaders")
|
||||
void simpleListenerWithHeaders(String data, @Header(PulsarHeaders.MESSAGE_ID) MessageId messageId,
|
||||
@Header(PulsarHeaders.RAW_DATA) byte[] rawData,
|
||||
@Header("foo") String foo) {
|
||||
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
In the above example we are accessing the values for the messageId and rawData message metadata as well as a custom message property named "foo".
|
||||
The Spring @Header annotation is used for each header field.
|
||||
|
||||
You can also use, Pulsar's `Message` as the envelope to carry the payload.
|
||||
When doing so, the user can directly call the corresponding methods on the Pulsar Message for retrieving the metadata.
|
||||
However, as a convenience, you can also retrieve it using the `Header` annotation.
|
||||
Note that you can also use the Spring messaging `Message` envelope to carry the payload and then retrieve the Pulsar headers using `@Header`.
|
||||
|
||||
===== Accessing Pulsar Headers in Batch Record based Consumer
|
||||
|
||||
In this section we will see how one can access the various Pulsar Headers in an application that is using a batch consumer.
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@PulsarListener(topics = "simpleBatchListenerWithHeaders", batch = true)
|
||||
void simpleBatchListenerWithHeaders(List<String> data,
|
||||
@Header(PulsarHeaders.MESSAGE_ID) List<MessageId> messageIds,
|
||||
@Header(PulsarHeaders.TOPIC_NAME) List<String> topicNames, @Header("foo") List<String> fooValues) {
|
||||
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
In the above example, we are consuming the data as `List<String>`.
|
||||
When extracting the various headers, we do as as `List<>` as well.
|
||||
Spring Pulsar will ensure that the headers list corresponds to the data list.
|
||||
|
||||
Headers can also be extracted in the same manner when receiving payload as `List<org.apache.pulsar.client.api.Message<?>`, or `org.apache.pulsar.client.api.Messages<?>` or `org.springframework.messaging.Messsge<?>` when using the batch listener.
|
||||
|
||||
[[micrometer]]
|
||||
=== Observability
|
||||
|
||||
|
||||
@@ -34,82 +34,82 @@ public abstract class PulsarHeaders {
|
||||
public static final String PULSAR_MESSAGE = PREFIX + "message_";
|
||||
|
||||
/**
|
||||
* Prefix for the unique message id.
|
||||
* Unique message id.
|
||||
*/
|
||||
public static final String MESSAGE_ID = PULSAR_MESSAGE + "id";
|
||||
|
||||
/**
|
||||
* Prefix for the raw message data.
|
||||
* Raw message data as bytes.
|
||||
*/
|
||||
public static final String RAW_DATA = PULSAR_MESSAGE + "raw_data";
|
||||
|
||||
/**
|
||||
* Prefix for message size.
|
||||
* Message size in bytes.
|
||||
*/
|
||||
public static final String MESSAGE_SIZE = PULSAR_MESSAGE + "size";
|
||||
|
||||
/**
|
||||
* Prefix for message publish time.
|
||||
* Message publish time (long).
|
||||
*/
|
||||
public static final String PUBLISH_TIME = PULSAR_MESSAGE + "publish_time";
|
||||
|
||||
/**
|
||||
* Prefix for event time.
|
||||
* Event time (long).
|
||||
*/
|
||||
public static final String EVENT_TIME = PULSAR_MESSAGE + "event_time";
|
||||
|
||||
/**
|
||||
* Prefix for message sequence id.
|
||||
* Message sequence id.
|
||||
*/
|
||||
public static final String SEQUENCE_ID = PULSAR_MESSAGE + "sequence_id";
|
||||
|
||||
/**
|
||||
* prefix for the producer name.
|
||||
* Producer name.
|
||||
*/
|
||||
public static final String PRODUCER_NAME = PULSAR_MESSAGE + "producer_name";
|
||||
|
||||
/**
|
||||
* Prefix for the message key.
|
||||
* Message key if present.
|
||||
*/
|
||||
public static final String KEY = PULSAR_MESSAGE + "key";
|
||||
|
||||
/**
|
||||
* Prefix for the message key as bytes.
|
||||
* Message key as bytes if present.
|
||||
*/
|
||||
public static final String KEY_BYTES = PULSAR_MESSAGE + "key_bytes";
|
||||
|
||||
/**
|
||||
* Prefix for the order key.
|
||||
* Message ordering key.
|
||||
*/
|
||||
public static final String ORDERING_KEY = PULSAR_MESSAGE + "ordering_key";
|
||||
|
||||
/**
|
||||
* Prefix for the topic name.
|
||||
* Topic name.
|
||||
*/
|
||||
public static final String TOPIC_NAME = PULSAR_MESSAGE + "topic_name";
|
||||
|
||||
/**
|
||||
* Prefix for redelivery count.
|
||||
* Redelivery count.
|
||||
*/
|
||||
public static final String REDELIVERY_COUNT = PULSAR_MESSAGE + "redelivery_count";
|
||||
|
||||
/**
|
||||
* Prefix for schema version.
|
||||
* Schema version.
|
||||
*/
|
||||
public static final String SCHEMA_VERSION = PULSAR_MESSAGE + "schema_version";
|
||||
|
||||
/**
|
||||
* Prefix for the cluster replicated from.
|
||||
* Cluster where the message is replicated from.
|
||||
*/
|
||||
public static final String REPLICATED_FROM = PULSAR_MESSAGE + "replicated_from";
|
||||
|
||||
/**
|
||||
* Prefix for broker publish time.
|
||||
* Broker publish time (long).
|
||||
*/
|
||||
public static final String BROKER_PUBLISH_TIME = PULSAR_MESSAGE + "broker_publish_time";
|
||||
|
||||
/**
|
||||
* Prefix for index.
|
||||
* Message index if available.
|
||||
*/
|
||||
public static final String INDEX = PULSAR_MESSAGE + "index";
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import org.apache.pulsar.client.admin.PulsarAdmin;
|
||||
import org.apache.pulsar.client.api.PulsarClient;
|
||||
import org.apache.pulsar.client.api.PulsarClientException;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -62,6 +63,7 @@ import io.micrometer.tracing.test.simple.SpansAssert;
|
||||
* @author Chris Bono
|
||||
* @see SampleTestRunner
|
||||
*/
|
||||
@Disabled
|
||||
public class ObservationIntegrationTests extends SampleTestRunner implements PulsarTestContainerSupport {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.apache.pulsar.client.admin.PulsarAdmin;
|
||||
import org.apache.pulsar.client.api.Message;
|
||||
import org.apache.pulsar.client.api.PulsarClient;
|
||||
import org.apache.pulsar.client.api.PulsarClientException;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -83,6 +84,7 @@ import io.micrometer.tracing.test.simple.SimpleTracer;
|
||||
*/
|
||||
@SpringJUnitConfig
|
||||
@DirtiesContext
|
||||
@Disabled
|
||||
public class ObservationTests implements PulsarTestContainerSupport {
|
||||
|
||||
private static final String LISTENER_ID_TAG = "spring.pulsar.listener.id";
|
||||
|
||||
Reference in New Issue
Block a user