The goal of this project is to play with RSocket
protocol. For it, we will implement three Spring Boot
Java applications: movie-server
, movie-client-shell
and movie-client-ui
. As storage, it's used the reactive NoSQL database MongoDB
. All the streaming of movie events and the logging are handling by AOP (Aspect Oriented Programming).
On ivangfr.github.io, I have compiled my Proof-of-Concepts (PoCs) and articles. You can easily search for the technology you are interested in by using the filter. Who knows, perhaps I have already implemented a PoC or written an article about what you are looking for.
- [Medium] RSocket Crypto Server Tutorial
- [Medium] Implementing and Securing a Spring Boot RSocket App using Keycloak for IAM
-
Spring Boot
Java Web application that exposes REST API endpoints or RSocket routes to managemovies
. Movies data are stored in reactiveMongoDB
.movie-server
has the following profiles:-
default
- start REST API on port
8080
and usesHTTP
- start REST API on port
-
rsocket-tcp
- start REST API on port
8080
and usesHTTP
- start RSocket on port
7000
and usesTCP
- start REST API on port
-
rsocket-websocket
- start REST API on port
8080
and usesHTTP
- start RSocket with mapping-path
/rsocket
and usesWebSocket
- start REST API on port
-
-
Spring Boot
Shell Java application that has a couple of commands to interact withmovie-server
.The picture below show those commands
It has the following profiles:
-
default
- start shell with enabled commands to call
movie-server
REST API endpoints usingHTTP
- start shell with enabled commands to call
-
rsocket-tcp
- start shell with enabled commands to call
movie-server
REST API endpoints usingHTTP
- start shell with enabled commands to call
movie-server
RSocket routes usingTCP
- start shell with enabled commands to call
-
rsocket-websocket
- start shell with enabled commands to call
movie-server
REST API endpoints usingHTTP
- start shell with enabled commands to call
movie-server
RSocket routes usingWebSocket
- start shell with enabled commands to call
-
-
Spring Boot
Java Web application that usesThymeleaf
andWebsocket
to show at real-time all the events generated when movies are added, deleted, liked and disliked.movie-client-ui
has the following profiles:-
default
- start REST API on port
8081
and usesHTTP
- does not connect to
movie-server
throughRSocket
; does not receive movie events;
- start REST API on port
-
rsocket-tcp
- start REST API on port
8080
and usesHTTP
- connects to
movie-server
throughRSocket
usingTCP
; receives movie events;
- start REST API on port
-
rsocket-websocket
- start REST API on port
8080
and usesHTTP
- connects to
movie-server
throughRSocket
usingWebSocket
; receives movie events;
- start REST API on port
-
The GIF below shows a user running some commands in movie-client-shell
, terminal on the right. In the right-top terminal is running movie-server
and in the right-bottom, movie-client-ui
. On the background, there's a browser where movie events are displayed.
Open a terminal and inside springboot-rsocket-webflux-aop
root folder run
docker compose up -d
-
movie-server
Open a new terminal and, inside
springboot-rsocket-webflux-aop
root folder, run one of the following profile's commandProfile Command rsocket-tcp ./mvnw clean spring-boot:run --projects movie-server -Dspring-boot.run.profiles=rsocket-tcp rsocket-websocket ./mvnw clean spring-boot:run --projects movie-server -Dspring-boot.run.profiles=rsocket-websocket default ./mvnw clean spring-boot:run --projects movie-server -
movie-client-shell
Open a new terminal and, inside
springboot-rsocket-webflux-aop
root folder, run the following command to build the executable jar file./mvnw clean package --projects movie-client-shell -DskipTests
To start
movie-client-shell
, run the profile's command you picked to runmovie-server
Profile Commands rsocket-tcp export SPRING_PROFILES_ACTIVE=rsocket-tcp && ./movie-client-shell/target/movie-client-shell-1.0.0.jar rsocket-websocket export SPRING_PROFILES_ACTIVE=rsocket-websocket && ./movie-client-shell/target/movie-client-shell-1.0.0.jar default export SPRING_PROFILES_ACTIVE=default && ./movie-client-shell/target/movie-client-shell-1.0.0.jar -
movie-client-ui
Open a new terminal and, inside
springboot-rsocket-webflux-aop
root folder, run the profile's command you picked to runmovie-server
Profile Command rsocket-tcp ./mvnw clean spring-boot:run --projects movie-client-ui -Dspring-boot.run.profiles=rsocket-tcp rsocket-websocket ./mvnw clean spring-boot:run --projects movie-client-ui -Dspring-boot.run.profiles=rsocket-websocket default ./mvnw clean spring-boot:run --projects movie-client-ui
-
- In a terminal, make sure you are in
springboot-rsocket-webflux-aop
root folder - Run the following script to build the Docker images
- JVM
./docker-build.sh
- Native (it's not working yet, see Issues)
./docker-build.sh native
- JVM
- In a terminal, make sure you are in
-
-
movie-server
Environment Variable Description MONGODB_HOST
Specify host of the Mongo
database to use (defaultlocalhost
)MONGODB_PORT
Specify port of the Mongo
database to use (default27017
) -
movie-client-shell
Environment Variable Description MOVIE_SERVER_HOST
Specify host of the movie-server
to use (defaultlocalhost
) -
movie-client-ui
Environment Variable Description MOVIE_SERVER_HOST
Specify host of the movie-server
to use (defaultlocalhost
)
-
-
- In a terminal, make sure you are inside
springboot-rsocket-webflux-aop
root folder - Run following command
- rsocket-tcp
./start-server-and-ui.sh rsocket-tcp && ./start-shell.sh rsocket-tcp
- rsocket-websocket
./start-server-and-ui.sh rsocket-websocket && ./start-shell.sh rsocket-websocket
- default
./start-server-and-ui.sh && ./start-shell.sh
- rsocket-tcp
- In a terminal, make sure you are inside
Application | Type | Transport | URL |
---|---|---|---|
movie-server | RSocket | TCP | tcp://localhost:7000 |
movie-server | RSocket | WebSocket | ws://localhost:8080/rsocket |
movie-server | REST | HTTP | http://localhost:8080 |
movie-client-ui | Website | HTTP | http://localhost:8081 |
Note: you can see the clients connected to
movie-server
by calling theinfo
actuator endpointcurl -i localhost:8080/actuator/info
Note: to run the commands below, you must start
movie-server
andmovie-client-shell
withrsocket-tcp
orrsocket-websocket
profiles
-
Open a browser and access
movie-client-ui
at http://localhost:8081 -
Go to
movie-client-shell
terminal -
Add a movie using RSocket (
Request-Response
)add-movie-rsocket --imdb aaa --title "RSocketland"
It should return
{"imdb":"aaa","title":"RSocketland","lastModifiedDate":"2020-07-20T12:43:39.857248","likes":0,"dislikes":0}
A
+
action should be displayed inmovie-client-ui
-
Add a movie using REST
add-movie-rest --imdb bbb --title "I, REST"
It should return
{"imdb":"bbb","title":"I, REST","lastModifiedDate":"2020-07-20T12:44:13.266657","likes":0,"dislikes":0}
A
+
action should be displayed inmovie-client-ui
-
Send a like to
RSocketland
movie using RSocket (Fire-And-Forget
)like-movie-rsocket --imdb aaa
It should return
Like submitted
A
thumbs-up
action should be displayed inmovie-client-ui
-
Get all movies using RSocket (
Request-Stream
)get-movies-rsocket
It should return
{"imdb":"aaa","title":"RSocketland","lastModifiedDate":"2020-07-20T12:56:34.565","likes":1,"dislikes":0} {"imdb":"bbb","title":"I, REST","lastModifiedDate":"2020-07-20T12:56:26.846","likes":0,"dislikes":0}
-
Select movies using RSocket (
Channel
)select-movies-rsocket --imdbs aaa,bbb
It should return
| IMBD: aaa | TITLE: RSocketland | LIKES: 1 | DISLIKES: 0 | | IMBD: bbb | TITLE: I, REST | LIKES: 0 | DISLIKES: 0 |
-
Delete movie
RSocketland
using RSocket (Request-Response
) and movieI, REST
using RESTdelete-movie-rsocket --imdb aaa delete-movie-rest --imdb bbb
It should return, as response, the IMDB of the movies
A
-
actions should be displayed inmovie-client-ui
-
Simulation
There are two scripts that contain some commands to add, retrieve, like, dislikes and delete movies. One uses REST and another RSocket to communicate with
movie-server
. At the end of the script execution, it's shown theExecution Time
inmilliseconds
.-
If you are running the applications with Maven
- REST
script ../src/main/resources/simulation-rest.txt
- RSocket
script ../src/main/resources/simulation-rsocket.txt
- REST
-
If you are running the applications as Docker containers
- REST
script /workspace/BOOT-INF/classes/simulation-rest.txt
- RSocket
script /workspace/BOOT-INF/classes/simulation-rsocket.txt
- REST
-
-
MongoDB
Find all movies
docker exec -it mongodb mongosh moviedb db.movies.find()
Type
exit
to get out ofMongoDB
shell
- To stop
movie-client-shell
, go to the terminal where it is running and typeexit
- To stop
movie-server
andmovie-client-ui
- If you start them with Maven, go to the terminals where they are running and press
Ctrl+C
- If you start them as Docker containers, go to a terminal and, inside
springboot-rsocket-webflux-aop
root folder, run the following command./stop-server-and-ui.sh
- If you start them with Maven, go to the terminals where they are running and press
- To stop and remove docker compose
mongodb
container, network and volumes, go to a terminal and, insidespringboot-rsocket-webflux-aop
root folder, run the command belowdocker compose down -v
To remove the Docker images created by this project, go to a terminal and, inside springboot-rsocket-webflux-aop
root folder, run the script below
./remove-docker-images.sh
- https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#rsocket
- https://spring.io/blog/2020/05/12/getting-started-with-rsocket-servers-calling-clients
- https://grapeup.com/blog/reactive-service-to-service-communication-with-rsocket-introduction/
Docker native image builds and starts up successfully. However, it doesn't accept connections even using JVM version of movie-client-ui
and movie-client-shell
.
After building and starting the Docker native image successfully, the app looks fine (i.e., we can open the page, websocket is connected, etc). However, it is not connecting to movie-server
.
After building the Docker native image and running it successfully, we have some problems such as
- there is the following WARN
Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)
- the autocomplete is not working;
- when tried to run one of script files (
simulation-rest.txt
orsimulation-rsocket.txt
) there is the following exceptionmovie-client-shell> script /app/resources/simulation-rest.txt java.lang.NullPointerException Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace. movie-client-shell> stacktrace java.lang.NullPointerException at java.base@17.0.7/java.io.FileInputStream.<init>(FileInputStream.java:149) at java.base@17.0.7/java.io.FileReader.<init>(FileReader.java:75) at org.springframework.shell.standard.commands.Script.script(Script.java:60) at java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.shell.command.invocation.InvocableShellMethod.doInvoke(InvocableShellMethod.java:306) at org.springframework.shell.command.invocation.InvocableShellMethod.invoke(InvocableShellMethod.java:232) at org.springframework.shell.command.CommandExecution$DefaultCommandExecution.evaluate(CommandExecution.java:227) at org.springframework.shell.Shell.evaluate(Shell.java:248) at org.springframework.shell.Shell.run(Shell.java:159) at org.springframework.shell.jline.InteractiveShellRunner.run(InteractiveShellRunner.java:73) at org.springframework.shell.DefaultShellApplicationRunner.run(DefaultShellApplicationRunner.java:65) at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:762) at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:752) at org.springframework.boot.SpringApplication.run(SpringApplication.java:319) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) at com.ivanfranchin.movieclientshell.MovieClientShellApplication.main(MovieClientShellApplication.java:10)