Generator-jhipster: TODO : Reactive/Webflux support

Created on 11 May 2018  ·  34Comments  ·  Source: jhipster/generator-jhipster

I have created a branch reactive to support reactive/webflux applications.

This issue is a TODO list for what remains:

  • [x] Reactive DomainUserDetailsService (authentication) (@cbornet)
  • [x] Account resource (@cbornet)
  • [x] Security Audits (@cbornet #10405)
  • [x] Serve front-end / static content (@cbornet)
  • [x] Configure Locale resolver (@cbornet)
  • [x] Configure CORS (@cbornet)
  • [x] Exception handling (Problem) (https://github.com/zalando/problem-spring-web/pull/182)(@cbornet)
  • [x] Http session / Cookie auth (#9326) (@cbornet)
  • [x] OAuth2 (@mraible #11117)
  • [x] Cassandra (@cbornet in #9373)
  • [x] Disable caching (@cbornet #10107)
  • [x] Couchbase (@tchlyah in https://github.com/jhipster/generator-jhipster/pull/8997)
  • [x] Skip user management on monolith and no database (#11014)(@cbornet)
  • [x] API first (#8532) (@cbornet)
  • [x] Server resources tests with WebTestClient

    • [x] User (@cbornet)

    • [x] Account (@cbornet)

    • [x] Logs (@cbornet)

  • [x] Server resources

    • [x] User (@cbornet)

    • [x] Logs (@cbornet)

  • [x] With service registry (Eureka) (@cbornet)
  • [x] Micro-service app (@cbornet)
  • [x] Metrics reporting with micrometer (@cbornet)
  • [x] Tune logback (#10462)(@cbornet)
  • [x] Kafka option (#10935)(@cbornet)
  • [x] Add BlockHound and Hooks.onOperatorDebug() during tests (#11009)(@cbornet)

Related issues:

  • [x] Update entity generator to support reactive applications (#11404)
  • [x] Update entity generator to support Elasticsearch in reactive applications #11536
  • [x] Add R2DBC support #11439

Blocked:

Later:

  • [ ] WebClient configuration including integration with Netflix (in place of FeignClient)
  • [ ] RSocket client/server (same as WS)
$$ bug-bounty $$ $500 area java reactive ⚛️

Most helpful comment

R2DBC 0.8.0 M8 is out now.

All 34 comments

For information: there is currently no possibility for the entity auditing to get the current user from the ReactiveSecurityContextHolder. Hence createdBy and lastModifiedBy will have to be set explicitly. See https://jira.spring.io/browse/DATACMNS-1231

Also there is currently no support for security audits so they should be removed for now.

Note on R2DBC : currently it's not perf enough to be considered in a real life app mainly because it doesn't support connection pooling yet. See progress on this in https://github.com/reactor/reactor/issues/651

Cool ! Micrometer just works with Webflux !

@cbornet Seems in springfox project integration with SB 2.1.x has been merged... and it includes migration to swagger-ui 3.

Yes. We need the v3 of Springfox to be released. I tried to use the snapshot but had a lot of issues so I'll wait for the release. As for swagger UI, we don't use the one packaged by Springfox so we could already do the move.

Reactor now supports a reactive pool that could be useful for R2DBC connection pooling

R2DBC 0.8.0 M8 is out now.

Yes. I tested it and it does improve performance a lot. Great job !

As this is a very big one, I'm increasing the bug bounty to $500 !

It would probably be better to open individual issues for this. But I didn't want to cripple the issue tracker. Maybe I could open a dedicated repo where we can add smaller issues with smaller bounties ?

@cbornet you can put them on the main repo as long as we have the correct labels (maybe have a specific one for reactive), and the original plan was to have smaller $100 tickets. So if you do that we could split/move the bug bounty, but at the moment we only got this one.

About caching, there's currently no support for @Cacheable in spring data reactive. A reactor add-on can be used to wrap the CacheManager. Note that the CacheManager being a blocking API, it kind of defeats the async non-blocking pattern. For now, the best solution seems to be to disable the cache option for reactive apps.

There's currently no support for security nor STOMP for websockets in WebFlux. So it seems hard to do much more than a hello world right now...
The recommendation seems to be to evaluate RSocket instead which I can only agree with :smiley:

@cbornet I'd like to help get the Reactive support "good enough" to release as GA. Is this issue's TODO list up-to-date? If so, I can start working on OAuth support and maybe entity generation. Let me know.

Yes the TODO is up to date. Your help on the OAuth support is very welcome if course 😀! Thanks a lot Matt !

Do you think all checkboxes are necessary for a GA release or can we hide some and add them as we implement them?

On Dec 7, 2019, at 14:22, Christophe Bornet notifications@github.com wrote:


Yes the TODO is up to date. Your help on the OAuth support is very welcome if course 😀! Thanks a lot Matt !


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.

Yes we can define what we want for a GA. For instance, do you think SQL support is mandatory ?

If it's easy to integrate R2DBC, then yes.

On Dec 13, 2019, at 13:42, Christophe Bornet notifications@github.com wrote:


Yes we can define what we want for a GA. For instance, do you think SQL support is mandatory ?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.

@cbornet I started working on OAuth support in https://github.com/jhipster/generator-jhipster/pull/11049. I created a sample app at https://github.com/mraible/jhipster-reactive-monolith-oauth2 and a PR that makes login work.

I still need to add non-blocking support in UserService. I added // todo: comments in my PR for code that needs to be uncommented and fixed.

Cool ! On my side, I've made progress with the r2dbc support. It's almost ready but it requires that we first upgrade to Spring 5.2.

@cbornet Do you know how to get tests to work? I'm getting the following error when I run ./mvnw test. It seems like none of the tests with @SpringBootTest are being executed.

WARNING: TestEngine with ID 'junit-vintage' failed to discover tests
java.lang.NoClassDefFoundError: junit/runner/Version
    at org.junit.vintage.engine.JUnit4VersionCheck.checkSupported(JUnit4VersionCheck.java:32)
    at org.junit.vintage.engine.VintageTestEngine.discover(VintageTestEngine.java:61)
    at org.junit.platform.launcher.core.DefaultLauncher.discoverEngineRoot(DefaultLauncher.java:177)
    at org.junit.platform.launcher.core.DefaultLauncher.discoverRoot(DefaultLauncher.java:164)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
    at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:154)
    at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:127)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:377)
    at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:138)
    at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:465)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:451)

@cbornet Nevermind. I was able to solve this warning by changing the junit exclusion to:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
  <exclusions>
    <exclusion>
      <groupId>org.junit.vintage</groupId>
      <artifactId>junit-vintage-engine</artifactId>
    </exclusion>
  </exclusions>
</dependency>

I also realized you have to run mvn verify for the Spring Boot tests to run.

@cbornet I don't see Spring Cloud Gateway as one of the items in this issue's description. I have OAuth working with Spring Cloud Gateway in https://github.com/jhipster/generator-jhipster/pull/11223. I still need to add JWT support. Not sure if Consul is necessary since we're still in Alpha mode.

FYI... it seems like a reactive monolith doesn't pass ./mvnw verify.

[ERROR] Failures:
[ERROR]   ExceptionTranslatorIT.testMethodArgumentNotValid:41 Response header 'Content-Type' expected:<application/problem+json> but was:<text/plain>

> POST /api/exception-translator-test/method-argument
> WebTestClient-Request-Id: [17]
> Content-Type: [application/json]
> Content-Length: [2]

{}

< 403 FORBIDDEN Forbidden
< Content-Type: [text/plain]
< Cache-Control: [no-cache, no-store, max-age=0, must-revalidate]
< Pragma: [no-cache]
< Expires: [0]
< X-Content-Type-Options: [nosniff]
< X-XSS-Protection: [1 ; mode=block]
< Feature-Policy: [geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; fullscreen 'self'; payment 'none']
< Content-Security-Policy: [default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:]
< Referrer-Policy: [strict-origin-when-cross-origin]

CSRF Token has been associated to this client

[ERROR]   ExceptionTranslatorIT.testMethodNotSupported:96 Status expected:<405> but was:<403>

> POST /api/exception-translator-test/access-denied
> WebTestClient-Request-Id: [15]

No content

< 403 FORBIDDEN Forbidden
< Content-Type: [text/plain]
< Cache-Control: [no-cache, no-store, max-age=0, must-revalidate]
< Pragma: [no-cache]
< Expires: [0]
< X-Content-Type-Options: [nosniff]
< X-XSS-Protection: [1 ; mode=block]
< Feature-Policy: [geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; fullscreen 'self'; payment 'none']
< Content-Security-Policy: [default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:]
< Referrer-Policy: [strict-origin-when-cross-origin]

CSRF Token has been associated to this client

[INFO]
[ERROR] Tests run: 33, Failures: 2, Errors: 0, Skipped: 0

Here's my .yo-rc.json:

{
  "generator-jhipster": {
    "promptValues": {
      "packageName": "com.mycompany.myapp",
      "nativeLanguage": "en"
    },
    "jhipsterVersion": "6.7.1",
    "applicationType": "monolith",
    "baseName": "mono",
    "packageName": "com.mycompany.myapp",
    "packageFolder": "com/mycompany/myapp",
    "serverPort": "8080",
    "authenticationType": "oauth2",
    "cacheProvider": "no",
    "enableHibernateCache": false,
    "websocket": false,
    "databaseType": "mongodb",
    "devDatabaseType": "mongodb",
    "prodDatabaseType": "mongodb",
    "searchEngine": false,
    "messageBroker": false,
    "serviceDiscoveryType": false,
    "buildTool": "maven",
    "enableSwaggerCodegen": false,
    "embeddableLaunchScript": false,
    "useSass": true,
    "clientPackageManager": "npm",
    "clientFramework": "angularX",
    "clientTheme": "none",
    "clientThemeVariant": "",
    "creationTimestamp": 1582154650121,
    "testFrameworks": ["protractor"],
    "jhiPrefix": "jhi",
    "entitySuffix": "",
    "dtoSuffix": "DTO",
    "otherModules": [],
    "enableTranslation": true,
    "nativeLanguage": "en",
    "languages": ["en"],
    "blueprints": [],
    "reactive": true
  }
}

@jhipster/developers Spring Cloud Gateway integration seems to be good to go! Should I merge?

I kept the Zuul code for Zuul for non-reactive apps. This means that we're just adding a feature, no breaking changes.

@cbornet Adding support for Elasticsearch seems to be the last thing to do to close this issue. Is that correct?

Indeed ! We could even open another issue for ES and close this one.

@cbornet I created https://github.com/jhipster/generator-jhipster/issues/11536 for Elasticsearch support.

OK. I'm removing it from here since it has it's own issue.
So we just need to merge #11009 and this issue can be closed.

All items are done so I guess we can close this big one.
Many thanks to @mraible for the work on OIDC and to @tchlyah for the couchbase support.
How do you think the bounty should be shared ?

@cbornet : I disagree about sharing the bounty because:

  • it was so much work to achieve this
  • as you was the lead on this part, you should take the main bounty (500$) and it will be well deserved. But I'm not sure it would be enough... we can discuss if you think it's not enough :)
  • for other people who participated to this ticket, we can do separate bounty (100$ or more if you think it's deserved) for each part

Just tell me.
What do you think ?

I also agree with Pascal, we have enough money to give more bounty

Thanks & Regards,
Deepu

On Wed, Apr 8, 2020 at 3:47 PM Pascal Grimaud notifications@github.com
wrote:

@cbornet https://github.com/cbornet : I disagree about sharing the
bounty because:

  • it was so much work to achieve this
  • as you was the lead on this part, you should take the main bounty
    (500$) and it will be well deserved. But I'm not sure it would be enough...
    we can discuss if you think it's not enough :)
  • for other people who participated to this ticket, we can do separate
    bounty (100$ or more if you think it's deserved) for each part

Just tell me.
What do you think ?


You are receiving this because you are on a team that was mentioned.
Reply to this email directly, view it on GitHub
https://github.com/jhipster/generator-jhipster/issues/7608#issuecomment-610970424,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAIOKF4MFQVFQLWPT5AI6X3RLR6APANCNFSM4E7OZQQA
.

Thank you @cbornet, glad to hear that I helped.

I totally agree with @pascalgrimaud, you deserve the whole bounty, and even more.

@cbornet You did as much work as I did on the OIDC integration! +1 to give you the whole bounty.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

marcelinobadin picture marcelinobadin  ·  3Comments

Steven-Garcia picture Steven-Garcia  ·  3Comments

SudharakaP picture SudharakaP  ·  3Comments

ahmedeldeeb25 picture ahmedeldeeb25  ·  3Comments

DanielFran picture DanielFran  ·  3Comments