Skip to content

Commit 3db232e

Browse files
author
Matt Raible
committed
Start demo script
1 parent a52b8ab commit 3db232e

File tree

1 file changed

+16
-342
lines changed

1 file changed

+16
-342
lines changed

jhipster-k8s/demo.adoc

Lines changed: 16 additions & 342 deletions
Original file line numberDiff line numberDiff line change
@@ -3,364 +3,38 @@
33
:commandkey: ⌘
44
:toc: macro
55

6-
== Reactive Java Microservices with JHipster Demo Steps
6+
// Why h2 vs h1?
77

8-
Today, I'd like to show you how to use the JHipster 7 to create a reactive Java microservices architecture with Spring Boot, Spring Cloud, Spring Cloud Gateway, and Spring WebFlux.
8+
= Kubernetes to the Cloud with JHipster Demo Steps
9+
10+
Today, I'd like to show you how to use JHipster 7 to create a reactive Java microservices architecture and deploy it to Google Cloud with Kubernetes.
911

1012
**Prerequisites:**
1113

12-
- https://adoptopenjdk.net/[Java 11]+
14+
- https://sdkman.io/[Java 11]+
1315
- https://nodejs.org/[Node 14]+
1416
- https://docs.docker.com/get-docker/[Docker]
1517

1618
toc::[]
1719

18-
=== Build a Reactive Java Microservices Architecture
19-
20-
In this demo, I'll show you how to generate a microservice architecture that uses OAuth 2.0, an API gateway, and two microservices (a blog and a store). The gateway will use PostgreSQL with R2DBC, the blog will use Neo4j, and the store will use MongoDB.
21-
22-
. Install JHipster 7:
23-
+
24-
[source,shell]
25-
----
26-
npm i -g generator-jhipster@7
27-
----
28-
29-
. Create a directory called `reactive-stack` and initialize `git`.
30-
+
31-
[source,shell]
32-
----
33-
take reactive-stack # mkdir reactive-stack && cd reactive-stack
34-
git init # initialize git, so apps aren't created with their own .git
35-
----
36-
37-
. Use the JDL below to define your architecture and apps.
38-
+
39-
====
40-
----
41-
application {
42-
config {
43-
baseName gateway // <1>
44-
reactive true // <2>
45-
packageName com.okta.developer.gateway
46-
applicationType gateway
47-
authenticationType oauth2 // <3>
48-
buildTool gradle // <4>
49-
clientFramework vue // <5>
50-
prodDatabaseType postgresql
51-
serviceDiscoveryType eureka
52-
testFrameworks [cypress] // <6>
53-
}
54-
entities Blog, Post, Tag, Product
55-
}
56-
57-
application {
58-
config {
59-
baseName blog
60-
reactive true
61-
packageName com.okta.developer.blog
62-
applicationType microservice // <7>
63-
authenticationType oauth2
64-
buildTool gradle
65-
databaseType neo4j
66-
devDatabaseType neo4j
67-
prodDatabaseType neo4j
68-
enableHibernateCache false
69-
serverPort 8081
70-
serviceDiscoveryType eureka
71-
}
72-
entities Blog, Post, Tag
73-
}
74-
75-
application {
76-
config {
77-
baseName store
78-
reactive true
79-
packageName com.okta.developer.store
80-
applicationType microservice
81-
authenticationType oauth2
82-
buildTool gradle
83-
databaseType mongodb
84-
devDatabaseType mongodb
85-
prodDatabaseType mongodb
86-
enableHibernateCache false
87-
serverPort 8082
88-
serviceDiscoveryType eureka
89-
}
90-
entities Product
91-
}
92-
93-
entity Blog {
94-
name String required minlength(3)
95-
handle String required minlength(2)
96-
}
97-
98-
entity Post {
99-
title String required
100-
content TextBlob required
101-
date Instant required
102-
}
103-
104-
entity Tag {
105-
name String required minlength(2)
106-
}
107-
108-
entity Product {
109-
title String required
110-
price BigDecimal required min(0)
111-
image ImageBlob
112-
}
113-
114-
relationship ManyToOne {
115-
Blog{user(login)} to User
116-
Post{blog(name)} to Blog
117-
}
118-
119-
relationship ManyToMany {
120-
Post{tag(name)} to Tag{post}
121-
}
122-
123-
paginate Post, Tag with infinite-scroll
124-
paginate Product with pagination
125-
126-
microservice Product with store
127-
microservice Blog, Post, Tag with blog
128-
129-
deployment { // <8>
130-
deploymentType docker-compose
131-
appsFolders [gateway, blog, store]
132-
dockerRepositoryName "mraible"
133-
}
134-
----
135-
<.> The first app is an API gateway.
136-
<.> Because the gateway is reactive, it'll use Spring Cloud Gateway.
137-
<.> The gateway and microservice apps must use the same authentication type.
138-
<.> Use Gradle, because a lot of y'all love it.
139-
<.> Vue support is new in JHipster 7, let's use it!
140-
<.> JHipster 7 supports Cypress! It seems to be more reliable than Protractor.
141-
<.> Make sure and specify `microservice` as the application type for the blog and store apps.
142-
<.> JDL allows you to create Docker Compose and Kubernetes deployments too!
143-
====
144-
+
145-
TIP: You can find additional JDL samples on GitHub in the https://github.com/jhipster/jdl-samples[jdl-samples repository].
146-
147-
. Import this architecture definition and generate `gateway`, `blog`, and `store` apps.
148-
+
149-
[source,shell]
150-
----
151-
jhipster jdl reactive-ms.jdl
152-
----
153-
+
154-
As part of this process, several Docker Compose files are generated for you. These allow you to run databases, the https://www.jhipster.tech/jhipster-registry/[JHipster Registry] (for service discovery), https://www.keycloak.org/[Keycloak] (for identity), all with Docker.
155-
156-
=== Run Your Reactive Java Microservices
157-
158-
. Open a terminal and run the following commands to start Keycloak, PostgreSQL, and the JHipster Registry.
159-
+
160-
[source,shell]
161-
----
162-
cd gateway
163-
docker-compose -f src/main/docker/keycloak.yml up -d #jhkeycloakup
164-
docker-compose -f src/main/docker/postgresql.yml up -d #jhpostgresqlup
165-
docker-compose -f src/main/docker/jhipster-registry.yml up -d #jhregistryup
166-
./gradlew
167-
----
168-
+
169-
TIP: JHipster has a https://www.jhipster.tech/oh-my-zsh/[Oh My ZSH! plugin] that I highly recommend. It provides aliases for starting Docker containers and is a real time-saver. I've included these commands as comments above.
170-
171-
. Open a new terminal window, start the blog app's Neo4j database, and then the app itself.
172-
+
173-
[source,shell]
174-
----
175-
cd ../blog
176-
docker-compose -f src/main/docker/neo4j.yml up -d #jhneo4jup
177-
./gradlew
178-
----
179-
180-
. Open another terminal window, start the store app's MongoDB database, and the microservice.
181-
+
182-
[source,shell]
183-
----
184-
cd ../store
185-
docker-compose -f src/main/docker/mongodb.yml up -d #jhmongoup
186-
./gradlew
187-
----
188-
+
189-
[CAUTION]
190-
====
191-
To make Keycloak work, you need to add the following line to your hosts file (`/etc/hosts` on Mac/Linux, `c:\Windows\System32\Drivers\etc\hosts` on Windows).
192-
193-
----
194-
127.0.0.1 keycloak
195-
----
196-
197-
This is because you will access your application with a browser on your machine (which is named localhost, or `127.0.0.1`), but inside Docker, it will run in its own container, which is named `keycloak`.
198-
====
199-
200-
. Open `http://localhost:8080` in your favorite browser. You should be able to login with `admin/admin` as credentials.
201-
202-
. To prove everything works, you can run `npm run e2e` in the gateway project's directory. This will run a number of end-to-end tests with https://www.cypress.io/[Cypress].
203-
204-
=== Prepare Your Reactive Java Stack for Production
205-
206-
Keycloak is a superb open source identity provider. It has excellent support for OAuth 2.0 and OpenID Connect (OIDC) and easily runs in a Docker container. I greatly appreciate Keycloak's ease-of-use. I also ❤️ Spring Security's OAuth and OIDC support.
207-
208-
Spring Security makes it so you only need to override three properties to switch from Keycloak to Okta!
209-
210-
Spring Cloud Gateway makes it easy to relay an access token between a gateway and microservices. It's just five lines of YAML:
211-
212-
[source,yaml]
213-
----
214-
spring:
215-
cloud:
216-
gateway:
217-
default-filters:
218-
- TokenRelay
219-
----
220-
221-
. Install the https://cli.okta.com[Okta CLI] and run `okta register`.
222-
223-
. In the gateway project's directory, run the command below. Accept the default redirect URIs.
224-
+
225-
[source,shell]
226-
----
227-
okta apps create jhipster
228-
----
229-
230-
==== Update the JHipster Registry to Distribute OIDC Configuration
231-
232-
Spring Cloud Config allows you to distribute Spring's configuration between apps. In this section, you'll configure JHipster's Spring Security settings to use Okta across all your services.
233-
234-
. Add the following YAML to `gateway/src/main/docker/central-server-config/localhost-config/application.yml`. You can find the values for each property in the `.okta.env` file.
235-
+
236-
[source,yaml]
237-
----
238-
spring:
239-
security:
240-
oauth2:
241-
client:
242-
provider:
243-
oidc:
244-
issuer-uri: https://<your-okta-domain>/oauth2/default
245-
registration:
246-
oidc:
247-
client-id: <client-id>
248-
client-secret: <client-secret>
249-
----
250-
251-
. Save your changes and restart the JHipster Registry:
252-
+
253-
[source,shell]
254-
----
255-
jhregistrydown
256-
jhregistryup
257-
----
258-
259-
. Use kbd:[Ctrl + C] to kill all your `./gradlew` processes and start them again.
260-
261-
. Open an incognito window, go to `http://localhost:8080`, and sign in. Rejoice that using Okta for authentication works!
262-
263-
. If you're feeling lucky, you can set your Okta credentials as environment variables and run end-to-end tests (from the `gateway` directory).
264-
+
265-
[source,shell]
266-
----
267-
export CYPRESS_E2E_USERNAME=<your-username>
268-
export CYPRESS_E2E_PASSWORD=<your-password>
269-
npm run e2e
270-
----
271-
272-
=== Create Docker Images for Your Microservice Apps
273-
274-
. Stop all your apps with kbd:[Ctrl + C]. Stop all your Docker instances too.
275-
+
276-
[source,shell]
277-
----
278-
docker stop $(docker ps -a -q)
279-
----
280-
+
281-
TIP: Bump up the memory and CPU that Docker uses in Docker > Preferences > Resources. I have my Docker preferences set to 6 CPUs and 12GB of RAM.
282-
283-
. To run your reactive stack with Docker Compose, you need to create Docker images for each app. In your three different app directories, run the following Gradle command:
284-
+
285-
[source,shell]
286-
----
287-
./gradlew -Pprod bootJar jibDockerBuild
288-
----
289-
290-
=== Run Your Microservices Stack with Docker Compose
291-
292-
Once your Docker containers are finished building, you'll want to add your Okta settings to Spring Cloud Config in JHipster Registry.
293-
294-
. Open `docker-compose/docker-compose.yml` in your favorite IDE and remove the Keycloak image at the bottom. You can leave it if you like, but it won't be used in this example.
295-
296-
. Update `docker-compose/central-server-config/application.yml` to contain your OIDC settings that you want to share with all your microservices.
297-
+
298-
[source,yaml]
299-
----
300-
spring:
301-
security:
302-
oauth2:
303-
client:
304-
provider:
305-
oidc:
306-
issuer-uri: https://<your-okta-domain>/oauth2/default
307-
registration:
308-
oidc:
309-
client-id: <client-id>
310-
client-secret: <client-secret>
311-
----
312-
313-
. In the `docker-compose` directory, run the following command to start all your containers.
314-
+
315-
[source,shell]
316-
----
317-
docker-compose up
318-
----
319-
320-
. Open `http://localhost:8080`, sign in, and access all of your microservices. Pretty slick, eh?! 🤓
321-
322-
== What About Kotlin Microservices?
323-
324-
JHipster supports Kotlin-based microservices thanks to its https://github.com/jhipster/jhipster-kotlin[Kotlin blueprint], supported by https://github.com/sendilkumarn[Sendil Kumar N].
325-
326-
You can install it using npm:
327-
328-
[source,shell]
329-
----
330-
npm install -g generator-jhipster-kotlin
331-
----
332-
333-
Then, use `khipster jdl reactive-ms` to create the same stack you did above with Kotlin.
334-
335-
NOTE: At the time of this writing, JHipster's Kotlin blueprint doesn't support JHipster 7. Watch the https://github.com/jhipster/jhipster-kotlin/releases[project's releases page] for updates.
336-
337-
== How Do I Deploy to the Cloud?
338-
339-
JHipster creates a cloud-native microservices architecture that can be deployed to many cloud providers. There's specific support for AWS, Microsoft Azure, Heroku, and Google Cloud Platform.
340-
341-
However, if you're doing microservices, you'll probably want to leverage Docker as you did in this tutorial. When your apps are containerized, they can be orchestrated with Kubernetes.
342-
343-
JHipster has a https://www.jhipster.tech/kubernetes/[Kubernetes] sub-generator that you can use to deploy it to the cloud. I'll cover this in a future demo.
20+
== Create a Kubernetes-Ready Microservices Architecture
34421

345-
In the meantime, you can watch a presentation that https://twitter.com/saturnism[Ray Tsang] and I did recently that shows how to deploy JHipster microservices with Kubernetes. If you start watching from https://youtu.be/AG4z18qePEw?t=2778[46:18], you'll see Ray show how to deploy to Google Cloud using Kubernetes.
22+
== Generate Kubernetes Deployment Descriptors
34623

347-
++++
348-
<div style="text-align: center; margin-bottom: 1.25rem">
349-
<iframe width="700" height="394" src="https://www.youtube.com/embed/AG4z18qePEw" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
350-
</div>
351-
++++
24+
== Install Minikube to Run Kubernetes Locally
35225

353-
== Should You Go Reactive?
26+
== Create Docker Images
35427

355-
As with most software architecture decisions, it depends. Are you building CRUD apps? Then no, Spring MVC is good enough.
28+
== Register an OIDC App for Auth
35629

357-
Are you dealing with massive amounts of steaming data and millions of customers? Then yes, reactive frameworks like Spring WebFlux might just save you $$$ on your monthly cloud bill.
30+
== Encrypt / Decrypt Your Spring Cloud Configuration
35831

359-
What about https://wiki.openjdk.java.net/display/loom/Main[Project Loom]? Will it allow you to write regular non-reactive code that performs as good as reactive frameworks? I'm not sure. I'm betting on reactive for now. I think it's a good skill to have for Java developers.
32+
== Deploy to Google Cloud (aka GCP)
36033

361-
== Stay Hip with JHipster!
34+
== Encrypt Kubernetes Secrets
36235

363-
⛑ Find the code on GitHub: https://github.com/oktadeveloper/java-microservices-examples/tree/main/reactive-jhipster[@oktadeveloper/java-microservices-examples/reactive-jhipster].
36+
== Scale Your JHipster Microservices
36437

365-
👀 Read the blog post: https://developer.okta.com/blog/2021/01/20/reactive-java-microservices[Reactive Java Microservices with Spring Boot and JHipster].
38+
== Monitor Your Kubernetes Cluster with K9s and KDash
36639

40+
== Learn More About Java Microservices and Kubernetes

0 commit comments

Comments
 (0)