jhipster / generator-jhipster

JHipster is a development platform to quickly generate, develop, & deploy modern web applications & microservice architectures.
https://www.jhipster.tech
Apache License 2.0
21.51k stars 4.02k forks source link

JWT + Memcached broken #14102

Closed pascalgrimaud closed 3 years ago

pascalgrimaud commented 3 years ago

See https://github.com/hipster-labs/jhipster-daily-builds/actions/workflows/jdl-broken-config.yaml

mraible commented 3 years ago

Is there an easy way to recreate the eureka-maven-jwt-react-memcached project locally?

pascalgrimaud commented 3 years ago

The steps:

mraible commented 3 years ago

I recreated eureka-maven-jwt-react-memcached locally and the customer entity does indeed fail in e2e tests.

mraible commented 3 years ago

It happens because the application type is gateway and it's not reactive. Enabling reactive in the JDL fixes it.

    ✔  All specs passed!                        01:29       60       60        -        -        -

Execution time: 2 min. 7 s.

PR coming shortly...

pascalgrimaud commented 3 years ago

Indeed you're right, @mraible : the generated JDL is:

application {
 config {
   baseName store
   applicationType gateway
   packageName tech.jhipster.demo.store
   serviceDiscoveryType eureka
   authenticationType jwt
   prodDatabaseType mysql
   buildTool maven
   clientFramework react
   enableSwaggerCodegen true
   testFrameworks [cypress]
 }
 entities *
}

application {
 config {
   baseName crm
   applicationType microservice
   packageName tech.jhipster.demo.crm
   serviceDiscoveryType eureka
   authenticationType jwt
   cacheProvider memcached
   prodDatabaseType postgresql
   buildTool maven
   serverPort 8081
   skipUserManagement true
 }
 entities *
}

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 Customer {
   firstName String required
   lastName String required
   gender Gender required
   email String required pattern(/[a-z0-9._+-]{1,20}@[a-z0-9]{3,15}\.[a-z]{2,4}/)
   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 String
}
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 ManyToOne {
OrderItem{product(name) required} to Product
}
relationship OneToMany {
  Customer{order} to ProductOrder{customer(email) required},
  ProductOrder{orderItem} to OrderItem{order(code) required}
}

service Product, 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
}
entity Shipment {
   trackingCode String
   date Instant required
   details String
}
enum PaymentMethod {
   CREDIT_CARD, CASH_ON_DELIVERY, PAYPAL
}
relationship OneToMany {
   Invoice{shipment} to Shipment{invoice(code) required}
}
service Invoice, Shipment with serviceClass
paginate Invoice, Shipment with pagination
microservice Customer, Product, ProductOrder, OrderItem, Invoice, Shipment with crm

// will be created under 'docker-compose' folder
deployment {
   deploymentType docker-compose
   appsFolders [store, crm]
   dockerRepositoryName "hipsterslabs"
   monitoring no
   serviceDiscoveryType eureka
}

// will be created under 'kubernetes' folder
deployment {
   deploymentType kubernetes
   appsFolders [store, crm]
   dockerRepositoryName "hipsterslabs"
   gatewayType SpringCloudGateway
   monitoring no
   serviceDiscoveryType eureka
   kubernetesNamespace jhipster
   kubernetesServiceType LoadBalancer
   istio false
}

I didn't put reactive to true because, it should be by default, when we choose gateway. So I think there is something related to the logic with memcached in our main generator-jhipster

pascalgrimaud commented 3 years ago

Just tried the JDL, and in fact, the store is reactive, so everything looks fine:

{
  "generator-jhipster": {
    "authenticationType": "jwt",
    "clientFramework": "react",
    "serverPort": "8080",
    "serviceDiscoveryType": "eureka",
    "skipUserManagement": false,
    "withAdminUi": true,
    "baseName": "store",
    "buildTool": "maven",
    "databaseType": "sql",
    "devDatabaseType": "h2Disk",
    "cacheProvider": "no",
    "enableHibernateCache": false,
    "enableSwaggerCodegen": true,
    "enableTranslation": true,
    "jhiPrefix": "jhi",
    "languages": ["en"],
    "messageBroker": false,
    "prodDatabaseType": "mysql",
    "searchEngine": false,
    "skipClient": false,
    "testFrameworks": ["cypress"],
    "websocket": false,
    "applicationType": "gateway",
    "packageName": "tech.jhipster.demo.store",
    "packageFolder": "tech/jhipster/demo/store",
    "jhipsterVersion": "7.0.0-beta.1",
    "skipServer": false,
    "clientPackageManager": "npm",
    "dtoSuffix": "DTO",
    "entitySuffix": "",
    "reactive": true,
    "clientTheme": "none",
    "clientThemeVariant": "",
    "skipCheckLengthOfIdentifier": false,
    "skipFakeData": false,
    "blueprints": [],
    "otherModules": [],
    "pages": [],
    "nativeLanguage": "en",
    "creationTimestamp": 1614667423566,
    "jwtSecretKey": "MzVlZWUyM2RjNzkxNWJhN2Y2M2ViNGNjMTcyMjBjZGM1OWNiYzMzZDRlNzc4MDU1ZTFiM2NkMTZiMDEwMmZiZWYzZDZhNzAwYjA4OTYxZDJmMTMwZTcwMjQ2ZjYzNDVmMzdlYjUwZjQ4OGRiYWVlZTc2NTZmZjgyNzY4MzExNWY=",
    "entities": ["Invoice", "Customer", "Shipment", "Product", "ProductOrder", "OrderItem"],
    "lastLiquibaseTimestamp": 1614667783000
  }
}
mraible commented 3 years ago

Wanna bet? I'm willing to wager a 6-pack of good Belgium beer that #14132 fixes it!

pascalgrimaud commented 3 years ago

I already put some :beers: in the generated code but it should be a secret :shushing_face:

mraible commented 3 years ago

Here's the error that seems to be causing the problem:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'memcachedCacheManager' defined in class path resource [tech/jhipster/demo/crm/config/CacheConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cache.CacheManager]: Factory method 'memcachedCacheManager' threw exception; nested exception is java.lang.IllegalArgumentException: A collection of caches cannot be empty or null
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:917)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:582)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:326)
    at tech.jhipster.demo.crm.CrmApp.main(CrmApp.java:69)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cache.CacheManager]: Factory method 'memcachedCacheManager' threw exception; nested exception is java.lang.IllegalArgumentException: A collection of caches cannot be empty or null
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
    ... 18 common frames omitted
Caused by: java.lang.IllegalArgumentException: A collection of caches cannot be empty or null
    at org.springframework.util.Assert.notEmpty(Assert.java:470)
    at com.google.code.ssm.spring.SSMCacheManager.setCaches(SSMCacheManager.java:118)
    at tech.jhipster.demo.crm.config.CacheConfiguration.memcachedCacheManager(CacheConfiguration.java:54)
    at tech.jhipster.demo.crm.config.CacheConfiguration$$EnhancerBySpringCGLIB$$ab2a2e80.CGLIB$memcachedCacheManager$1(<generated>)
    at tech.jhipster.demo.crm.config.CacheConfiguration$$EnhancerBySpringCGLIB$$ab2a2e80$$FastClassBySpringCGLIB$$d43f8eec.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
    at tech.jhipster.demo.crm.config.CacheConfiguration$$EnhancerBySpringCGLIB$$ab2a2e80.memcachedCacheManager(<generated>)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 19 common frames omitted
mraible commented 3 years ago

If I remove CacheConfiguration.java when it's a microservice with Memcached, it works.

mraible commented 3 years ago

You win this one @pascalgrimaud. I'm stumped.