Skip to content

Commit

Permalink
Bundle Javadoc with Antora documentation site.
Browse files Browse the repository at this point in the history
Closes #2950
  • Loading branch information
mp911de committed Jul 31, 2024
1 parent 87ef15c commit 0b2344b
Show file tree
Hide file tree
Showing 20 changed files with 95 additions and 83 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,5 @@ work
build/
node_modules
node
package.json
package-lock.json
.mvn/.gradle-enterprise
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"dependencies": {
"antora": "3.2.0-alpha.6",
"@antora/atlas-extension": "1.0.0-alpha.2",
"@antora/collector-extension": "1.0.0-alpha.7",
"@asciidoctor/tabs": "1.0.0-beta.6",
"@springio/antora-extensions": "1.13.0",
"@springio/asciidoctor-extensions": "1.0.0-alpha.11"
}
}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@
<build>
<plugins>
<plugin>
<groupId>io.spring.maven.antora</groupId>
<groupId>org.antora</groupId>
<artifactId>antora-maven-plugin</artifactId>
</plugin>
</plugins>
Expand Down
8 changes: 3 additions & 5 deletions src/main/antora/antora-playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
# The purpose of this Antora playbook is to build the docs in the current branch.
antora:
extensions:
- '@antora/collector-extension'
- require: '@springio/antora-extensions/root-component-extension'
- require: '@springio/antora-extensions'
root_component_name: 'data-redis'
site:
title: Spring Data Redis
Expand All @@ -22,13 +21,12 @@ content:
start_path: src/main/antora
asciidoc:
attributes:
page-pagination: ''
hide-uri-scheme: '@'
tabs-sync-option: '@'
chomp: 'all'
extensions:
- '@asciidoctor/tabs'
- '@springio/asciidoctor-extensions'
- '@springio/asciidoctor-extensions/javadoc-extension'
sourcemap: true
urls:
latest_version_segment: ''
Expand All @@ -38,5 +36,5 @@ runtime:
format: pretty
ui:
bundle:
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.3.5/ui-bundle.zip
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.16/ui-bundle.zip
snapshot: true
5 changes: 5 additions & 0 deletions src/main/antora/antora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ ext:
local: true
scan:
dir: target/classes/
- run:
command: ./mvnw package -Pdistribute
local: true
scan:
dir: target/antora
4 changes: 3 additions & 1 deletion src/main/antora/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@
* xref:appendix.adoc[]
* https://github.com/spring-projects/spring-data-commons/wiki[Wiki]
* xref:attachment$api/java/index.html[Javadoc,role=link-external,window=_blank]
* https://github.com/spring-projects/spring-data-commons/wiki[Wiki,role=link-external,window=_blank]
10 changes: 5 additions & 5 deletions src/main/antora/modules/ROOT/pages/redis/connection-modes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Each mode of operation requires specific configuration that is explained in the

The easiest way to get started is by using Redis Standalone with a single Redis server,

Configure `LettuceClientConfiguration` or `JedisConnectionFactory`, as shown in the following example:
Configure javadoc:org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory[] or javadoc:org.springframework.data.redis.connection.jedis.JedisConnectionFactory[], as shown in the following example:

[source,java]
----
Expand Down Expand Up @@ -60,12 +60,12 @@ class WriteToMasterReadFromReplicaConfiguration {
}
----

TIP: For environments reporting non-public addresses through the `INFO` command (for example, when using AWS), use `RedisStaticMasterReplicaConfiguration` instead of `RedisStandaloneConfiguration`. Please note that `RedisStaticMasterReplicaConfiguration` does not support Pub/Sub because of missing Pub/Sub message propagation across individual servers.
TIP: For environments reporting non-public addresses through the `INFO` command (for example, when using AWS), use javadoc:org.springframework.data.redis.connection.RedisStaticMasterReplicaConfiguration[] instead of javadoc:org.springframework.data.redis.connection.RedisStandaloneConfiguration[]. Please note that `RedisStaticMasterReplicaConfiguration` does not support Pub/Sub because of missing Pub/Sub message propagation across individual servers.

[[redis:sentinel]]
== Redis Sentinel

For dealing with high-availability Redis, Spring Data Redis has support for https://redis.io/topics/sentinel[Redis Sentinel], using `RedisSentinelConfiguration`, as shown in the following example:
For dealing with high-availability Redis, Spring Data Redis has support for https://redis.io/topics/sentinel[Redis Sentinel], using javadoc:org.springframework.data.redis.connection.RedisSentinelConfiguration[], as shown in the following example:

[source,java]
----
Expand Down Expand Up @@ -110,8 +110,8 @@ Sometimes, direct interaction with one of the Sentinels is required. Using `Redi
[[cluster.enable]]
== Redis Cluster

xref:redis/cluster.adoc[Cluster support] is based on the same building blocks as non-clustered communication. `RedisClusterConnection`, an extension to `RedisConnection`, handles the communication with the Redis Cluster and translates errors into the Spring DAO exception hierarchy.
`RedisClusterConnection` instances are created with the `RedisConnectionFactory`, which has to be set up with the associated `RedisClusterConfiguration`, as shown in the following example:
xref:redis/cluster.adoc[Cluster support] is based on the same building blocks as non-clustered communication. javadoc:org.springframework.data.redis.connection.RedisClusterConnection[], an extension to `RedisConnection`, handles the communication with the Redis Cluster and translates errors into the Spring DAO exception hierarchy.
`RedisClusterConnection` instances are created with the `RedisConnectionFactory`, which has to be set up with the associated javadoc:org.springframework.data.redis.connection.RedisClusterConfiguration[], as shown in the following example:

.Sample RedisConnectionFactory Configuration for Redis Cluster
====
Expand Down
2 changes: 1 addition & 1 deletion src/main/antora/modules/ROOT/pages/redis/drivers.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public LettuceConnectionFactory lettuceConnectionFactory() {
}
----

For more detailed client configuration tweaks, see https://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/connection/lettuce/LettuceClientConfiguration.html[`LettuceClientConfiguration`].
For more detailed client configuration tweaks, see javadoc:org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration[].

Lettuce integrates with Netty's https://netty.io/wiki/native-transports.html[native transports], letting you use Unix domain sockets to communicate with Redis.
Make sure to include the appropriate native transport dependencies that match your runtime environment.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ include::example$examples/ReactiveRedisApplication.java[tags=file]

Even in this simple example, there are a few notable things to point out:

* You can create an instance of `RedisTemplate` (or `ReactiveRedisTemplate` for reactive usage) with a `RedisConnectionFactory`. Connection factories are an abstraction on top of the supported drivers.
* You can create an instance of javadoc:org.springframework.data.redis.core.RedisTemplate[] (or javadoc:org.springframework.data.redis.core.ReactiveRedisTemplate[]for reactive usage) with a javadoc:org.springframework.data.redis.connection.RedisConnectionFactory[]. Connection factories are an abstraction on top of the supported drivers.
* There's no single way to use Redis as it comes with support for a wide range of data structures such as plain keys ("strings"), lists, sets, sorted sets, streams, hashes and so on.
14 changes: 7 additions & 7 deletions src/main/antora/modules/ROOT/pages/redis/hash-mappers.adoc
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
[[redis.hashmappers.root]]
= Hash Mapping

Data can be stored by using various data structures within Redis. `Jackson2JsonRedisSerializer` can convert objects in https://en.wikipedia.org/wiki/JSON[JSON] format. Ideally, JSON can be stored as a value by using plain keys. You can achieve a more sophisticated mapping of structured objects by using Redis hashes. Spring Data Redis offers various strategies for mapping data to hashes (depending on the use case):
Data can be stored by using various data structures within Redis. javadoc:org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer[] can convert objects in https://en.wikipedia.org/wiki/JSON[JSON] format. Ideally, JSON can be stored as a value by using plain keys. You can achieve a more sophisticated mapping of structured objects by using Redis hashes. Spring Data Redis offers various strategies for mapping data to hashes (depending on the use case):

* Direct mapping, by using `HashOperations` and a xref:redis.adoc#redis:serializer[serializer]
* Direct mapping, by using javadoc:org.springframework.data.redis.core.HashOperations[] and a xref:redis.adoc#redis:serializer[serializer]
* Using xref:repositories.adoc[Redis Repositories]
* Using `HashMapper` and `HashOperations`
* Using javadoc:org.springframework.data.redis.hash.HashMapper[] and javadoc:org.springframework.data.redis.core.HashOperations[]

[[redis.hashmappers.mappers]]
== Hash Mappers

Hash mappers are converters of map objects to a `Map<K, V>` and back. `HashMapper` is intended for using with Redis Hashes.
Hash mappers are converters of map objects to a `Map<K, V>` and back. javadoc:org.springframework.data.redis.hash.HashMapper[] is intended for using with Redis Hashes.

Multiple implementations are available:

* `BeanUtilsHashMapper` using Spring's {spring-framework-javadoc}/org/springframework/beans/BeanUtils.html[BeanUtils].
* `ObjectHashMapper` using xref:redis/redis-repositories/mapping.adoc[Object-to-Hash Mapping].
* javadoc:org.springframework.data.redis.hash.BeanUtilsHashMapper[] using Spring's {spring-framework-javadoc}/org/springframework/beans/BeanUtils.html[BeanUtils].
* javadoc:org.springframework.data.redis.hash.ObjectHashMapper[] using xref:redis/redis-repositories/mapping.adoc[Object-to-Hash Mapping].
* <<redis.hashmappers.jackson2,`Jackson2HashMapper`>> using https://github.com/FasterXML/jackson[FasterXML Jackson].

The following example shows one way to implement hash mapping:
Expand Down Expand Up @@ -53,7 +53,7 @@ public class HashMapping {
[[redis.hashmappers.jackson2]]
=== Jackson2HashMapper

`Jackson2HashMapper` provides Redis Hash mapping for domain objects by using https://github.com/FasterXML/jackson[FasterXML Jackson].
javadoc:org.springframework.data.redis.hash.Jackson2HashMapper[] provides Redis Hash mapping for domain objects by using https://github.com/FasterXML/jackson[FasterXML Jackson].
`Jackson2HashMapper` can map top-level properties as Hash field names and, optionally, flatten the structure.
Simple types map to simple values. Complex types (nested objects, collections, maps, and so on) are represented as nested JSON.

Expand Down
18 changes: 9 additions & 9 deletions src/main/antora/modules/ROOT/pages/redis/pubsub.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,21 @@ In order to subscribe to messages, one needs to implement the `MessageListener`
[[redis:pubsub:subscribe:containers]]
=== Message Listener Containers

Due to its blocking nature, low-level subscription is not attractive, as it requires connection and thread management for every single listener. To alleviate this problem, Spring Data offers `RedisMessageListenerContainer`, which does all the heavy lifting. If you are familiar with EJB and JMS, you should find the concepts familiar, as it is designed to be as close as possible to the support in Spring Framework and its message-driven POJOs (MDPs).
Due to its blocking nature, low-level subscription is not attractive, as it requires connection and thread management for every single listener. To alleviate this problem, Spring Data offers javadoc:org.springframework.data.redis.listener.RedisMessageListenerContainer[], which does all the heavy lifting. If you are familiar with EJB and JMS, you should find the concepts familiar, as it is designed to be as close as possible to the support in Spring Framework and its message-driven POJOs (MDPs).

`RedisMessageListenerContainer` acts as a message listener container. It is used to receive messages from a Redis channel and drive the `MessageListener` instances that are injected into it. The listener container is responsible for all threading of message reception and dispatches into the listener for processing. A message listener container is the intermediary between an MDP and a messaging provider and takes care of registering to receive messages, resource acquisition and release, exception conversion, and the like. This lets you as an application developer write the (possibly complex) business logic associated with receiving a message (and reacting to it) and delegates boilerplate Redis infrastructure concerns to the framework.
javadoc:org.springframework.data.redis.listener.RedisMessageListenerContainer[] acts as a message listener container. It is used to receive messages from a Redis channel and drive the javadoc:org.springframework.data.redis.connection.MessageListener[] instances that are injected into it. The listener container is responsible for all threading of message reception and dispatches into the listener for processing. A message listener container is the intermediary between an MDP and a messaging provider and takes care of registering to receive messages, resource acquisition and release, exception conversion, and the like. This lets you as an application developer write the (possibly complex) business logic associated with receiving a message (and reacting to it) and delegates boilerplate Redis infrastructure concerns to the framework.

A `MessageListener` can additionally implement `SubscriptionListener` to receive notifications upon subscription/unsubscribe confirmation. Listening to subscription notifications can be useful when synchronizing invocations.
A javadoc:org.springframework.data.redis.connection.MessageListener[] can additionally implement javadoc:org.springframework.data.redis.connection.SubscriptionListener[] to receive notifications upon subscription/unsubscribe confirmation. Listening to subscription notifications can be useful when synchronizing invocations.

Furthermore, to minimize the application footprint, `RedisMessageListenerContainer` lets one connection and one thread be shared by multiple listeners even though they do not share a subscription. Thus, no matter how many listeners or channels an application tracks, the runtime cost remains the same throughout its lifetime. Moreover, the container allows runtime configuration changes so that you can add or remove listeners while an application is running without the need for a restart. Additionally, the container uses a lazy subscription approach, using a `RedisConnection` only when needed. If all the listeners are unsubscribed, cleanup is automatically performed, and the thread is released.
Furthermore, to minimize the application footprint, javadoc:org.springframework.data.redis.listener.RedisMessageListenerContainer[] lets one connection and one thread be shared by multiple listeners even though they do not share a subscription. Thus, no matter how many listeners or channels an application tracks, the runtime cost remains the same throughout its lifetime. Moreover, the container allows runtime configuration changes so that you can add or remove listeners while an application is running without the need for a restart. Additionally, the container uses a lazy subscription approach, using a `RedisConnection` only when needed. If all the listeners are unsubscribed, cleanup is automatically performed, and the thread is released.

To help with the asynchronous nature of messages, the container requires a `java.util.concurrent.Executor` (or Spring's `TaskExecutor`) for dispatching the messages. Depending on the load, the number of listeners, or the runtime environment, you should change or tweak the executor to better serve your needs. In particular, in managed environments (such as app servers), it is highly recommended to pick a proper `TaskExecutor` to take advantage of its runtime.


[[redis:pubsub:subscribe:adapter]]
=== The MessageListenerAdapter

The `MessageListenerAdapter` class is the final component in Spring's asynchronous messaging support. In a nutshell, it lets you expose almost *any* class as a MDP (though there are some constraints).
The javadoc:org.springframework.data.redis.listener.adapter.MessageListenerAdapter[] class is the final component in Spring's asynchronous messaging support. In a nutshell, it lets you expose almost *any* class as a MDP (though there are some constraints).

Consider the following interface definition:

Expand All @@ -96,7 +96,7 @@ public interface MessageDelegate {
}
----

Notice that, although the interface does not extend the `MessageListener` interface, it can still be used as a MDP by using the `MessageListenerAdapter` class. Notice also how the various message handling methods are strongly typed according to the *contents* of the various `Message` types that they can receive and handle. In addition, the channel or pattern to which a message is sent can be passed in to the method as the second argument of type `String`:
Notice that, although the interface does not extend the `MessageListener` interface, it can still be used as a MDP by using the javadoc:org.springframework.data.redis.listener.adapter.MessageListenerAdapter[] class. Notice also how the various message handling methods are strongly typed according to the *contents* of the various `Message` types that they can receive and handle. In addition, the channel or pattern to which a message is sent can be passed in to the method as the second argument of type `String`:

[source,java]
----
Expand All @@ -105,7 +105,7 @@ public class DefaultMessageDelegate implements MessageDelegate {
}
----

Notice how the above implementation of the `MessageDelegate` interface (the above `DefaultMessageDelegate` class) has *no* Redis dependencies at all. It truly is a POJO that we make into an MDP with the following configuration:
Notice how the above implementation of the `MessageDelegate` interface (the above `DefaultMessageDelegate` class) has *no* Redis dependencies at all. It truly is a POJO that we make into an MDP with the following configuration:

[tabs]
======
Expand Down Expand Up @@ -193,7 +193,7 @@ Each time a message is received, the adapter automatically and transparently per
[[redis:reactive:pubsub:subscribe:containers]]
== Reactive Message Listener Container

Spring Data offers `ReactiveRedisMessageListenerContainer` which does all the heavy lifting of conversion and subscription state management on behalf of the user.
Spring Data offers javadoc:org.springframework.data.redis.listener.ReactiveRedisMessageListenerContainer[] which does all the heavy lifting of conversion and subscription state management on behalf of the user.

The message listener container itself does not require external threading resources. It uses the driver threads to publish messages.

Expand Down Expand Up @@ -223,7 +223,7 @@ stream.doOnNext(inner -> // notification hook when Redis subscriptions are synch
[[redis:reactive:pubsub:subscribe:template]]
=== Subscribing via template API

As mentioned above you can directly use `ReactiveRedisTemplate` to subscribe to channels / patterns. This approach
As mentioned above you can directly use javadoc:org.springframework.data.redis.core.ReactiveRedisTemplate[] to subscribe to channels / patterns. This approach
offers a straight forward, though limited solution as you lose the option to add subscriptions after the initial
ones. Nevertheless you still can control the message stream via the returned `Flux` using eg. `take(Duration)`. When
done reading, on error or cancellation all bound resources are freed again.
Expand Down
Loading

0 comments on commit 0b2344b

Please sign in to comment.