Git Product home page Git Product logo

nexiles / spring-cloud-gateway-rsocket-websocket Goto Github PK

View Code? Open in Web Editor NEW
8.0 3.0 2.0 4.95 MB

SpringBoot example application using SpringCloudGateway, RSocket, SpringSecurity, VueJS and optionally KeyCloak

License: MIT License

JavaScript 21.49% Vue 26.50% Sass 1.26% HTML 1.61% Java 49.13%
rsocket communication websocket stream keycloak-client springcloud-gateway spring-boot example-code springsecurity request-stream

spring-cloud-gateway-rsocket-websocket's Introduction

SpringCloud Gateway RSocket Example

NOTE: This Project has been archived and will no longer get updates.

What is RSocket ?

Check out the official docs: RSocket Docs

Most interesting:

Network communication is asynchronous. The RSocket protocol embraces this and models all communication as multiplexed streams of messages over a single network connection, and never synchronously blocks while waiting for a response

In this example I am using a SpringCloud Gateway to demonstrate how RSocket communication works over WebSocket with an rsocket-js client and VueJS frontend.

Motivation

We'd like to use a single websocket endpoint/broker for multiple services. The normal spring integration with STOMP over WebSocket cannot be used on the reactive stack. Therefore, I had to take a deeper look into RSocket.

The Example

The server is creating scheduled order events which are added to a stream, those can be retrieved using a HTTP GET or RSocket Request Stream.

There are two kind of order, LOTR (Lord of the Rings) order and GOT (Game of Thrones) order, to demonstrate how routes & security can be handled. The order event is a order with random kind (either GOT or LOTR).

For now this example is just using the REQUEST_STREAM frame, but could be easily extended.

The decision about who retrieves which data is made based on the users authorities.

Demo

SpringSecurity

springsecurity-example

KeyCloak

keycloak-example

Security

This example can be used with two different Identity Providers:

Those can be easily switched trough using profiles.

Users

Username Password Role Can access/retrieve orders
admin admin ADMIN ALL
frodo frodo MIDDLEEARTH LOTR
john john WESTEROS GOT

To administrate the KeyCloak use username: kcadmin and password: kcadmin.

Spring Security

Routes and endpoints requested via basic auth.

KeyCloak

Routes are requested via bearer auth (where the JWT is obtained before the request is made) and endpoints are handled by the SpringCloudGateway which holds the authentication (OAuth2 client).

Test it

Either use the checked in IntelliJ run-configuration in .run or launch it manually.

Server (Maven v3.6.3)

SpringSecurity

$ mvn clean package
$ cd target/
$ java -jar gateway-rsocket-websocket.jar

KeyCloak

Run the KeyCloak using docker-compose up and start the server afterwards:

$ mvn clean package
$ cd target/
$ java -jar -Dspring.profiles.active=keycloak gateway-rsocket-websocket.jar

Client (Node v14.16.0 & NPM v6.14.11)

$ cd frontend/
$ npm install
$ npm run dev

Now head over to the frontend served under http://localhost:8070/ (routed by the gateway).

Ports used

Server: 8070

Client: 8080

KeyCloak: 8060 (optional)

Test with other tools

All values in doubled curly brackets ({{}) must be replaced with the actual value, including the brackets!

RSocket

For RSocket development I used RSC installed using:

brew install making/tap/rsc

Note: When using this tool whole frames sent are visible and also check out the server logs.

SpringSecurity

# Basic
$ rsc --stream --route=orders.all --sm simple:{{user}}:{{password}} --smmt MESSAGE_RSOCKET_AUTHENTICATION --debug ws://localhost:8070/server/rsocket
$ rsc --stream --route=orders.lotr --sm simple:{{user}}:{{password}} --smmt MESSAGE_RSOCKET_AUTHENTICATION --debug ws://localhost:8070/server/rsocket
$ rsc --stream --route=orders.got --sm simple:{{user}}:{{password}} --smmt MESSAGE_RSOCKET_AUTHENTICATION --debug ws://localhost:8070/server/rsocket

# With data (payload)
$ rsc --stream --route=orders.all --sm simple:{{user}}:{{password}} --smmt MESSAGE_RSOCKET_AUTHENTICATION --debug --data='{"rscclient":"request"}' ws://localhost:8070/server/rsocket

# With metadata
$ rsc --stream --route=orders.all --sm simple:{{user}}:{{password}} --smmt MESSAGE_RSOCKET_AUTHENTICATION --debug --metadata='{"data":"custom metadata value from rsc"}' ws://localhost:8070/server/rsocket

KeyCloak

First we need to get an access_token for bearer auth, see this

# Basic
$ rsc --stream --route=orders.all --sm "bearer:{{access_token}}" --smmt MESSAGE_RSOCKET_AUTHENTICATION --debug ws://localhost:8070/server/rsocket
$ rsc --stream --route=orders.lotr --sm "bearer:{{access_token}}" --smmt MESSAGE_RSOCKET_AUTHENTICATION --debug ws://localhost:8070/server/rsocket
$ rsc --stream --route=orders.got --sm "bearer:{{access_token}}" --smmt MESSAGE_RSOCKET_AUTHENTICATION --debug ws://localhost:8070/server/rsocket

# With data (payload)
$ rsc --stream --route=orders.all --sm "bearer:{{access_token}}" --smmt MESSAGE_RSOCKET_AUTHENTICATION --debug --data='{"rscclient":"request"}' ws://localhost:8070/server/rsocket

# With metadata
$ rsc --stream --route=orders.all --sm "bearer:{{access_token}}" --smmt MESSAGE_RSOCKET_AUTHENTICATION --debug --metadata='{"data":"custom metadata value from rsc"}' ws://localhost:8070/server/rsocket

HTTP

To retrieve the stream using HTTP I used HTTPIE using:

SpringSecurity

Retrieve orders:

http --stream :8070/server/orders --auth "{{user}}:{{password}}"

Create orders:

# Random
http :8070/server/orders/new --auth "{{user}}:{{password}}"
# Specific
http :8070/server/orders/new kind==lotr --auth "{{user}}:{{password}}"
http :8070/server/orders/new kind==got --auth "{{user}}:{{password}}"

http --stream :8070/server/orders Authorization:"Bearer {{access_token}}"

KeyCloak

First we need to get an access_token for bearer auth, see this

http --stream :8070/server/orders Authorization:"Bearer {{access_token}}"

Create orders:

# Random
http :8070/server/orders/new Authorization:"Bearer {{access_token}}"
# Specific
http :8070/server/orders/new kind==lotr Authorization:"Bearer {{access_token}}"
http :8070/server/orders/new kind==got Authorization:"Bearer {{access_token}}"

Get KeyCloak AccessToken

To directly extract the token from the JSON response JQ is used.

http -f :8060/auth/realms/RSOCKET/protocol/openid-connect/token client_id=gateway username={{user}} password={{password}} grant_type=password client_secret=059fa1a6-b94f-42a1-81c8-210acfe6f299 | jq .access_token

Now this token can be used for bearer auth.

Next up

  • Payload integration
  • Custom metadata
  • Route with variable
  • SpringSecurity
  • Multiple routes

Disclaimer

We are pretty new to WebFlux and the whole reactor project, so this code might not be optimized for being non-blocking, suggestions are welcome.

Contributing

Each contribution, no matter in what, is highly appreciated!

spring-cloud-gateway-rsocket-websocket's People

Contributors

dependabot[bot] avatar s-frei avatar seletz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

varunarang awsp

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.