relationship between two entities in different micro-services - jhipster

i have a question : does jhipster allow relationship between two entities in different micro-services
i have a :
1- customer microservice (with Customer entity)
2-farm microservice (with Farm entity)
it is possibl to do a ManytoOne relationship between Customer and Farm ? and How ?
this is my jdl file
application {
config {
baseName gateway
packageName com.privacy.gateway
applicationType gateway
serverPort 8080
serviceDiscoveryType eureka
databaseType mongodb
cacheProvider hazelcast
authenticationType oauth2
buildTool maven
clientFramework react
}
entities *
}
application {
config {
baseName soilmonitoring
packageName com.privacy.soilmonitoring
applicationType microservice
serverPort 8081
serviceDiscoveryType eureka
databaseType mongodb
cacheProvider hazelcast
authenticationType oauth2
buildTool maven
}
entities SoilStream, SoilDevice
}
application {
config {
baseName customer
packageName com.privacy.customer
applicationType microservice
serverPort 8082
serviceDiscoveryType eureka
databaseType mongodb
cacheProvider hazelcast
authenticationType oauth2
buildTool maven
}
entities Customer
}
application {
config {
baseName farm
packageName com.privacy.farm
applicationType microservice
serverPort 8083
serviceDiscoveryType eureka
databaseType mongodb
cacheProvider hazelcast
authenticationType oauth2
buildTool maven
}
entities Farm
}
application {
config {
baseName farmservice
packageName com.privacy.farmservice
applicationType microservice
serverPort 8084
serviceDiscoveryType eureka
databaseType mongodb
cacheProvider hazelcast
authenticationType oauth2
buildTool maven
}
entities FarmService
}
entity SoilDevice {
name String required
status DeviceStatus
}
entity FarmService {
name String required
subscriptionPlan SubscriptionPlan
}
entity Customer {
description String
}
entity Farm {
name String
description String
}
enum DeviceStatus {
ONLINE , OFFLINE
}
enum SubscriptionPlan {
SMALL , MEDIUM , LARGE
}
entity SoilStream {
soilTemp Float
soilHum Float
soilO2 Float
soilCO2 Float
soilEc Float
soilPh Float
lighting Float
airTemp Float
airHum Float
}
relationship ManyToMany{
FarmService{farm} to Farm{farmservice}
}
relationship ManyToOne {
SoilStream{soildevice} to SoilDevice
Farm{customer} to Customer{farm}
}
paginate all with pagination
service all with serviceClass
dto all with mapstruct
microservice SoilStream, SoilDevice with soilmonitoring
microservice Farm with farm
microservice Customer with customer
microservice FarmService with farmservice
deployment {
deploymentType docker-compose
appsFolders [gateway , soilmonitoring , customer , farm, farmservice]
}
when i run jhipster import-jdl file.jdl i got the error :
ERROR! Error during import-jdl: Entities for the ManyToMany relationship from 'FarmService' to 'Farm' do not belong to the same application.

You can't because they are stored in 2 different databases. The only thing you can do is to use ID of the other entity, then depending on your use case you may aggregate data in an upper level service or in UI or duplicate partial data.
See the discussion in JHipster issue tracking to understand more: https://github.com/jhipster/generator-jhipster/issues/9949

Related

How to restore persistence properties that the domain model does not have

I have been thinking and reading about this for some time with not success.
I'm in the process of separating the db layer from the domain (I was using orm entities as domain entities).
To do it I have created simple mapper classes with methods to transform a persistence entity to a domain entity and viceversa.
The problem comes when a domain entity does not have all the persistence properties as they are useless for the bussiness logic (for example the user logo image url).
I map the user db result to its domain entity without saving the logo so when I try to convert it back to persistence I don't have a way to retrieve again the logo.
My question is, there is a pattern to solve this or a domain entity does have to always contain all the necessary info to be persisted even when that info is completely useless for the bussiness logic?
Code example:
// User persistence entity
class User {
name
is_active
account_id
logo
}
// User domain entity
class User {
name
isActive
account
}
// Mapper
class UserEntityMapper {
static toDomain(raw) {
return new User({
name: raw.name,
isActive: raw.is_active,
account: raw.account_id,
})
}
static toPersistence(User domain) {
return {
name: domain.name,
is_active: domain.isActive,
account_id: domain.account,
logo: // How tf can i get the logo here????
}
}
}

Why my microservice does not automatically add user information?

I created application with the following jdl.
And then, I ran the test with cypress when it was created successfully.
Most of them pass but get some errors in entities that have relationship with User entity in microservice.
I noticed that the application does not automatically add user information to the microservices' databases. This is unlike any other I have done before. I tried removing the kafka option but the result is the same.
Tell me, is my design wrong? Please
Thanks very much
application {
config {
baseName StudySpace
applicationType gateway
packageName io.witcher.studyspace
serverPort 8080
authenticationType oauth2
databaseType sql
devDatabaseType mysql
prodDatabaseType mysql
cacheProvider hazelcast
clientFramework react
buildTool gradle
languages [vi, en]
clientTheme flatly
serviceDiscoveryType consul
testFrameworks [cypress]
messageBroker kafka
}
entities *
}
application {
config {
baseName GroupService
applicationType microservice
packageName io.witcher.studyspace.group_service
serverPort 8081
authenticationType oauth2
databaseType sql
devDatabaseType mysql
prodDatabaseType mysql
buildTool gradle
languages [en, vi]
cacheProvider hazelcast
serviceDiscoveryType consul
testFrameworks [cypress]
messageBroker kafka
}
entities Group, GroupMember, GroupAdmin, WaitingMember
}
application {
config {
baseName ExamStore
applicationType microservice
packageName io.witcher.studyspace.exam_store
serverPort 8082
authenticationType oauth2
databaseType sql
devDatabaseType mysql
prodDatabaseType mysql
buildTool gradle
languages [en, vi]
cacheProvider hazelcast
serviceDiscoveryType consul
testFrameworks [cypress]
messageBroker kafka
}
entities Topic, Exam, ExamItem, Question, Option, QuestionGroup
}
application {
config {
baseName AnswerStore
reactive true
applicationType microservice
packageName io.witcher.studyspace.answer_store
serverPort 8083
authenticationType oauth2
databaseType sql
devDatabaseType mysql
prodDatabaseType mysql
buildTool gradle
languages [en, vi]
cacheProvider hazelcast
serviceDiscoveryType consul
testFrameworks [cypress]
messageBroker kafka
}
entities GroupTimeTable, TimeTable, AnswerSheet, AnswerSheetItem
}
entity GroupAdmin {}
entity WaitingMember {}
entity GroupMember {}
entity Group {
groupId String unique required
name String minlength(5) maxlength(255) required
}
entity Topic {
topicId String unique required
name String minlength(5) maxlength(255) required
}
entity QuestionGroup {
repoId String unique required
name String minlength(5) maxlength(255) required
groupId String
}
entity Question {
content TextBlob required
note TextBlob
}
entity Option {
content TextBlob required
isCorrect Boolean required
}
entity Exam {
examId String unique required
name String minlength(3) maxlength(155) required
duration Integer min(5) max(180) required
mix Integer min(0) max(2) required
groupId String required
}
entity ExamItem {
numOfQuestion Integer required
}
entity GroupTimeTable {
examId String required
startAt Instant required
endAt Instant required
groupId String required
note String
}
entity TimeTable {
title String minlength(2) maxlength(255)
time Instant
note TextBlob required
}
entity AnswerSheet {
time Instant required
}
entity AnswerSheetItem {
questionId Integer required
answerId Integer required
}
relationship ManyToOne {
GroupMember{user(login)} to User
GroupMember{group(groupId)} to Group
WaitingMember{user(login)} to User
WaitingMember{group(groupId)} to Group
GroupAdmin{user(login)} to User
GroupAdmin{group(groupId)} to Group
AnswerSheet{groupTimeTable} to GroupTimeTable
AnswerSheet{user(login)} to User
TimeTable{user(login)} to User
AnswerSheetItem{answerSheet} to AnswerSheet
QuestionGroup{user(login)} to User
QuestionGroup{topic(topicId)} to Topic
Question{repo(repoId)} to QuestionGroup
Option{question} to Question
ExamItem{repo} to QuestionGroup
ExamItem{exam} to Exam
}
dto * with mapstruct
service * with serviceClass
paginate * with infinite-scroll
microservice Group, GroupMember, GroupAdmin, WaitingMember with GroupService
microservice Topic, Exam, ExamItem, Question, Option, QuestionGroup with ExamStore
microservice GroupTimeTable, TimeTable, AnswerSheet, AnswerSheetItem with AnswerStore

JHipster How to control entitie generation to microservice? or How to do JDL properly to get the entities generated into the right micorservice folder

I am trying to prototype a microservice application with JHipster and I have tried to collect all the information what I was able in order to do it properly, but it is not totally clear how to put together a JDL to have the right entities in the right services generated.
What I would expect is to have a directory layout like:
/..
gateway <- Ideal would be to have only fronted code
invoice <- Invoice CRUD code with corresponding ms (with below JDL it is empty)
order <- Order CRUD code with corresponding ms
usage <- Usage CRUD code with corresponding ms (with below JDL it is empty)
Here is the JDL used:
application {
config {
baseName gateway,
applicationType gateway,
packageName com.org.myApp.sales,
serviceDiscoveryType eureka,
searchEngine elasticsearch,
authenticationType oauth2,
prodDatabaseType postgresql,
cacheProvider hazelcast,
buildTool gradle,
clientFramework react,
testFrameworks [protractor]
}
entities *
}
application {
config {
baseName invoice,
applicationType microservice,
packageName com.org.myApp.invoice,
serviceDiscoveryType eureka,
searchEngine elasticsearch,
authenticationType oauth2,
prodDatabaseType postgresql,
devDatabaseType postgresql,
buildTool gradle,
serverPort 8081,
skipUserManagement true
}
entities Invoice, Product
}
application {
config {
baseName usage,
applicationType microservice,
packageName com.org.myApp.usage,
serviceDiscoveryType eureka,
searchEngine elasticsearch,
authenticationType oauth2,
prodDatabaseType postgresql,
devDatabaseType postgresql,
cacheProvider no,
enableHibernateCache false,
buildTool gradle,
serverPort 8082,
skipUserManagement true
}
entities Usage
}
application {
config {
baseName order,
applicationType microservice,
packageName com.org.myApp.order,
serviceDiscoveryType eureka,
searchEngine elasticsearch,
authenticationType oauth2,
prodDatabaseType postgresql,
devDatabaseType postgresql,
buildTool gradle,
serverPort 8083,
skipUserManagement true
}
entities ProductOrder, OrderItem, ProductCategory, Product
}
entity Product {
name String required
description String
price BigDecimal required min(0)
size Size required
image ImageBlob
}
enum Size {
S, M, L, XL, XXL
}
entity ProductCategory {
name String required
description String
}
entity Customer {
firstName String required
lastName String required
gender Gender required
email String required pattern(/^[^#\s]+#[^#\s]+\.[^#\s]+$/)
phone String required
addressLine1 String required
addressLine2 String
city String required
country String required
}
enum Gender {
MALE, FEMALE, OTHER
}
entity ProductOrder {
placedDate Instant required
status OrderStatus required
code String required
invoiceId Long
}
enum OrderStatus {
COMPLETED, PENDING, CANCELLED
}
entity OrderItem {
quantity Integer required min(0)
totalPrice BigDecimal required min(0)
status OrderItemStatus required
}
enum OrderItemStatus {
AVAILABLE, OUT_OF_STOCK, BACK_ORDER
}
relationship OneToOne {
Customer{user(login) required} to User
}
relationship ManyToOne {
OrderItem{product(name) required} to Product
}
relationship OneToMany {
ProductOrder{orderItem} to OrderItem{order(code) required} ,
ProductCategory{product} to Product{productCategory(name)}
}
service Product, ProductCategory, Customer, ProductOrder, OrderItem with serviceClass
paginate Product, Customer, ProductOrder, OrderItem with pagination
/* Entities for Invoice microservice */
entity Invoice {
code String required
date Instant required
details String
status InvoiceStatus required
paymentMethod PaymentMethod required
paymentDate Instant required
paymentAmount BigDecimal required
}
enum InvoiceStatus {
PAID, ISSUED, CANCELLED
}
enum PaymentMethod {
CREDIT_CARD, CASH_ON_DELIVERY, PAYPAL
}
entity Usage {
date Instant required
details String
sentDate Instant required
userId Long required
productId Long required
}
microservice Invoice with invoice
microservice Usage with usage
microservice Product, ProductCategory, ProductOrder, OrderItem with order
dto * with mapstruct
paginate Invoice with pagination
Environment:
##### **Environment and Tools**
JHipster version: v6.6.0
java version "11.0.5" 2019-10-15 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.5+10-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.5+10-LTS, mixed mode)
node: v12.14.0
npm: 6.13.4
yeoman: 3.1.1
INFO! Congratulations, JHipster execution is complete!
So here are my questions:
1. What is exactly controlling where the entities are generated?
application {
config {
baseName gateway,
applicationType gateway,
packageName com.org.myApp.sales,
serviceDiscoveryType eureka,
searchEngine elasticsearch,
authenticationType oauth2,
prodDatabaseType postgresql,
cacheProvider hazelcast,
buildTool gradle,
clientFramework react,
testFrameworks [protractor]
}
entities * <-- What if all entities associated to a different service not to the gateway? (actually when I tried I ended up with an empty folder for gateway)
}
2. How is microservice <ENTITIES> with <MICROSERVICE_APP_NAME> relates to the above mentioned entities * section?
3. Is the relationship between entities affects where the code is generated?
Entities are not generated in a gateway from backend standpoint, only frontend code for these entities is generated
It's used by the gateway to route to correct microservice
There can't be any relationship between entities from different microservices because they reside in distinct databases

Cassandra support in apollo graphql

I want to connect Apache Cassandra to apollo graphql server. Is there any ORM library available for cassandra in node just like Sequelize for relational databases.
Can any one please help me out
Maybe this could help:
http://express-cassandra.readthedocs.io/en/stable/
From the description of the page: Express-Cassandra is a Cassandra ORM/ODM/OGM for NodeJS with Elassandra & JanusGraph Support.
There is an automatically generated GraphQL API for Cassandra that you can run as a service to expose your CQL tables via GraphQL.
GitHub repo: https://github.com/datastax/cassandra-data-apis
Small Example:
Say you have the a table called books
CREATE TABLE library.books (
title text PRIMARY KEY,
author text
);
It will automatically generate these APIs
schema {
query: Query
mutation: Mutation
}
type Query {
books(value: BooksInput, orderBy: [BooksOrder], options: QueryOptions): BooksResult
booksFilter(filter: BooksFilterInput!, orderBy: [BooksOrder], options: QueryOptions): BooksResult
}
type Mutation {
insertBooks(value: BooksInput!, ifNotExists: Boolean, options: UpdateOptions): BooksMutationResult
updateBooks(value: BooksInput!, ifExists: Boolean, ifCondition: BooksFilterInput, options: UpdateOptions): BooksMutationResult
deleteBooks(value: BooksInput!, ifExists: Boolean, ifCondition: BooksFilterInput, options: UpdateOptions): BooksMutationResult
}
And you can query them with
mutation {
catch22: insertBooks(value: {title:"Catch-22", author:"Joseph Heller"}) {
value {
title
}
}
}
query {
books (value: {title:"Catch-22"}) {
values {
title
author
}
}
}

Merge two endpoint using a different name and schema with Eve

This is a simplified version of my settings.py:
accounts_schema = {
'username': {
},
'password': {
}
}
accounts = {
'schema': accounts_schema,
}
After a user is created with a POST request to the /accounts endpoint, the user's info can be retrived with a GET to /accounts/<id_of_user>.
I would like to know if it possible to "merge" two endpoints that are using a different schema so
POST /update_accounts/<id_of_user>
will point to
/accounts/<id_of_user>
but update_accounts must have, for example, this schema:
update_accounts_schema = {
'token': {
},
'validity': {
}
}
From the documentation:
Multiple API endpoints can target the same database collection. For example you can set both admins and /users to read and write from the same people collection on the database.
So you can have update_accounts and accounts both targeting the same datasource, and each one with its own user privileges/allowed methods, etc.

Resources