Skip to content

Add reactive docs #250

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 12, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions spring-pulsar-docs/src/main/asciidoc/application-properties.adoc
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[appendix]
[[application-properties]]
[[appendix.application-properties]]
= Application Properties
include::attributes.adoc[]

You can specify various properties inside your `application.properties` file, inside your `application.yml` file, or as command line switches.
This appendix provides a list of Spring Pulsar properties and references to the underlying classes that consume them.

TIP: Spring Boot provides various conversion mechanisms with advanced value formatting. See <<features#features.external-config.typesafe-configuration-properties.conversion, the properties conversion section>> for more detail.
TIP: Spring Boot provides various conversion mechanisms with advanced value formatting.
See {spring-boot-docs}/#features.external-config.typesafe-configuration-properties.conversion[the properties conversion section] for more detail.

NOTE: Property contributions can come from additional jar files on your classpath, so this list is not exhaustive.
Also, you can define your own properties.

include::application-properties/pulsar-client.adoc[]

@@ -17,3 +17,9 @@ include::application-properties/pulsar-producer.adoc[]
include::application-properties/pulsar-consumer.adoc[]

include::application-properties/pulsar-administration.adoc[]

include::application-properties/pulsar-reactive-sender.adoc[]

include::application-properties/pulsar-reactive-consumer.adoc[]

include::application-properties/pulsar-reactive-reader.adoc[]
10 changes: 10 additions & 0 deletions spring-pulsar-docs/src/main/asciidoc/attributes.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
:toc: left
:toclevels: 6
:numbered:
:icons: font
:hide-uri-scheme:
:sectnums:
:sectnumlevels: 3

:github: https://github.com/spring-projects-experimental/spring-pulsar
:spring-boot-docs: https://docs.spring.io/spring-boot/docs/3.0.0/reference/htmlsingle
1 change: 1 addition & 0 deletions spring-pulsar-docs/src/main/asciidoc/authors.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Soby Chacko; Chris Bono; Alexander Preuß; Jay Bryant; Christophe Bornet
3 changes: 3 additions & 0 deletions spring-pulsar-docs/src/main/asciidoc/copyright.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(C) 2022 VMware, Inc.

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
51 changes: 21 additions & 30 deletions spring-pulsar-docs/src/main/asciidoc/index.adoc
Original file line number Diff line number Diff line change
@@ -1,50 +1,41 @@
[[spring-pulsar-reference]]
= Spring for Apache Pulsar
:toc: left
:toclevels: 4
:numbered:
:icons: font
:hide-uri-scheme:
Soby Chacko; Chris Bono; Alexander Preuß; Jay Bryant; Christophe Bornet

//ifdef::backend-html5[]
//*{project-version}*
//
//NOTE: This documentation is also available as https://docs.spring.io/spring-pulsar/docs/{project-version}/reference/pdf/spring-pulsar-reference.pdf[PDF].
//endif::[]
//
//ifdef::backend-pdf[]
//NOTE: This documentation is also available as https://docs.spring.io/spring-pulsar/docs/{project-version}/reference/html/index.html[HTML].
//endif::[]
include::attributes.adoc[]

(C) 2022 VMware, Inc.
include::authors.adoc[]

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
include::copyright.adoc[]

== Preface

include::preface.adoc[]

[[quick-intro]]
== Introduction

This first part of the reference documentation is a high-level quick tour of Spring for Apache Pulsar.

include::quick-tour.adoc[]
include::intro.adoc[leveloffset=+1]

[[reference]]
== Reference

This part of the reference documentation goes through the details of the various components in Spring for Apache Pulsar.

include::pulsar.adoc[]

[[resources]]
include::reactive-pulsar.adoc[leveloffset=+2]

include::pulsar-admin.adoc[leveloffset=+2]

include::observability.adoc[leveloffset=+2]

:sectnums!:
[[other-resources]]
== Other Resources

In addition to this reference documentation, we recommend a number of other resources that may help you learn about Spring and Apache Pulsar.

- {github}[Spring for Apache Pulsar GitHub Repository]
- https://pulsar.apache.org/[Apache Pulsar Project Home Page]
- https://pulsar.apache.org/docs/client-libraries-java/[Apache Pulsar Java Client]
- https://github.com/spring-projects-experimental/spring-pulsar[Spring for Apache Pulsar GitHub Repository]
- https://github.com/apache/pulsar[Apache Pulsar GitHub Repository]
- https://github.com/apache/pulsar-client-reactive[Apache Pulsar Reactive Client GitHub Repository]

[[appendix]]
== Appendices

include::application-properties.adoc[leveloffset=+2]

include::non-ga-versions.adoc[leveloffset=+2]
41 changes: 41 additions & 0 deletions spring-pulsar-docs/src/main/asciidoc/intro.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
= Introduction
This project provides a basic Spring-friendly API for developing https://pulsar.apache.org/[Apache Pulsar] applications.

On a very high level, Spring for Apache Pulsar provides a `PulsarTemplate` for publishing to a Pulsar topic and a `PulsarListener` annotation for consuming from a Pulsar topic.
In addition, it also provides various convenience APIs for Spring developers to ramp up their development journey into Apache Pulsar.

== Minimum Supported Versions

The minimum supported versions for the underlying libraries required by the framework are as follows:
|===
| Library | Version

| Java
| 17

| Apache Pulsar
| 2.10.0

| Spring Boot
| 3.0.0

| Spring Framework
| 6.0.0

| Gradle
| 7.5
|===

== Building the Project
If you have cloned the project locally, follow these steps to build the project from the soure code.

Spring for Apache Pulsar uses Gradle as its build tool. Run the following command to do a full build of the project:
[indent=0]
----
./gradlew clean build
----
You can build without running tests by using the following command:
[indent=0]
----
./gradlew clean build -x test
----
57 changes: 57 additions & 0 deletions spring-pulsar-docs/src/main/asciidoc/non-ga-versions.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
[appendix]
[[appendix.non-ga-versions]]
= Non-GA Versions

include::attributes.adoc[]

You can find snapshot or milestone versions of the dependencies in the following repositories:

[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>apache-snapshots</id>
<name>Apache Snapshots</name>
<url>https://repository.apache.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
----

[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
repositories {
maven {
name = 'spring-milestones'
url = 'https://repo.spring.io/milestone'
}
maven {
name = 'spring-snapshots'
url = 'https://repo.spring.io/snapshot'
}
maven {
name = 'apache-snapshot'
url = 'https://repository.apache.org/content/repositories/snapshots'
}
}
----
96 changes: 96 additions & 0 deletions spring-pulsar-docs/src/main/asciidoc/observability.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
[[micrometer]]
= Observability

:github: https://github.com/spring-projects-experimental/spring-pulsar

Spring for Apache Pulsar includes a way to manage observability through https://micrometer.io/[Micrometer].

NOTE: Observability has not been added to the Reactive components yet


[[observation]]
== Micrometer Observations
The `PulsarTemplate` and `PulsarListener` are instrumented with the Micrometer observations API.
When a Micrometer `ObservationRegistry` bean is provided, send and receive operations are traced and timed.

=== Custom tags
The default implementation adds the `bean.name` tag for template observations and `listener.id` tag for listener observations.
To add other tags to timers and traces, configure a custom `PulsarTemplateObservationConvention` or `PulsarListenerObservationConvention` to the template or listener container, respectively.

TIP: You can subclass either `DefaultPulsarTemplateObservationConvention` or `DefaultPulsarListenerObservationConvention` or provide completely new implementations.

include::observation/_metrics.adoc[]

include::observation/_spans.adoc[]

See https://micrometer.io/docs/tracing[Micrometer Tracing] for more information.

=== Manual Configuration without Spring Boot
If you do not use Spring Boot, you need to configure and provide an `ObservationRegistry` as well as Micrometer Tracing. See https://micrometer.io/docs/tracing[Micrometer Tracing] for more information.

=== Auto-Configuration with Spring Boot
If you use Spring Boot, the Spring Boot Actuator auto-configures an instance of `ObservationRegistry` for you.
If `micrometer-core` is on the classpath, every stopped observation leads to a timer.

Spring Boot also auto-configures Micrometer Tracing for you. This includes support for Brave OpenTelemetry, Zipkin, and Wavefront. When using the Micrometer Observation API, finishing observations leads to spans reported to Zipkin or Wavefront. You can control tracing by setting properties under `management.tracing`. You can use Zipkin with `management.zipkin.tracing`, while Wavefront uses `management.wavefront`.

==== Example Configuration
The following example shows the steps to configure your Spring Boot application to use Zipkin with Brave.

. Add the required dependencies to your application (in Maven or Gradle, respectively):
+
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-urlconnection</artifactId>
</dependency>
</dependencies>
----
+
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-tracing-bridge-brave'
implementation 'io.zipkin.reporter2:zipkin-reporter-brave'
implementation 'io.zipkin.reporter2:zipkin-sender-urlconnection'
}
----
+
NOTE
====
You need the `'io.zipkin.reporter2:zipkin-sender-urlconnection'` dependency only if your application does not have a configured WebClient or RestTemplate.
====
. Add the required properties to your application:
+
[source,yaml,indent=0,subs="verbatim"]
----
management:
tracing.enabled: true
zipkin:
tracing.endpoint: "http://localhost:9411/api/v2/spans"
----
+
The `tracing.endpoint` above expects Zipkin is running locally as described https://zipkin.io/pages/quickstart.html[here].

At this point, your application should record traces when you send and receive Pulsar messages. You should be able to view them in the Zipkin UI (at http://localhost:9411, when running locally).

TIP: You can also see the preceding configuration on the link:{github}/blob/main/spring-pulsar-sample-apps/README.adoc[Spring Pulsar Sample Apps].

The steps are very similar to configuring any of the other supported Tracing environments.
4 changes: 0 additions & 4 deletions spring-pulsar-docs/src/main/asciidoc/preface.adoc

This file was deleted.

43 changes: 43 additions & 0 deletions spring-pulsar-docs/src/main/asciidoc/pulsar-admin.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[[pulsar-admin]]
= Pulsar Administration

:javadocs: https://docs.spring.io/spring-pulsar/docs/current-SNAPSHOT/api

== Pulsar Admin Client
On the Pulsar administration side, Spring Boot auto-configuration provides a `PulsarAdministration` to manage Pulsar clusters.
The administration implements an interface called `PulsarAdminOperations` and provides {javadocs}/org/springframework/pulsar/core/PulsarAdminOperations.html[a `createOrModify` method] to handle topic administration through its contract.

When you use the Pulsar Spring Boot starter, you get the `PulsarAdministration` auto-configured.
By default, the application tries to connect to a local Pulsar instance at `http://localhost:8080`.
However, there are many application properties available to help you configure the client.
See the <<application-properties.adoc#appendix.application-properties.pulsar-administration,Appendix>> for application properties prefixed with `spring.pulsar.administration`.

[[pulsar-admin-authentication]]
=== Authentication
When accessing a Pulsar cluster that requires authentication, the admin client requires the same security configuration as the regular Pulsar client.
You can use the aforementioned <<pulsar.adoc#client-authentication,security configuration>> by replacing `spring.pulsar.client` with `spring.pulsar.administration`.

[[pulsar-auto-topic-creation]]
== Automatic Topic Creation

On initialization, the `PulsarAdministration` checks if there are any `PulsarTopic` beans in the application context.
For all such beans, the `PulsarAdministration` either creates the corresponding topic or, if necessary, modifies the number of partitions.

The following example shows how to add `PulsarTopic` beans to let the `PulsarAdministration` auto-create topics for you:

====
[source,java]
----
@Bean
PulsarTopic simpleTopic {
// This will create a non-partitioned topic in the public/default namespace
return PulsarTopic.builder("simple-topic").build();
}
@Bean
PulsarTopic partitionedTopic {
// This will create a partitioned topic with 3 partitions in the provided tenant and namespace
return PulsarTopic.builder("persistent://my-tenant/my-namespace/partitioned-topic", 3).build();
}
----
====
146 changes: 12 additions & 134 deletions spring-pulsar-docs/src/main/asciidoc/pulsar.adoc
Original file line number Diff line number Diff line change
@@ -4,14 +4,14 @@
:javadocs: https://docs.spring.io/spring-pulsar/docs/current-SNAPSHOT/api
:github: https://github.com/spring-projects-experimental/spring-pulsar

This section offers detailed explanations of the various concerns that impact using Spring for Apache Pulsar.
For a quick but less detailed introduction, see <<index.adoc#quick-intro>>.
include::quick-tour.adoc[leveloffset=+3]

[[pulsar-client]]
==== Pulsar Client

When you use the Pulsar Spring Boot Starter, you get the `PulsarClient` auto-configured.
This is done through a factory bean called `PulsarClientFactoryBean`, which takes a configuration object called `PulsarClientConfiguration`. By default, the application tries to connect to a local Pulsar instance at `pulsar://localhost:6650`. However, there are many application properties available to configure the client. See the <<application-properties.adoc#appendix.application-properties.pulsar-client,Appendix>> for more detail.
This is done through a factory bean called `PulsarClientFactoryBean`, which takes a configuration object called `PulsarClientConfiguration`. By default, the application tries to connect to a local Pulsar instance at `pulsar://localhost:6650`. However, there are many application properties available to configure the client.
See the <<application-properties.adoc#appendix.application-properties.pulsar-client,Appendix>> for more detail.

[[client-authentication]]
===== Authentication
@@ -101,13 +101,15 @@ See the <<application-properties.adoc#appendix.application-properties.pulsar-pro

[[pulsar-producer-factory]]
==== Pulsar Producer Factory
The `PulsarTemplate` relies on a `PulsarProducerFactory` to actually create the underlying producer. Spring Boot auto-configuration also provides this producer factory. Additionally, you can configure the factory by specifying any of the available producer-centric application properties. See the <<application-properties.adoc#appendix.application-properties.pulsar-producer,Appendix>>.
The `PulsarTemplate` relies on a `PulsarProducerFactory` to actually create the underlying producer. Spring Boot auto-configuration also provides this producer factory. Additionally, you can configure the factory by specifying any of the available producer-centric application properties.
See the <<application-properties.adoc#appendix.application-properties.pulsar-producer,Appendix>>.

[[producer-caching]]
==== Pulsar Producer Caching
Each underlying Pulsar producer consumes resources. To improve performance and avoid continual creation of producers, the producer factory caches the producers that it creates. They are cached in an LRU fashion and evicted when they have not been used within a configured time period. The link:{github}/blob/8e33ac0b122bc0e75df299919c956cacabcc9809/spring-pulsar/src/main/java/org/springframework/pulsar/core/CachingPulsarProducerFactory.java#L159[cache key] is composed of just enough information to ensure that callers are returned the same producer on subsequent creation requests.

Additionally, you can configure the cache settings by specifying any of the `spring.producer.cache` prefixed application properties. See the <<application-properties.adoc#appendix.application-properties.pulsar-producer,Appendix>>.
Additionally, you can configure the cache settings by specifying any of the `spring.pulsar.producer.cache` prefixed application properties.
See the <<application-properties.adoc#appendix.application-properties.pulsar-producer,Appendix>>.


[[pulsar-listener]]
@@ -118,7 +120,8 @@ To use `PulsarListener`, you need to use the `@EnablePulsar` annotation.
When you use Spring Boot support, it automatically enables this annotation and configures all the components necessary for `PulsarListener`, such as the message listener infrastructure (which is responsible for creating the Pulsar consumer).
`PulsarMessageListenerContainer` uses a `PulsarConsumerFactory` to create and manage the Pulsar consumer.

This consumer factory is also auto-configured through Spring Boot. See the <<application-properties.adoc#appendix.application-properties.pulsar-consumer,Appendix>> for Pulsar consumer properties.
This consumer factory is also auto-configured through Spring Boot.
See the <<application-properties.adoc#appendix.application-properties.pulsar-consumer,Appendix>> for Pulsar consumer properties.

Let us revisit the `PulsarListener` code snippet we saw in the quick-tour section:

@@ -287,7 +290,7 @@ void listen(String message) {
----
====

Note that the properties used are direct Pulsar consumer properties.
TIP: The properties used are direct Pulsar consumer properties, not the `spring.pulsar.consumer` application configuration properties

[[pulsar-message-listener-container]]
==== Pulsar Message Listener Container
@@ -579,7 +582,8 @@ When calling `acknowledge()`, you need not receive the payload with the `Message
You can also call a different variant of `acknowledge` by providing the message ID: `acknowledge.acknowledge(message.getMessageId());`
When you use `acknowledge(messageId)`, you must receive the payload by using the `Message<?>` envelope.

Similar to what is possible for acknowledging, the `Acknowledgment` API also provides options for negatively acknowledging. See the nack methods shown earlier.
Similar to what is possible for acknowledging, the `Acknowledgment` API also provides options for negatively acknowledging.
See the nack methods shown earlier.

You can also call `acknowledge` directly on the Pulsar consumer:

@@ -1223,40 +1227,6 @@ ProducerInterceptor secondInterceptor() {
----
====

[[pulsar-admin]]
==== Pulsar Admin
On the Pulsar administration side, Spring Boot auto-configuration provides a `PulsarAdministration` to manage Pulsar clusters.
The administration implements an interface called `PulsarAdminOperations` and provides {javadocs}/org/springframework/pulsar/core/PulsarAdminOperations.html[a `createOrModify` method] to handle topic administration through its contract.

When you use the Pulsar Spring Boot starter, you get the `PulsarAdministration` auto-configured.
By default, the application tries to connect to a local Pulsar instance at `http://localhost:8080`. However, there are many application properties available to help you configure the client. See the <<application-properties.adoc#appendix.application-properties.pulsar-administration,Appendix>> for more detail.

===== Authentication
When accessing a Pulsar cluster that requires authentication, the admin client requires the same security configuration as the regular Pulsar client. You can use the aforementioned <<client-authentication,security configuration>> by replacing `spring.pulsar.client` with `spring.pulsar.administration`.

==== Automatic Topic creation
On initialization, the `PulsarAdministration` checks if there are any `PulsarTopic` beans in the application context.
For all such beans, the `PulsarAdministration` either creates the corresponding topic or, if necessary, modifies the number of partitions.

The following example shows how to add `PulsarTopic` beans to let the `PulsarAdministration` auto-create topics for you:

====
[source,java]
----
@Bean
PulsarTopic simpleTopic {
// This will create a non-partitioned topic in the public/default namespace
return PulsarTopic.builder("simple-topic").build();
}
@Bean
PulsarTopic partitionedTopic {
// This will create a partitioned topic with 3 partitions in the provided tenant and namespace
return PulsarTopic.builder("persistent://my-tenant/my-namespace/partitioned-topic", 3).build();
}
----
====

[[pulsar-headers]]
==== Pulsar Headers

@@ -1314,95 +1284,3 @@ When extracting the various headers, we do so as a `List<>` as well.
Spring Pulsar ensures that the headers list corresponds to the data list.

You can also extract headers in the same manner when you use the batch listener and receive payloads as `List<org.apache.pulsar.client.api.Message<?>`, `org.apache.pulsar.client.api.Messages<?>`, or `org.springframework.messaging.Messsge<?>`.

[[micrometer]]
=== Observability

Spring for Apache Pulsar includes a way to manage observability through https://micrometer.io/[Micrometer].

[[observation]]
==== Micrometer Observations
The `PulsarTemplate` and `PulsarListener` are instrumented with the Micrometer observations API.
When a Micrometer `ObservationRegistry` bean is provided, send and receive operations are traced and timed.

===== Custom tags
The default implementation adds the `bean.name` tag for template observations and `listener.id` tag for listener observations.
To add other tags to timers and traces, configure a custom `PulsarTemplateObservationConvention` or `PulsarListenerObservationConvention` to the template or listener container, respectively.

TIP: You can subclass either `DefaultPulsarTemplateObservationConvention` or `DefaultPulsarListenerObservationConvention` or provide completely new implementations.

include::observation/_metrics.adoc[leveloffset=+2]

include::observation/_spans.adoc[leveloffset=+2]

See https://micrometer.io/docs/tracing[Micrometer Tracing] for more information.

===== Manual Configuration without Spring Boot
If you do not use Spring Boot, you need to configure and provide an `ObservationRegistry` as well as Micrometer Tracing. See https://micrometer.io/docs/tracing[Micrometer Tracing] for more information.

===== Auto-Configuration with Spring Boot
If you use Spring Boot, the Spring Boot Actuator auto-configures an instance of `ObservationRegistry` for you.
If `micrometer-core` is on the classpath, every stopped observation leads to a timer.

Spring Boot also auto-configures Micrometer Tracing for you. This includes support for Brave OpenTelemetry, Zipkin, and Wavefront. When using the Micrometer Observation API, finishing observations leads to spans reported to Zipkin or Wavefront. You can control tracing by setting properties under `management.tracing`. You can use Zipkin with `management.zipkin.tracing`, while Wavefront uses `management.wavefront`.

====== Example Configuration
The following example shows the steps to configure your Spring Boot application to use Zipkin with Brave.

. Add the required dependencies to your application (in Maven or Gradle, respectively):
+
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-urlconnection</artifactId>
</dependency>
</dependencies>
----
+
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-tracing-bridge-brave'
implementation 'io.zipkin.reporter2:zipkin-reporter-brave'
implementation 'io.zipkin.reporter2:zipkin-sender-urlconnection'
}
----
+
NOTE
====
You need the `'io.zipkin.reporter2:zipkin-sender-urlconnection'` dependency only if your application does not have a configured WebClient or RestTemplate.
====
. Add the required properties to your application:
+
[source,yaml,indent=0,subs="verbatim"]
----
management:
tracing.enabled: true
zipkin:
tracing.endpoint: "http://localhost:9411/api/v2/spans"
----
+
The `tracing.endpoint` above expects Zipkin is running locally as described https://zipkin.io/pages/quickstart.html[here].

At this point, your application should record traces when you send and receive Pulsar messages. You should be able to view them in the Zipkin UI (at http://localhost:9411, when running locally).

TIP: You can also see the preceding configuration on the link:{github}/blob/main/spring-pulsar-sample-apps/README.adoc[Spring Pulsar Sample Apps].

The steps are very similar to configuring any of the other supported Tracing environments.
91 changes: 7 additions & 84 deletions spring-pulsar-docs/src/main/asciidoc/quick-tour.adoc
Original file line number Diff line number Diff line change
@@ -1,40 +1,14 @@
[[quick-tour]]
=== Quick Tour
= Quick Tour

:spring-pulsar-version: 0.1.0-SNAPSHOT

In this section, we take a quick tour of Spring for Apache Pulsar.

==== Minimum Supported Versions

The minimum supported versions for the underlying libraries required by the framework are as follows:
|===
| Library | Version

| Java
| 17

| Apache Pulsar
| 2.10.0

| Spring Boot
| 3.0.0

| Spring Framework
| 6.0.0

| Gradle
| 7.x (7.5 or later)
|===

=== Quick Sample

In the following sample Spring Boot application, we show how to write a publisher and a consumer that use Spring for Apache Pulsar.
We will take a quick tour of Spring for Apache Pulsar by showing a sample Spring Boot application that produces and consumes.
This is a complete application and does not require any additional configuration, as long as you have a Pulsar cluster running on the default location - `localhost:6650`.

NOTE: We recommend using a Spring-Boot-First approach for Spring for Apache Pulsar-based application, as that simplifies things tremendously. To do so, you can add the `spring-pulsar-spring-boot-starter` module as a dependency.

==== Dependencies
== Dependencies

Spring Boot applications need only the `spring-pulsar-spring-boot-starter` dependency. The following listings show how to define the dependency for Maven and Gradle, respectively:

@@ -58,44 +32,8 @@ dependencies {
}
----

===== Non-GA Versions
You can find snapshot or milestone versions of the dependency in the Spring Artifactory repository. The following listings show how to define the repositories for Maven and Gradle, respectively:

[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
<repositories>
...
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
----

[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
repositories {
...
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://repo.spring.io/snapshot' }
}
----

==== Application Code
== Application Code

The following listing shows the Spring Boot application case for the example:

@@ -110,18 +48,18 @@ public class PulsarBootHelloWorld {
@Bean
ApplicationRunner runner(PulsarTemplate<String> pulsarTemplate) {
return (args) -> pulsarTemplate.send("hello-pulsar", "Hello Pulsar World!");
return (args) -> pulsarTemplate.send("hello-pulsar-topic", "Hello Pulsar World!");
}
@PulsarListener(subscriptionName = "hello-pulsar-subscription", topics = "hello-pulsar")
@PulsarListener(subscriptionName = "hello-pulsar-sub", topics = "hello-pulsar-topic")
void listen(String message) {
System.out.println("Message Received: " + message);
}
}
----

Let us quickly go through the higher-level details of this application.
<<index.adoc#reference,Later in this documentation>>, we see these components in much more detail.
Later in the documentation we see these components in much more detail.

In the preceding sample, we heavily rely on Spring Boot auto-configuration.
Spring Boot auto-configures several components for our application.
@@ -137,18 +75,3 @@ Behind the scenes, it creates a message listener container to create and manage
As with a regular Pulsar consumer, the default subscription type when using `PulsarListener` is the `Exclusive` mode.
As records are published in to the `hello-pulsar` topic, the `Pulsarlistener` consumes them and prints them on the console.
The framework also infers the schema type used from the data type that the `PulsarListner` method uses as the payload -- `String`, in this case.


=== Building the Project
If you have cloned the project locally, follow these steps to build the project from the soure code.

Spring for Apache Pulsar uses Gradle as its build tool. Run the following command to do a full build of the project:
[indent=0]
----
./gradlew clean build
----
You can build without running tests by using the following command:
[indent=0]
----
./gradlew clean build -x test
----
504 changes: 504 additions & 0 deletions spring-pulsar-docs/src/main/asciidoc/reactive-pulsar.adoc

Large diffs are not rendered by default.

65 changes: 65 additions & 0 deletions spring-pulsar-docs/src/main/asciidoc/reactive-quick-tour.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
[[quick-tour-reactive]]
= Quick Tour

:spring-pulsar-version: 0.1.0-SNAPSHOT

We will take a quick tour of the Reactive support in Spring for Apache Pulsar by showing a sample Spring Boot application that produces and consumes in a Reactive fashion.
This is a complete application and does not require any additional configuration, as long as you have a Pulsar cluster running on the default location - `localhost:6650`.

NOTE: We recommend using a Spring-Boot-First approach for Spring for Apache Pulsar-based applications, as that simplifies things tremendously. To do so, you can add the `spring-pulsar-reactive-spring-boot-starter` module as a dependency.

== Dependencies

Spring Boot applications need only the `spring-pulsar-reactive-spring-boot-starter` dependency. The following listings show how to define the dependency for Maven and Gradle, respectively:

[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
<dependencies>
<dependency>
<groupId>org.springframework.pulsar</groupId>
<artifactId>spring-pulsar-reactive-spring-boot-starter</artifactId>
<version>{spring-pulsar-version}</version>
</dependency>
</dependencies>
----
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
dependencies {
implementation 'org.springframework.pulsar:spring-pulsar-reactive-spring-boot-starter:{spring-pulsar-version}'
}
----

== Application Code

Here is the application source code:

[source,java,indent=0,pending-extract=true,subs="verbatim"]
----
@SpringBootApplication
public class ReactiveSpringPulsarHelloWorld {
public static void main(String[] args) {
SpringApplication.run(ReactiveSpringPulsarHelloWorld.class, args);
}
@Bean
ApplicationRunner runner(ReactivePulsarTemplate<String> pulsarTemplate) {
return (args) -> pulsarTemplate.send("hello-pulsar-topic", "Hello Reactive Pulsar World!").subscribe();
}
@ReactivePulsarListener(subscriptionName = "hello-pulsar-sub", topics = "hello-pulsar-topic")
Mono<Void> listen(String message) {
System.out.println("Reactive listener received: " + message);
return Mono.empty();
}
}
----

That is it, with just a few lines of code we have a working Spring Boot app that is producing and consuming messages from a Pulsar topic in a Reactive fashion.

Once started, the application uses a `ReactivePulsarTemplate` to send messages to the `hello-pulsar-topic`.
It then consumes from the `hello-pulsar-topic` using a `@ReactivePulsarListener`.

NOTE: One of the key ingredients to the simplicity is the Spring Boot starter which auto-configures and provides the required components to the application
2 changes: 1 addition & 1 deletion spring-pulsar-sample-apps/sample-app1/build.gradle
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ plugins {
description = 'Spring Pulsar Sample Application (Send and Receive)'

dependencies {
api project(':spring-pulsar-spring-boot-starter')
implementation project(':spring-pulsar-spring-boot-starter')
implementation 'com.google.code.findbugs:jsr305'

// observability
2 changes: 1 addition & 1 deletion spring-pulsar-sample-apps/sample-app2/build.gradle
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ plugins {
description = 'Spring Pulsar Sample Applications (Custom Routing)'

dependencies {
api project(':spring-pulsar-spring-boot-starter')
implementation project(':spring-pulsar-spring-boot-starter')
implementation 'com.google.code.findbugs:jsr305'

// observability
2 changes: 1 addition & 1 deletion spring-pulsar-sample-apps/sample-reactive/build.gradle
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ plugins {
description = 'Reactive Spring Pulsar Sample Application'

dependencies {
api project(':spring-pulsar-reactive-spring-boot-starter')
implementation project(':spring-pulsar-reactive-spring-boot-starter')
implementation 'com.google.code.findbugs:jsr305'
}