|
| 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. |
0 commit comments