Skip to content

Commit f265b20

Browse files
committed
Ascii Docs documentation
1 parent 4f068e4 commit f265b20

File tree

8 files changed

+375
-0
lines changed

8 files changed

+375
-0
lines changed

docs/.DS_Store

6 KB
Binary file not shown.

docs/asciidoc/.DS_Store

6 KB
Binary file not shown.

docs/asciidoc/api-guide.adoc

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
== Reactive Commons API
2+
3+
[[api-guide-overview]]
4+
=== Overview
5+
6+
This section describes the reactive API for producing and consuming messages using Reactive Commons.
7+
There are three main classes in Reactive Commons:
8+
9+
. `HandlerRegistry` for listening to events and commands messages and for registering their respective handlers.
10+
. `DomainEventBus` for emiting events to an event bus
11+
. `DirectAsyncGateway` for emiting commands to an event bus
12+
13+
The project uses https://github.com/reactor/reactor-core[Reactor Core] to expose a https://github.com/reactive-streams/reactive-streams-jvm["Reactive Streams"] API.
14+
15+
=== Semantic Messages Classes
16+
17+
Reactice Commons has 2 classes that represent events or commands, it give it a semantic meaning for a message. So, let talks about DomainEvent and Command classes .
18+
19+
==== DomainEvent<T>
20+
21+
This class let you represent a Event in the system. It accepts a generic class that will be the information to transport for that event, a eventId and a name for the event. The structure for a DomainEvent is:
22+
23+
[source,java]
24+
--------
25+
package org.reactivecommons.api.domain;
26+
27+
public class DomainEvent<T> {
28+
private final String name;
29+
private final String eventId;
30+
private final T data;
31+
32+
public DomainEvent(String name, String eventId, T data) {
33+
this.name = name;
34+
this.eventId = eventId;
35+
this.data = data;
36+
}
37+
38+
//... getters, equals, hascode, toString impl..
39+
40+
}
41+
--------
42+
43+
==== Command<T>
44+
45+
An other basic structure is the Command class. This class let you represent a Command/Request in the system. It accepts a generic class that will be the information for that command, a eventId and a name for that event. The structure for a DomainEvent is:
46+
47+
[source,java]
48+
--------
49+
package org.reactivecommons.api.domain;
50+
51+
52+
import lombok.AllArgsConstructor;
53+
import lombok.Data;
54+
55+
@Data
56+
@AllArgsConstructor
57+
public class Command<T> {
58+
private final String name;
59+
private final String commandId;
60+
private final T data;
61+
}
62+
--------
63+
64+
=== Reactive Commons - Sending Events and Commands
65+
66+
Outbound messages are sent to an event bus using `DomainEventBus` or `DirectAsyncGateway` classes. If you are using Spring Boot, you can have a Main class like this:
67+
68+
[source,java]
69+
--------
70+
import org.reactivecommons.async.impl.config.annotations.EnableDomainEventBus;
71+
import org.springframework.boot.SpringApplication;
72+
import org.springframework.boot.autoconfigure.SpringBootApplication;
73+
74+
@SpringBootApplication
75+
@EnableDomainEventBus
76+
public class MainApplication {
77+
public static void main(String[] args) {
78+
SpringApplication.run(MainApplication.class, args);
79+
}
80+
81+
@Bean
82+
public ManageTasksUseCase manageTasksUseCase(TaskToDoRepository tasks, DomainEventBus eventBus) {
83+
return new ManageTasksUseCase(tasks, eventBus);
84+
}
85+
86+
}
87+
--------
88+
89+
The @EnableDomainEventBus annotation enable to the application to emit Events to the System. This annotation create a EnableDomainEventBus Bean, so you can use it for emit events. This interface looks like:
90+
91+
[source,java]
92+
--------
93+
package org.reactivecommons.api.domain;
94+
95+
import org.reactivestreams.Publisher;
96+
97+
public interface DomainEventBus {
98+
<T> Publisher<Void> emit(DomainEvent<T> event);
99+
}
100+
--------
101+
102+
The emit method recive a DomainEvent<T> class where you can publish information to the system. The method will respond you in a reacive way with a Publisher, like a Mono or a Flux object. So, for example, if you want to send a UserRegistered event to the system ,you have to us
103+
104+
105+
[source,java]
106+
--------
107+
108+
public class AnyUseCase {
109+
110+
private DomainEventBus eventBus;
111+
112+
public ManageTasksUseCase( DomainEventBus eventBus) {
113+
this.eventBus = eventBus;
114+
}
115+
116+
public Mono<TaskToDo> doSomething(String name, String description) {
117+
return doSomething()
118+
.flatMap(task -> emitCreatedEvent(task).thenReturn(task));
119+
}
120+
121+
private Mono<Void> emitCreatedEvent(EventClass event) {
122+
return Mono.from(eventBus.emit(new DomainEvent<>("name.event", uuid(), event)));
123+
}
124+
//...
125+
}
126+
--------

docs/asciidoc/getting-started.adoc

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
== Getting Started
2+
3+
[[Requirements]]
4+
=== Requirements
5+
6+
You need Java JRE installed (Java 8 or later).
7+
8+
You also need to install RabbitMQ. Follow the
9+
https://www.rabbitmq.com/download.html[instructions from the website].
10+
Note you should use RabbitMQ 3.6.x or later.
11+
12+
=== Quick Start
13+
14+
This quick start tutorial sets up a single node RabbitMQ and runs the sample reactive
15+
sender and consumer using Reactive Commons.
16+
17+
==== Start RabbitMQ
18+
19+
Start RabbitMQ on your local machine with all the defaults (e.g. AMQP port is 5672).
20+
21+
==== Sample Spring Boot Application
22+
23+
The Spring Boot sample publishes and cosumes messages with the `DomainEventBus`. This application illustrates how to configure Reactive Commons using RabbitMQ in a Spring Boot environment.
24+
25+
To build your own application using the Reactive Commons API,
26+
you need to include a dependency to Reactive Commons.
27+
28+
[source,groovy,subs="attributes,specialcharacters"]
29+
--------
30+
dependencies {
31+
compile "org.reactivecommons:async-commons-starter:{appversion}"
32+
}
33+
--------
34+
35+
Also you need to include the name for your app in the application.properties:
36+
[source]
37+
--------
38+
spring.application.name=MyAppName
39+
--------
40+
Or yaml
41+
[source, yaml]
42+
--------
43+
spring:
44+
application:
45+
name: myAppName
46+
--------
47+
48+
The https://github.com/reactor/reactor-rabbitmq/blob/master/reactor-rabbitmq-samples/src/main/java/reactor/rabbitmq/samples/SpringBootSample.java[`SpringBootSample`]
49+
code is on GitHub.
50+
51+
===== DomainEventBus
52+
53+
You must enable DomainEventBus with the @EnableDomainEventBus annotation. It give you a bean DomainEventBus, which let you, to emit and listen messages like DomainEvent type.
54+
55+
===== DomainEvent Class
56+
The DomainEvent class has the following structure:
57+
58+
[source,java]
59+
--------
60+
package org.reactivecommons.api.domain;
61+
62+
public class DomainEvent<T> {
63+
private final String name;
64+
private final String eventId;
65+
private final T data;
66+
67+
public DomainEvent(String name, String eventId, T data) {
68+
this.name = name;
69+
this.eventId = eventId;
70+
this.data = data;
71+
}
72+
73+
//... getters, equals, hascode, toString impl..
74+
75+
}
76+
--------
77+
78+
A Main application may looks like:
79+
80+
[source,java]
81+
--------
82+
import org.reactivecommons.async.impl.config.annotations.EnableDomainEventBus;
83+
import org.springframework.boot.SpringApplication;
84+
import org.springframework.boot.autoconfigure.SpringBootApplication;
85+
86+
@SpringBootApplication
87+
@EnableDomainEventBus
88+
public class MainApplication {
89+
public static void main(String[] args) {
90+
SpringApplication.run(MainApplication.class, args);
91+
}
92+
93+
@Bean
94+
public ManageTasksUseCase manageTasksUseCase(TaskToDoRepository tasks, DomainEventBus eventBus) {
95+
return new ManageTasksUseCase(tasks, eventBus);
96+
}
97+
98+
}
99+
--------
100+
101+
Where the ManageTasksUseCase expose some use cases of the domain.
102+
103+
[source,java]
104+
--------
105+
106+
public class ManageTasksUseCase {
107+
108+
private TaskToDoRepository tasks;
109+
private DomainEventBus eventBus;
110+
111+
public ManageTasksUseCase(TaskToDoRepository tasks, DomainEventBus eventBus) {
112+
this.tasks = tasks;
113+
this.eventBus = eventBus;
114+
}
115+
116+
public Mono<TaskToDo> createNew(String name, String description) {
117+
return uuid()
118+
.flatMap(id -> TaskToDoFactory.createTask(id, name, description))
119+
.flatMap(tasks::save)
120+
.flatMap(task -> emitCreatedEvent(task).thenReturn(task));
121+
}
122+
123+
private Mono<Void> emitCreatedEvent(TaskToDo task) {
124+
return Mono.from(eventBus.emit(new DomainEvent<>("task.created", task.getId(), task)));
125+
}
126+
//...
127+
}
128+
--------
129+
130+
===== HandlerRegistry
131+
Reactive commons has four types of listeners implemented, available to be registered in the application via the HandlerRegistry, each of them is designed to tackle common requirements for listeners in event based applications and abstracts the behavior of event flow in every situation .
132+
133+
A simple sample is:
134+
135+
[source,java]
136+
--------
137+
import org.springframework.context.annotation.Bean;
138+
import org.springframework.context.annotation.Configuration;
139+
import org.springframework.beans.factory.annotation.Autowired;
140+
141+
@Configuration
142+
public class SomeConfigurationClass {
143+
144+
@Autowired
145+
private ManageTasksUseCase someBusinessDependency;
146+
147+
@Bean
148+
public HandlerRegistry notificationEvents() {
149+
return HandlerRegistry.register()
150+
.listenEvent("task.created", event -> someBusinessDependency.functionReturningMonoVoid(event), EventClass.class);
151+
}
152+
}
153+
--------
154+
155+
[#versioning]
156+
==== Versioning
157+
158+
Reactive Commons used https://semver.org/
159+
160+
Reactive Commons uses a `MAJOR.MINOR.PATCH` scheme, whereby an increment in:
161+
162+
* MAJOR version when you make incompatible API changes,
163+
* MINOR version when you add functionality in a backwards compatible manner, and
164+
* PATCH version when you make backwards compatible bug fixes.
165+
Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.

docs/asciidoc/images/pubsub.png

242 KB
Loading

docs/asciidoc/index.asciidoc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
= Reactive Commons Reference Guide
2+
Daniel Bustamante Ospina
3+
// version is automatically set in doc.gradle, no need to change it here
4+
:appversion: 1.0.0.BUILD-SNAPSHOT
5+
ifndef::host-github[:ext-relative: {outfilesuffix}]
6+
{appversion}
7+
:doctype: book
8+
:toc:
9+
:toclevels: 4
10+
:source-highlighter: prettify
11+
:numbered:
12+
:icons: font
13+
:hide-uri-scheme:
14+
:imagesdir: images
15+
16+
:github-repo: reactive-commons
17+
:github-code: https://github.com/{github-repo}
18+
19+
// ======================================================================================
20+
= Introduction
21+
include::overview.adoc[]
22+
include::getting-started.adoc[]
23+
include::new.adoc[]
24+
= Reference Documentation
25+
include::api-guide.adoc[]
26+
// ======================================================================================

docs/asciidoc/new.adoc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
== New & Noteworthy
2+
3+
[[new]]
4+
5+
=== What's new in Reactive Commons 1.0
6+
7+
* Introduction of the Reactive Commons API (DomainEvent, Command, DynamicRegistry, HandlerRegistry and DirectAsyncGateway classes/interfaces )
8+
* Support for request/reply pattern
9+
* Support for Direct Commands pattern
10+
* Support for Event pattern
11+
* Exception handling
12+
* Support for RabbitMQ
13+
* Support for SNS/SQS
14+

docs/asciidoc/overview.adoc

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
== Overview
2+
3+
=== Reactive Commons
4+
5+
The purpose of reactive-commons is to provide a set of abstractions and implementations over different patterns and practices that make the foundation of a reactive microservices architecture.
6+
7+
Even though the main purpose is to provide such abstractions in a mostly generic way such abstractions would be of little use without a concrete implementation so we provide some implementations in a best effors maner that aim to be easy to change, personalize and extend.
8+
9+
The first approach to this work was to release a very simple abstractions and a corresponding implementation over asyncronous message driven communication between microservices build on top of project-reactor and spring boot.
10+
11+
=== Project Reactor
12+
13+
https://projectreactor.io[Reactor] is a highly optimized reactive library for
14+
building efficient, non-blocking applications on the JVM based on the
15+
https://github.com/reactive-streams/reactive-streams-jvm[Reactive Streams Specification].
16+
Reactor based applications can sustain very high throughput message rates
17+
and operate with a very low memory footprint,
18+
making it suitable for building efficient event-driven applications using
19+
the microservices architecture.
20+
21+
Reactor implements two publishers
22+
https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html[Flux<T>] and
23+
https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html[Mono<T>],
24+
both of which support non-blocking back-pressure.
25+
This enables exchange of data between threads with well-defined memory usage,
26+
avoiding unnecessary intermediate buffering or blocking.
27+
28+
=== Reactive API for Event Mechanism
29+
30+
Reactive Commons is a reactive API for asyncronous message driven communication based on Reactor.
31+
Reactive Commons API enables messages to be published over RabbitMQ or SNS/SQS and consumed from those products using functional APIs with non-blocking back-pressure and low overheads.
32+
This enables applications using Reactor to use RabbitMQ or SNS/SQS as a message bus, integrating with other systems to provide an end-to-end reactive system.
33+
34+
When we talk about asyncronous message driven communication, we can use several sematic ways to use the term "message". So, we can talk about Events and Commands.
35+
36+
==== Events - Pub/Sub
37+
Events represent a fact inside the domain, it is the representation of a decision or a state change that a system want to notify to its subscriptors. Events represents facts in the past, so events are not intentions or requests of anything in present, for example: "UserRegistered", "NotificationSent".
38+
39+
Events are the most important topic in a Publish-Subscribe system, because this element let us to notify a many stakeholders in a specific event. An other benefit is system is decouple, because you can add more subscriber to the system without modify some component.
40+
41+
==== Commands
42+
Commands represent a intention for doing something, that intention must to be doing by the domain context with that responsibility. An example of a command may be: "registerUser", "sendNotification".
43+
44+
==== Request / Reply

0 commit comments

Comments
 (0)