Closed paris0120 closed 2 years ago
@paris0120 I see that you are opening many issues and thanks for your interest in helping the project. But could you please follow the issue template and provide more details like the configuration used and so on so that we dont wate time and there is better chance of issue resolution please
@paris0120 I see that you are opening many issues and thanks for your interest in helping the project. But could you please follow the issue template and provide more details like the configuration used and so on so that we dont wate time and there is better chance of issue resolution please
OK, updated.
blog application is missing clientFramework, so it's not a microfrontend. gateway is using react, store is using angular, mixing client frameworks is not supported.
blog application is missing clientFramework, so it's not a microfrontend. gateway is using react, store is using angular, mixing client frameworks is not supported.
Isn't this duplicated and confusing? If the microservice has to have the same client framework why they can have their own setting?
Also even gateway have the same framework as angular the problem still exists.
blog application is missing clientFramework, so it's not a microfrontend. gateway is using react, store is using angular, mixing client frameworks is not supported.
Isn't this duplicated and confusing? If the microservice has to have the same client framework why they can have their own setting?
Also even gateway have the same framework as angular the problem still exists.
See https://github.com/jhipster/generator-jhipster/issues/19340#issuecomment-1207203662
Please fix the jdl, so we can try to reproduce.
I was able to reproduce this today with the following command:
jhipster jdl reactive-mf --skip-install --client-framework angularX
After generating the apps, I started the gateway and logged in. I looked in the Entities menu and found there are no errors rendered. When you use the above command with react
, the fact that the downstream microfrontends can't be loaded is communicated to the user.
I figured if I started the blog
app, I'd at least be able to see its entities. After starting the blog and still seeing no entities, I saw the following error in my browser console.
Then, I tried to start the store
app and saw this error.
container entry:./user[0] - Error: Module not found: Error: Can't resolve '
app/entities/user/user.module.ts' in '/Users/mraible/Downloads/mfa-ng/store'
The errors happens on microfrontend side (not gateway) with oauth2. User was wrongly been exposed by the microfrontend. Exposing entities are not required anymore.
been
For the case above user entity is not required but if user has relationship with some of the entitles user entity is still needed.
@mshima Are you saying that the JDL for reactive-mf.jdl is incorrect?
https://github.com/jhipster/jdl-samples/blob/main/reactive-mf.jdl
@mraible no, the PR https://github.com/jhipster/generator-jhipster/pull/19357 should fix the issue.
For the case above user entity is not required but if user has relationship with some of the entitles user entity is still needed.
I haven't tried, but it should work just fine, the menu and routes are exposed (and everything they depends on).
@mshima I tried your PR and it does fix this particular problem. However, I did notice that I'm unable to save a new blog entity. It seems like it works if I don't select a user, but no data is inserted into the database. If I do select a user, the entity is created in the database, but the user relationship is not saved.
Something might be missing from our Cypress tests since all e2e pass for the blog app.
I investigated and did some debugging as to why the user relationship is not getting saved properly. It appears that all the data is being sent properly from the UI, and the backend is receiving it. However, saving the blog
entity with blog.user
populated doesn't seem to be working. I do see the following in the logs.
2022-08-07T11:06:44.820-06:00 WARN 320 --- [o4jDriverIO-2-7] o.s.d.n.c.m.DefaultNeo4jIsNewStrategy :
Instances of class com.okta.developer.blog.domain.User with an assigned id will always be treated as new
without version property!
@atomfrede Do you think this could be caused by an upgrade to Neo4j?
I just tried my original example from this blog post and everything works as expected. The example is created with v7.0.1 and you can save a blog
entity with or without a user
and it all works.
@mraible weblux+neo4j is broken for almost 6 months. And were flaky before that. https://github.com/hipster-labs/jhipster-daily-builds/actions/workflows/neo4j.yaml?page=7 Do you think I should test user relationships using another database?
@mshima I tested with React and Vue. Both of them seem to let you add the user successfully.
However, neither one renders the user on the view or edit screens.
I tried a new JDL for my microfrontends architecture today, changing to no database in the gateway and PostgreSQL in the blog app. In doing so, I discovered that a database is required when using oauth2 on the gateway if you have microservices with relationships to user
. If you use the JDL below, it'll generate just fine, but when you try to add a new blog, it'll 404 on the request for users from the gateway.
application {
config {
baseName gateway
reactive true
packageName com.okta.developer.gateway
applicationType gateway
authenticationType oauth2
buildTool gradle
clientFramework react
databaseType no
serviceDiscoveryType eureka
testFrameworks [cypress]
microfrontends [blog, store]
}
}
application {
config {
baseName blog
reactive true
packageName com.okta.developer.blog
applicationType microservice
authenticationType oauth2
buildTool gradle
clientFramework react
prodDatabaseType postgresql
serverPort 8081
serviceDiscoveryType eureka
testFrameworks [cypress]
}
entities Blog, Post, Tag
}
application {
config {
baseName store
reactive true
packageName com.okta.developer.store
applicationType microservice
authenticationType oauth2
buildTool gradle
clientFramework react
databaseType mongodb
devDatabaseType mongodb
prodDatabaseType mongodb
enableHibernateCache false
serverPort 8082
serviceDiscoveryType eureka
testFrameworks [cypress]
}
entities Product
}
entity Blog {
name String required minlength(3)
handle String required minlength(2)
}
entity Post {
title String required
content TextBlob required
date Instant required
}
entity Tag {
name String required minlength(2)
}
entity Product {
title String required
price BigDecimal required min(0)
image ImageBlob
}
relationship ManyToOne {
Blog{user(login)} to User
Post{blog(name)} to Blog
}
relationship ManyToMany {
Post{tag(name)} to Tag{post}
}
paginate Post, Tag with infinite-scroll
paginate Product with pagination
deployment {
deploymentType docker-compose
appsFolders [gateway, blog, store]
dockerRepositoryName "mraible"
}
deployment {
deploymentType kubernetes
appsFolders [gateway, blog, store]
clusteredDbApps [store]
kubernetesNamespace demo
serviceDiscoveryType eureka
dockerRepositoryName "mraible"
}
I checked jhipster jdl reactive-ms
(microservices, not microfrontends). It uses Vue for the frontend. Adding a new blog with a user works and renders the entity as expected in the list. However, when you try to view the entity, there's an error in the console, and nothing loads.
vue-router.esm.js:2316 TypeError: Cannot read properties of undefined (reading 'call')
at __webpack_require__ (bootstrap:19:1)
at ./src/main/webapp/app/entities/blog/blog/blog-details.vue (blog-details.vue:15:1)
at Function.__webpack_require__ (bootstrap:19:1)
If you try to edit the blog, the form renders just fine, but the assigned user is not selected.
If I create the same stack with React:
jhipster jdl reactive-ms.jdl --client-framework react
The behavior is the same. It adds and renders fine in the list, but not in the view or update screens. There's also an error in the console when the list loads.
react-dom.development.js:86 Warning: Cannot update a component (`PrivateRoute`) while rendering a
different component (`__WEBPACK_DEFAULT_EXPORT__`). To locate the bad setState() call inside
`__WEBPACK_DEFAULT_EXPORT__`, follow the stack trace as described in
https://reactjs.org/link/setstate-in-render at __WEBPACK_DEFAULT_EXPORT__
@mraible user api is always using gateways api, it may not be synchronized. Not sure if https://github.com/jhipster/generator-jhipster/pull/19382 fixes user issues.
@mshima I tried https://github.com/jhipster/generator-jhipster/pull/19382 with the following command (after checking out the branch and running npm link
):
jhipster jdl reactive-ms.jdl --client-framework react
I get an error when generating the apps:
create src/main/docker/central-server-config/localhost-config/application.yml
ERROR! /Users/mraible/dev/generator-jhipster/generators/client/templates/react/src/main/webapp/app/shared/reducers/user-management.ts.ejs:30
28| };
29|
>> 30| const apiUrl = '<%= entityApi %>api/users';
31|
32| // Async Actions
33|
entityApi is not defined
ReferenceError: /Users/mraible/dev/generator-jhipster/generators/client/templates/react/src/main/webapp/app/shared/reducers/user-management.ts.ejs:30
28| };
29|
>> 30| const apiUrl = '<%= entityApi %>api/users';
31|
32| // Async Actions
33|
entityApi is not defined
at JHipsterClientGenerator.eval ("/Users/mraible/dev/generator-jhipster/generators/client/templates/react/src/main/webapp/app/shared/reducers/user-management.ts.ejs":13:26)
at user-management.ts (/Users/mraible/dev/generator-jhipster/node_modules/ejs/lib/ejs.js:703:17)
at /Users/mraible/dev/generator-jhipster/node_modules/ejs/lib/ejs.js:260:40
at new Promise (<anonymous>)
at tryHandleCache (/Users/mraible/dev/generator-jhipster/node_modules/ejs/lib/ejs.js:258:14)
at Object.exports.renderFile (/Users/mraible/dev/generator-jhipster/node_modules/ejs/lib/ejs.js:491:10)
at EditionInterface.processFile (/Users/mraible/dev/generator-jhipster/node_modules/mem-fs-editor/lib/actions/copy-tpl-async.js:22:20)
at EditionInterface.applyProcessingFileFunc (/Users/mraible/dev/generator-jhipster/node_modules/mem-fs-editor/lib/actions/copy-async.js:14:52)
at EditionInterface.exports._copySingleAsync (/Users/mraible/dev/generator-jhipster/node_modules/mem-fs-editor/lib/actions/copy-async.js:94:50)
at EditionInterface.exports.copyAsync (/Users/mraible/dev/generator-jhipster/node_modules/mem-fs-editor/lib/actions/copy-async.js:50:17)
at async EditionInterface.module.exports [as copyTplAsync] (/Users/mraible/dev/generator-jhipster/node_modules/mem-fs-editor/lib/actions/copy-tpl-async.js:11:3)
at async renderTemplate (/Users/mraible/dev/generator-jhipster/generators/generator-base.js:2507:11)
at async Promise.all (index 40)
at async JHipsterClientGenerator.writeFiles (/Users/mraible/dev/generator-jhipster/generators/generator-base.js:2627:19) {
path: '/Users/mraible/dev/generator-jhipster/generators/client/templates/react/src/main/webapp/app/shared/reducers/user-management.ts.ejs'
@mraible I did some test with syncUserWithIdP
. It's not compatible with microfrontends and microservices (gateways should work).
The synchronization happens here https://github.com/jhipster/generator-jhipster/blob/9f478679d9f59ef891243399809479fd93772386/generators/server/templates/src/main/java/package/web/rest/AccountResource.java.ejs#L78
It's executed when the current account is fetched, so only a user that was logged at some time will show. I suggest to open a new bug report to discuss.
The AccountResource doesn't exists at microservices.
@mshima I think it's fine that it's not supported. However, we might want to catch it earlier. Currently, if you use JDL to create a gateway with oauth2
and databaseType: no
, it will compile and generate everything just fine. However, if you have a downstream microservice with a relationship to User
, the user lookup will fail. I'm not sure if we can do anything to validate that.
FWIW, I do plan to investigate using SCIM to synchronize users from identity providers in the future.
What about the compile error above? It happens when I use your skip_ci-api_url
branch and jhipster jdl reactive-ms
.
@mraible should be fixed at the PR, but it's useless without the backend support. Should we fail when a user relationship is found at Microservices?
@mshima I pulled from your branch and tried again. jhipster jdl reactive-ms --client-framework react
still has strange behavior that didn't exist when I first wrote my tutorial with JHipster 7.0.1.
The original example uses Vue. When you assign a user to a blog it'll show in the list, view, and edit screens. Now, it only shows on the list screen.
I also tried microfrontends using jhipster jdl reactive-mf --client-framework react
. It has the same behavior as reactive-ms.
I'll try with Angular and Vue.
Should we fail when a user relationship is found at Microservices?
No. It worked at one point so it seems there's a regression.
Ought I think the examples worked because you are using neo4j. At the form, the user is loaded using the gateway api. Neo4j cascades, so the user entity (which was loaded from the gateway) and the relationship are saved. At databases like postgresql, it would fail to save due to missing user from relationship.
Results for saving a blog user with microservices (reactive-ms
) JDL:
One interesting thing to note is I left the data intact after running the Angular example. When I loaded it up with the Vue UI, it does render the user in the list. So it seems that Angular might have some errors in its list template. I'll investigate to see if I can find a fix.
I discovered the difference between Angular and Vue.
For Angular, the list screen issues a request to the backend with parameters.
http://localhost:9000/services/blog/api/blogs?eagerload=true&sort=id,asc
With Vue, there are no parameters. I tried changing blog.component.ts
to not use the query object in the queryBackend()
method.
return this.blogService.query().pipe(tap(() => (this.isLoading = false)));
This makes it so the user is rendered in Angular's list screen.
I also inspected the API calls for the view and edit screens. The data returned contains user: null
so it seems it might be a problem on the backend.
I tried a different JDL, this time using Angular for the client and PostgreSQL for the blog.
When I try to save a blog with a user, there's a 500 error on the server.
2022-08-09T17:30:13.859-06:00 ERROR 2911 --- [ctor-http-nio-2] o.z.problem.spring.common.AdviceTraits : Internal Server Error
org.springframework.dao.DataIntegrityViolationException: executeMany; SQL [INSERT INTO blog (name, handle, user_id) VALUES ($1, $2, $3)]; Referential integrity constraint violation: "FK_BLOG__USER_ID: PUBLIC.BLOG FOREIGN KEY(USER_ID) REFERENCES PUBLIC.JHI_USER(ID) ('4c973896-5761-41fc-8217-07c5d13a004b')"; SQL statement:
INSERT INTO blog (name, handle, user_id) VALUES ($1, $2, $3) [23506-200]; nested exception is io.r2dbc.spi.R2dbcDataIntegrityViolationException: [23506] [23506] Referential integrity constraint violation: "FK_BLOG__USER_ID: PUBLIC.BLOG FOREIGN KEY(USER_ID) REFERENCES PUBLIC.JHI_USER(ID) ('4c973896-5761-41fc-8217-07c5d13a004b')"; SQL statement:
INSERT INTO blog (name, handle, user_id) VALUES ($1, $2, $3) [23506-200]
at org.springframework.r2dbc.connection.ConnectionFactoryUtils.convertR2dbcException(ConnectionFactoryUtils.java:229)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Assembly trace from producer [reactor.core.publisher.MonoError]
My JDL:
application {
config {
baseName gateway
reactive true
packageName com.okta.developer.gateway
applicationType gateway
authenticationType oauth2
buildTool gradle
clientFramework angularX
prodDatabaseType postgresql
serviceDiscoveryType eureka
testFrameworks [cypress]
}
entities Blog, Post, Tag, Product
}
application {
config {
baseName blog
reactive true
packageName com.okta.developer.blog
applicationType microservice
authenticationType oauth2
buildTool gradle
prodDatabaseType postgresql
serverPort 8081
serviceDiscoveryType eureka
}
entities Blog, Post, Tag
}
application {
config {
baseName store
reactive true
packageName com.okta.developer.store
applicationType microservice
authenticationType oauth2
buildTool gradle
databaseType mongodb
devDatabaseType mongodb
prodDatabaseType mongodb
enableHibernateCache false
serverPort 8082
serviceDiscoveryType eureka
}
entities Product
}
entity Blog {
name String required minlength(3)
handle String required minlength(2)
}
entity Post {
title String required
content TextBlob required
date Instant required
}
entity Tag {
name String required minlength(2)
}
entity Product {
title String required
price BigDecimal required min(0)
image ImageBlob
}
relationship ManyToOne {
Blog{user(login)} to User
Post{blog(name)} to Blog
}
relationship ManyToMany {
Post{tag(name)} to Tag{post}
}
paginate Post, Tag with infinite-scroll
paginate Product with pagination
microservice Product with store
microservice Blog, Post, Tag with blog
deployment {
deploymentType docker-compose
appsFolders [gateway, blog, store]
dockerRepositoryName "mraible"
}
I think this logic in BlogResource#createBlog()
used to solve this, but it's not working anymore. Maybe because it's not subscribed to?
if (blog.getUser() != null) {
// Save user in case it's new and only exists in gateway
userRepository.save(blog.getUser());
}
@mraible implemented the syncUser logic at the /api/users api for Microservices at https://github.com/jhipster/generator-jhipster/pull/19384. User relationships are ok.
Generated using Postgres:
jhipster jdl reactive-mf.jdl --client-framework angularX --workspaces --monorepository --db postgresql --skip-jhipster-dependencies --build maven
npm run java:docker:arm64
npm run ci:e2e:prepare
@mshima The issue I identified in my last three comments have nothing to do with microfrontends. I know it's confusing since this issues is related to microfrontends. I was simply trying to get reactive-ms.jdl
working, which is a microservices architecture with a monolith UI on the gateway. I tried the fix in https://github.com/jhipster/generator-jhipster/pull/19384 and the following command:
jhipster jdl reactive-ms.jdl --client-framework angularX
It has the same issue where it makes a call to /services/blog/api/blogs?eagerload=true&sort=id,asc
on the list screen and no user is returned. If I change the URL to /services/blog/api/blogs
, the user is returned.
I also tried with PostgreSQL (again, with microservices JDL, not microfrontends):
jhipster jdl reactive-ms.jdl --client-framework angularX --db postgresql
This results in the blog
app not starting with the following error:
2022-08-10T09:52:20.290-06:00 ERROR 17595 --- [ restartedMain] t.j.c.liquibase.AsyncSpringLiquibase :
Liquibase could not start correctly, your database is NOT ready: FATAL: role "blog" does not exist
org.postgresql.util.PSQLException: FATAL: role "blog" does not exist
Since the gateway is already using PostgreSQL, I'm guessing this is because I'm unable to start the blog's PostgreSQL Docker container.
➜ blog git:(main) jhpostgresqlup
WARN[0000] Found orphan containers ([docker-jhipster-registry-1 docker-keycloak-1 docker-gateway-postgresql-1 docker-blog-neo4j-1]) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
[+] Running 0/1
⠙ Container docker-blog-postgresql-1 Starting 0.1s
Error response from daemon: driver failed programming external connectivity on endpoint docker-blog-postgresql-1 (5f3f49f571e1a1c070da6849c6a0718db900643e2d701d14e2fe35b94e123a44): Bind for 127.0.0.1:5432 failed: port is already allocated
I investigated and did some debugging as to why the user relationship is not getting saved properly. It appears that all the data is being sent properly from the UI, and the backend is receiving it. However, saving the
blog
entity withblog.user
populated doesn't seem to be working. I do see the following in the logs.2022-08-07T11:06:44.820-06:00 WARN 320 --- [o4jDriverIO-2-7] o.s.d.n.c.m.DefaultNeo4jIsNewStrategy : Instances of class com.okta.developer.blog.domain.User with an assigned id will always be treated as new without version property!
@atomfrede Do you think this could be caused by an upgrade to Neo4j?
Not sure, but yes it might be related. It sounds like by default optimistic locking is active now
@mraible since you opened https://github.com/jhipster/generator-jhipster/issues/19399 to track relationships. https://github.com/jhipster/generator-jhipster/pull/19357 can be reviewed since it fixes this bug.
I can confirm that https://github.com/jhipster/generator-jhipster/pull/19357 fixes this bug and that Angular and React + microfrontends works without issues!
With Vue, I get errors when I create apps with jhipster jdl reactive-mf --client-framework vue
and run all apps with Gradle.
@mraible the PR changes angular only.
With Vue, I get errors when I create apps with
jhipster jdl reactive-mf --client-framework vue
and run all apps with Gradle.![]()
looks related to webpack.
try removing build/webpack
and recreating package-lock.json and node_modules.
@mshima I tried again this morning with the main
branch and everything works as expected.
@DanielFran bounty claimed https://opencollective.com/generator-jhipster/expenses/90547.
@mshima approved
Overview of the issue
I got the following errors with micro frontend. The 'user.module.ts' file is missing.
[INFO] container entry:./user[0] - Error: Module not found: Error: Can't resolve 'app/entities/user/user.module.ts' in '/home/paris/projects/tradingemulator/ms/trading' [INFO] [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 17.126 s [INFO] Finished at: 2022-08-04T14:11:27-04:00 [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal com.github.eirslett:frontend-maven-plugin:1.12.1:npm (webapp build dev) on project trading: Failed to run task: 'npm run webapp:build' failed. org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1) -> [Help 1] [ERROR]
Motivation for or Use Case
Generate micro frontend
Reproduce the error
generate app with the following jdl profile then mvnspring-boot:run for the store app.
Related issues
Suggest a Fix
JHipster Version(s)
7.9.2
JHipster configuration
Entity configuration(s)
entityName.json
files generated in the.jhipster
directoryBrowsers and Operating System