在30分钟内使用JHipster域语言创建完整的微服务堆栈

Øriginally published in deepu.tech.

It’s been quite a while since I wrote a blog, I did a few some years ago but never really continued writing. So when I decided to start writing again, I didn’t have to think a lot about a topic as it was very obvious — JHipster.

JHipster is a development platform for Java web applications and microservices development. If you are a JVM developer you might have already heard about ĴHipster. If not, well, you are missing out on a lot and I highly recommend you check it out. You can also check out my book “Full Stack Development with ĴHipster” on Amazon and Packt to learn about JHipster.

I have been working on JHipster from April 2015 and the coolest feature that I got to implement so far is definitely multiple applications generation using JDL. This feature is available in the latest version of JHipster. If you are not familiar with JDL, I recommend you to check out the docs at https://www.jhipster.tech/jdl/

The E-Commerce application

因此,让我们看看如何使用JHipster创建微服务堆栈。 今天我们将建立一个电子商务商店。 堆栈包括-

  • Service discovery using JHipster Registry, a Spring boot application that packs Eureka server and Spring cloud config server.

  • API management and Gateway using Spring Boot, Netflix Zuul, ReactJS, and Swagger.

  • Microservices using Spring Boot.

  • Monitoring using JHipster Console which is made of the Elastic stack(ELK) and Zipkin.

Microservice application architecture中号icroservice application architecture

网关将传入的请求路由到两个微服务,发票应用程序和通知应用程序。

Requirements

为了遵循本教程,您需要使用最新版本的码头工人,码头工人-compose,节点JS和爪哇安装在您的计算机上。 以下是我已安装的版本(更新资料: With JHipster 6+ you can use 爪哇 11 & 12).

$ docker -v                                                                                                                       
Docker version 18.06.1-ce, build e68fc7a

$ docker-compose -v                                
docker-compose version 1.20.1, build 5d8c71b

$ node -v                
v8.11.4

$ java -version          
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (Zulu 8.38.0.13-CA-linux64) (build 1.8.0_212-b04)
OpenJDK 64-Bit Server VM (Zulu 8.38.0.13-CA-linux64) (build 25.212-b04, mixed mode)

首先,安装最新版本的JHipster

$ npm install generator-jhipster -g

确认您有版本5.3.4或以上跑步

$ jhipster --version

Creating the JDL

Now let us create our JDL. Head over to the JDL Studio or your favorite IDE/Editor(You can use JHipster IDE plugin if you like).

首先,让我们定义应用程序。 我们将从网关开始

application {
  config {
    baseName store,
    applicationType gateway,
    packageName com.jhipster.demo.store,
    serviceDiscoveryType eureka,
    authenticationType jwt,
    prodDatabaseType mysql,
    cacheProvider hazelcast,
    buildTool gradle,
    clientFramework react,
    testFrameworks [protractor]
  }
  entities *
}

大多数选项都是不言自明的,我们正在构建一个名为商店类型网关与智威汤逊认证和尤里卡基于服务的发现。 该应用程序使用的MySQL数据库和淡褐色用于缓存。 它是使用摇篮。 对于客户端,它使用反应和萨斯。 它也有量角器用于端到端测试。

在定义的最后,您可以看到实体*,我们稍后再讨论。

现在让我们定义发票微服务

application {
  config {
    baseName invoice,
    applicationType microservice,
    packageName com.jhipster.demo.invoice,
    serviceDiscoveryType eureka,
    authenticationType jwt,
    prodDatabaseType mysql,
    buildTool gradle,
    serverPort 8081
  }
  entities Invoice, Shipment
}

它遵循与我们的网关类似的选项,并且由于它是微服务,因此它没有定义任何客户端选项,并且跳过了由网关处理的用户管理。 此外,我们还提到了自定义端口8081因为我们不希望该应用程序与网关使用的默认端口8080冲突。

现在让我们定义第二个微服务,即Notification应用程序

application {
  config {
    baseName notification,
    applicationType microservice,
    packageName com.jhipster.demo.notification,
    serviceDiscoveryType eureka,
    authenticationType jwt,
    databaseType mongodb,
    cacheProvider no,
    enableHibernateCache false,
    buildTool gradle,
    serverPort 8082
  }
  entities Notification
}

该应用程序遵循许多类似于“网关和发票”应用程序的选项,但是它使用的不是MySQL,而是MongoDB作为其数据库,并禁用缓存。

现在我们的应用程序定义已经完成,我们将继续定义实体模型。

对于我们的网关商店应用程序,让我们定义以下实体和枚举

/** Product sold by the Online store */
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 {
    Customer{order} to ProductOrder{customer(email) required},
    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

JDL定义了实体,枚举,实体之间的关系以及诸如分页和服务层之类的选项。

实体字段定义遵循以下语法

entity <entity name> {
  <field name> <type> [<validation>*]
}

关系定义遵循语法

relationship (OneToMany | ManyToOne | OneToOne | ManyToMany) {
    <from entity>[{<relationship name>[(<display field>)]}] 
    to 
    <to entity>[{<relationship name>[(<display field>)]}]
}

Refer the JDL docs for full DSL reference.

发票微服务应用程序具有以下实体

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 Invoice, Shipment with invoice

注意最后微服务 option declared here, it specifies that these entities belong to the 微服务 named 发票以便我们的网关知道将这些实体的请求路由到何处。

现在让我们查看Notification微服务应用程序的实体

entity Notification {
    date Instant required
    details String
    sentDate Instant required
    format NotificationType required
    userId Long required
    productId Long required
}

enum NotificationType {
    EMAIL, SMS, PARCEL
}

microservice Notification with notification

现在,让我们回到在应用程序定义中使用的entity关键字。

application {
  config {
    ...
  }
  entities *
}

application {
  config {
    ...
  }
  entities Invoice, Shipment
}

application {
  config {
    ...
  }
  entities Notification
}

/* Entities for Store Gateway */

entity Product {
    ...
}

entity ProductCategory {
    ...
}

entity Customer {
    ...
}

entity ProductOrder {
    ...
}

entity OrderItem {
    ...
}

microservice Invoice, Shipment with invoice

/* Entities for Invoice microservice */
entity Invoice {
    ...
}

entity Shipment {
    ...
}

/* Entities for notification microservice */

entity Notification {
    ...
}

microservice Notification with notification

在这里,我们指示商店网关应用程序应包含JDL中定义的所有实体,并且网关将知道跳过属于另一个微服务的实体的服务器端代码,因此将仅为这些微服务生成客户端代码, 在这里发票,装船,and 通知. We also instruct the 发票 application and 通知 application to include its entities.

Generating the applications

在我们要创建微服务堆栈的位置创建一个文件夹。

$ mkdir ecommerce && cd ecommerce

现在,让我们将所有内容放到一个JDL文件中。 让我们称之为app.jdl并将其保存到此文件夹中。

application {
  config {
    baseName store,
    applicationType gateway,
    packageName com.jhipster.demo.store,
    serviceDiscoveryType eureka,
    authenticationType jwt,
    prodDatabaseType mysql,
    cacheProvider hazelcast,
    buildTool gradle,
    clientFramework react,
    testFrameworks [protractor]
  }
  entities *
}

application {
  config {
    baseName invoice,
    applicationType microservice,
    packageName com.jhipster.demo.invoice,
    serviceDiscoveryType eureka,
    authenticationType jwt,
    prodDatabaseType mysql,
    buildTool gradle,
    serverPort 8081
  }
  entities Invoice, Shipment
}

application {
  config {
    baseName notification,
    applicationType microservice,
    packageName com.jhipster.demo.notification,
    serviceDiscoveryType eureka,
    authenticationType jwt,
    databaseType mongodb,
    cacheProvider no,
    enableHibernateCache false,
    buildTool gradle,
    serverPort 8082
  }
  entities Notification
}

/* Entities for Store Gateway */

/** Product sold by the Online store */
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 {
   Customer{order} to ProductOrder{customer(email) required},
   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
}

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 Invoice, Shipment with invoice

/* Entities for notification microservice */

entity Notification {
    date Instant required
    details String
    sentDate Instant required
    format NotificationType required
    userId Long required
    productId Long required
}

enum NotificationType {
    EMAIL, SMS, PARCEL
}

microservice Notification with notification

现在让我们调用JHipster CLI导入该文件

$ jhipster import-jdl app.jdl

这将创建商店,发票和通知 folders和will do the below in each of the folders

  • 生成适当的应用程序和实体配置。根据配置生成应用程序和实体源代码。为应用程序安装NPM依赖项。

该过程完成后,您应该在控制台上看到以下内容

Entity Product generated successfully.
Entity ProductCategory generated successfully.
Entity Customer generated successfully.
Entity ProductOrder generated successfully.
Entity OrderItem generated successfully.
Entity Invoice generated successfully.
Entity Shipment generated successfully.
Entity Notification generated successfully.
Congratulations, JHipster execution is complete!

遍历生成的代码以熟悉您自己。

Running the applications with Docker

现在,我们的应用程序已经创建,可以使用Docker在本地对其进行测试了。 首先,我们使用JHipster生成一些docker compose配置。

在内部创建一个新文件夹电子商务文件夹并运行JHipster docker-compose命令

$ mkdir docker-compose && cd docker-compose
$ jhipster docker-compose

它将提示您一些问题,选择以下突出显示的答案

🐳  Welcome to the JHipster Docker Compose Sub-Generator 🐳
Files will be generated in folder: /home/deepu/workspace/temp/ecommerce/docker-compose
✔ Docker is installed

? Which *type* of application would you like to deploy? Microservice application

? Which *type* of gateway would you like to use? JHipster gateway based on Netflix Zuul

? Enter the root directory where your gateway(s) and microservices are located ../

3 applications found at /home/deepu/workspace/temp/ecommerce/
? Which applications do you want to include in your configuration? invoice, notification, store

? Which applications do you want to use with clustered databases (only available with MongoDB and Couchbase)? 

? Do you want to setup monitoring for your applications ? Yes, for logs and metrics with the JHipster Console (based on ELK and Zipkin)

? You have selected the JHipster Console which is based on the ELK stack and additional technologies, which one do you want to use ? Zipkin, for distributed tracing (only compatible with
 JHipster >= v4.2.0)

JHipster registry detected as the service discovery and configuration provider used by your apps
? Enter the admin password used to secure the JHipster Registry? admin

这将为堆栈生成所有必需的docker-compose配置,还将打印出进一步的指令以构建docker映像。

ñote: In the latest JHipster versions we migrated to using Jib for creating Docker images. This is a huge improvement over the Docker Maven plugin that we were using, as a result the command to create an image has changed to ./gradlew -Pprod bootWar jibDockerBuild.

Docker Compose configuration generated with missing images!
To generate the missing Docker image(s), please run:
  ./gradlew -Pprod bootWar jibDockerBuild in /home/deepu/workspace/temp/ecommerce/invoice
  ./gradlew -Pprod bootWar jibDockerBuild in /home/deepu/workspace/temp/ecommerce/notification
  ./gradlew -Pprod bootWar jibDockerBuild in /home/deepu/workspace/temp/ecommerce/store

按照说明构建docker镜像。 构建完所有3张图片后,请从码头工人组成文件夹来启动所有内容。

$ docker-compose up -d

容器启动后,您可以使用以下命令流式传输日志

$ docker-compose logs -f

Now point your favorite browser to http://localhost:8080/ and see the E-Commerce microservice application in action.

Gateway application(Store)Gateway application(Store)

You can see the JHipster registry in action at http://localhost:8761/

JHipster RegistryĴHipster Registry

And finally the JHipster console at http://localhost:5601/

JHipster Console- Kibana dashboardĴHipster Console- Kibana dashboard

玩完之后,您可以通过在码头工人组成夹

docker-compose down

Hope you had fun creating microservices using JHipster. To learn how to convert a JHipster monolith to microservices check out my book “Full Stack Development with JHipster” on Amazon and Packt.

在接下来的几周中,我将撰写一些有关将微服务栈部署到GCP,Azure,AWS,Heroku等各种云提供商的文章。

If you like JHipster don't forget to give it a star on Github.

如果您喜欢这篇文章,请留下喜欢或评论。

You can follow me on Twitter and LinkedIn.

我的其他相关文章:

  1. Deploying JHipster Microservices on Azure Kubernetes Service (AKS)

  2. JHipster microservices with Istio service mesh on Kubernetes

Originally published in Medium on Sep 22, 2018

from: https://dev.to//deepu105/create-full-microservice-stack-using-jhipster-domain-language-under-30-minutes-4ele

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值