Tạo ứng dụng Kotlin Spring thông qua Google Cloud Platform

1. Giới thiệu

Spring Framework 5.0 đã thêm dịch vụ hỗ trợ chuyên dụng cho Kotlin, giúp các nhà phát triển Kotlin dễ dàng sử dụng Spring. Do đó, những thay đổi này đồng nghĩa với việc các công cụ tích hợp của Google Cloud do Spring Cloud GCP cung cấp cũng hoạt động liền mạch trong Kotlin. Trong lớp học lập trình này, bạn sẽ thấy việc bắt đầu sử dụng các dịch vụ của Google Cloud trong ứng dụng Kotlin dễ dàng như thế nào!

Lớp học lập trình này hướng dẫn cách thiết lập một ứng dụng đăng ký đơn giản trong Kotlin, ứng dụng này minh hoạ cách sử dụng các dịch vụ của GCP, bao gồm: Cloud Pub/SubCloud SQL.

Sản phẩm bạn sẽ tạo ra

Trong lớp học lập trình này, bạn sẽ thiết lập ứng dụng Kotlin Spring Boot, chấp nhận thông tin của người đăng ký, xuất bản ứng dụng này lên một chủ đề trên Cloud Pub/Sub, đồng thời duy trì ứng dụng này trong cơ sở dữ liệu Cloud MySQL.

Kiến thức bạn sẽ học được

Cách tích hợp với các dịch vụ của Google Cloud trong ứng dụng Kotlin Spring.

Bạn cần có

  • Một dự án trên Google Cloud Platform
  • Một trình duyệt, chẳng hạn như Chrome hoặc Firefox

Bạn sẽ dùng hướng dẫn này như thế nào?

Chỉ có thể đọc Đọc và hoàn thành bài tập

Bạn đánh giá thế nào về kinh nghiệm xây dựng ứng dụng web HTML/CSS?

Người mới tập Trung cấp Thành thạo

Bạn đánh giá trải nghiệm sử dụng các dịch vụ của Google Cloud Platform như thế nào?

Người mới tập Trung cấp Thành thạo

2. Thiết lập và yêu cầu

Thiết lập môi trường theo tiến độ riêng

  1. Đăng nhập vào Cloud Console rồi tạo dự án mới hoặc sử dụng lại dự án hiện có. (Nếu chưa có tài khoản Gmail hoặc G Suite, bạn phải tạo một tài khoản.)

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

Xin lưu ý rằng mã dự án là một tên riêng biệt trong tất cả dự án Google Cloud (tên ở trên đã được sử dụng nên sẽ không phù hợp với bạn!). Lớp này sẽ được đề cập sau trong lớp học lập trình này là PROJECT_ID.

  1. Tiếp theo, bạn sẽ cần bật tính năng thanh toán trong Cloud Console để sử dụng tài nguyên của Google Cloud.

Việc chạy qua lớp học lập trình này sẽ không tốn nhiều chi phí. Hãy nhớ làm theo mọi hướng dẫn trong phần "Dọn dẹp" sẽ tư vấn cho bạn cách tắt tài nguyên để bạn không phải chịu thanh toán ngoài hướng dẫn này. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí 300 USD.

Google Cloud Shell

Mặc dù bạn có thể vận hành Google Cloud từ xa trên máy tính xách tay, nhưng trong lớp học lập trình này, chúng ta sẽ sử dụng Google Cloud Shell, một môi trường dòng lệnh chạy trong Đám mây.

Kích hoạt Cloud Shell

  1. Trong Cloud Console, hãy nhấp vào Kích hoạt Cloud Shell H7JlbhKGHITmsxhQIcLwoe5HXZMhDlYue4K-SPszMxUxDjIeWfOHBfxDHYpmLQTzUmQ7Xx8o6OJUlANnQF0iBuyFP1RzVad_4nCa0Zszrz5LtwQZZ.

zlNW0HehB_AFW1qZ4AyebSQUdWm95n7TbnOr7UVm3j9dFcg6oWApJRlC0jnU1Mvb-IQp-trP1Px8xKNwt6o3pP6fyih947sEhOFI4IRF0W7WZk6hFqZDUGXQQXrw21GuMm2ecHrbzQ

Nếu trước đây chưa từng khởi động Cloud Shell, bạn sẽ được trình bày một màn hình trung gian (dưới màn hình đầu tiên) mô tả về ứng dụng này. Nếu trường hợp đó xảy ra, hãy nhấp vào Tiếp tục (và bạn sẽ không thấy thông báo đó nữa). Màn hình một lần đó sẽ có dạng như sau:

kEPbNAo_w5C_pi9QvhFwWwky1cX8hr_xEMGWySNIoMCdi-Djx9AQRqWn-__DmEpC7vKgUtl-feTcv-wBxJ8NwzzAp7mY65-fi2LJo4twUoewT1SUjd6Y3h81RG3rKIkqhoVlFR-G7w

Quá trình cấp phép và kết nối với Cloud Shell chỉ mất vài phút.

pTv5mEKzWMWp5VBrg2eGcuRPv9dLInPToS-mohlrqDASyYGWnZ_SwE-MzOWHe76ZdCSmw0kgWogSJv27lrQE8pvA5OD6P1I47nz8vrAdK7yR1NseZKJvcxAZrPb8wRxoqyTpD-gbhA

Máy ảo này chứa tất cả các công cụ phát triển mà bạn cần. Dịch vụ này cung cấp thư mục gốc 5 GB ổn định và chạy trong Google Cloud, giúp nâng cao đáng kể hiệu suất và khả năng xác thực của mạng. Trong lớp học lập trình này, đa số mọi người đều có thể thực hiện chỉ bằng một trình duyệt hoặc Chromebook.

Sau khi kết nối với Cloud Shell, bạn sẽ thấy mình đã được xác thực và dự án đã được đặt thành mã dự án.

  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng bạn đã được xác thực:
gcloud auth list

Kết quả lệnh

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

Kết quả lệnh

[core]
project = <PROJECT_ID>

Nếu chưa, bạn có thể thiết lập chế độ này bằng lệnh sau:

gcloud config set project <PROJECT_ID>

Kết quả lệnh

Updated property [core/project].

3. Cung cấp tài nguyên Pub/Sub

Trước tiên, chúng ta cần thiết lập một chủ đề và gói thuê bao Cloud Pub/Sub. Trong ứng dụng này, chúng tôi sẽ phát hành thông tin đăng ký theo một chủ đề Pub/Sub; thông tin sau đó được đọc từ chủ đề này và được lưu trữ trong cơ sở dữ liệu.

Trong hướng dẫn này, chúng ta sẽ dựa vào Cloud Shell để cung cấp tài nguyên. Xin lưu ý rằng bạn cũng có thể định cấu hình tài nguyên Pub/Sub thông qua phần Cloud Pub/Sub trong Google Cloud Console.

Trong thiết bị đầu cuối Cloud Shell, trước tiên hãy bật Pub/Sub API.

$ gcloud services enable pubsub.googleapis.com

Tiếp theo, chúng ta sẽ tạo một chủ đề Pub/Sub có tên là registrations cho ứng dụng này. Thông tin đăng ký gửi qua ứng dụng sẽ được xuất bản lên chủ đề này.

$ gcloud pubsub topics create registrations

Cuối cùng, hãy tạo một gói thuê bao cho chủ đề này. Khi đăng ký tài khoản Pub/Sub, bạn có thể nhận thông báo về một chủ đề.

$ gcloud pubsub subscriptions create registrations-sub --topic=registrations

Hiện tại, bạn đã hoàn tất việc tạo một chủ đề và gói đăng ký Cloud Pub/Sub cho ứng dụng của mình.

4. Tạo một thực thể và cơ sở dữ liệu Cloud SQL (MySQL)

Đối với ứng dụng mẫu, chúng ta cũng cần thiết lập một thực thể cơ sở dữ liệu để lưu giữ thông tin của người đăng ký. Bước này cũng sẽ dựa vào thiết bị đầu cuối Cloud Shell để cấp phép các tài nguyên Cloud SQL. Xin lưu ý rằng bạn cũng có thể xem và định cấu hình các thực thể Cloud SQL thông qua Google Cloud Console.

Trước tiên, hãy bật API Quản trị của Cloud SQL.

$ gcloud services enable sqladmin.googleapis.com

Tiếp theo, chúng ta sẽ cung cấp một thực thể Cloud SQL (MySQL). Lệnh này có thể mất chút thời gian.

$ gcloud sql instances create codelab-instance --region=us-east1

Sau khi bạn tạo thành công phiên bản Cloud SQL, hãy tạo một cơ sở dữ liệu mới trong thực thể đó có tên là registrants.

$ gcloud sql databases create registrants --instance codelab-instance

Hiện tại, bạn đã hoàn tất việc thiết lập phiên bản và cơ sở dữ liệu của Cloud SQL cho ứng dụng của mình.

5. Khởi chạy ứng dụng Spring Boot

Bây giờ, chúng ta đã sẵn sàng để bắt đầu viết đơn đăng ký. Các bước tiếp theo sẽ tiếp tục sử dụng Cloud Shell được mô tả trong các bước thiết lập.

Trước tiên, chúng ta sẽ sử dụng Initializr để tạo mã scaffolding cho dự án. Trong cửa sổ Cloud Shell, hãy chạy:

$ cd ~
$ curl https://start.spring.io/starter.tgz \
  -d language=kotlin \
  -d bootVersion=2.4.0 \
  -d dependencies=web,data-jpa,integration,cloud-gcp-pubsub,thymeleaf \
  -d baseDir=registrations-codelab | tar -xzvf -
$ cd registrations-codelab

Lệnh này sẽ tạo một chế độ thiết lập dự án Maven ban đầu cũng như mã khung (scaffolding) cho ứng dụng của bạn trong thư mục registrations-codelab/. Các phần sau đây mô tả các chỉnh sửa mã cần thiết để tạo một ứng dụng hoạt động.

Trình soạn thảo mã Cloud Shell

Cách dễ nhất để bắt đầu sửa đổi và xem mã trong môi trường Cloud Shell là sử dụng Trình chỉnh sửa mã Cloud Shell tích hợp sẵn.

Sau khi mở một thực thể Cloud Shell, hãy nhấp vào biểu tượng Bút chì để mở trình soạn thảo mã. Trình chỉnh sửa sẽ cho phép bạn sửa đổi trực tiếp các tệp dự án do initialzr tạo ra.

cce293b40119c37b.png

6. Cấu hình cơ sở dữ liệu

Trước tiên, hãy định cấu hình ứng dụng của bạn để ứng dụng có thể kết nối với cơ sở dữ liệu Cloud MySQL mà bạn thiết lập. Các thư viện của Spring Cloud GCP có cung cấp một điều kiện khởi động Cloud MySQL, cung cấp các phần phụ thuộc cần thiết để kết nối với một phiên bản Cloud MySQL.

Thêm phần phụ thuộc spring-cloud-gcp-starter-sql-mysql vào dự án pom.xml:

registrations-codelab/pom.xml

...
<dependencies>

  ... Other dependencies above ...

  <!-- Add the MySQL starter to the list of dependencies -->
  <dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>spring-cloud-gcp-starter-sql-mysql</artifactId>
  </dependency>
</dependencies>

Ngoài ra, bạn cần sửa đổi tệp cấu hình application.properties để mô tả cấu hình cơ sở dữ liệu. Sao chép các thuộc tính sau vào tệp application.properties.

Tìm tên kết nối thực thể với cơ sở dữ liệu của bạn:

$ gcloud sql instances describe codelab-instance \
  --format 'value(connectionName)'

Dữ liệu đầu ra của lệnh này sẽ được dùng trong tệp application.properties để định cấu hình thông tin kết nối.

src/main/resources/application.properties

# Modify this property using the output from the previous command line.
spring.cloud.gcp.sql.instance-connection-name=INSTANCE_CONNECTION_NAME

# Your database name
spring.cloud.gcp.sql.database-name=registrants

# So app starts despite "table already exists" errors.
spring.datasource.continue-on-error=true

# Enforces database initialization
spring.datasource.initialization-mode=always

# Cloud SQL (MySQL) only supports InnoDB, not MyISAM
spring.jpa.database-platform=org.hibernate.dialect.MySQL55Dialect
spring.jpa.hibernate.ddl-auto=create-drop

# This is used if you want to connect to a different database instance
# user other than root; not used in codelab.
# spring.datasource.username=root

# This is used to specify the password of the database user;
# not used in codelab.
# spring.datasource.password=password

Thuộc tính duy nhất bạn phải sửa đổi là tên kết nối thực thể. Giá trị này phải được định dạng thành một giá trị được phân tách bằng dấu hai chấm có định dạng: YOUR_GCP_PROJECT_ID:REGION:DATABASE_INSTANCE_NAME.

7. Tạo nội dung tĩnh

Đầu tiên, chúng ta sẽ tạo giao diện người dùng cho ứng dụng của mình. Ứng dụng phải có một biểu mẫu cho phép người dùng đăng ký cá nhân, đồng thời có một chế độ xem hiển thị tất cả những người đăng ký thành công.

Đối với trang chủ, hãy tạo một index.html chứa biểu mẫu đăng ký.

src/main/resources/static/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Registration Sample Application</title>
</head>
<body>

<h1>Registration</h1>

<div>
  <nav>
    <a href="/">Home</a><br>
    <a href="/registrants">Registered People</a><br>
  </nav>

  <p>
    This is a demo registration application which sends user information to a Pub/Sub topic and
    persists it into a MySQL database.
  </p>

  <h2>Register Person</h2>
  <div>
    <form action="/registerPerson" method="post">
      First Name: <input type="text" name="firstName" />
      Last Name: <input type="text" name="lastName" />
      Email: <input type="text" name="email" />
      <input type="submit" value="Submit"/>
    </form>
  </div>
</div>

</body>
</html>

Tiếp theo, chúng ta sẽ tạo một mẫu Thymeleaf có tên là registrants.html để hiển thị người dùng đã đăng ký. Thymeleaf là một khung tạo mẫu mà chúng tôi sử dụng để tạo và phân phát HTML được tạo động. Bạn sẽ thấy mẫu giống như HTML, ngoại trừ việc mẫu này có một số phần tử Markdown bổ sung để xử lý nội dung động. Mẫu này chấp nhận một thông số duy nhất có tên là personsList. Thông số này chứa tất cả những người đăng ký đã đăng ký thông qua ứng dụng.

src/main/resources/templates/registrants.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <title>Registrants List</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<h1>Registrants List</h1>
<p>
  This page displays all the people who were registered through the Pub/Sub topic.
  All results are retrieved from the MySQL database.
</p>
<table border="1">
  <tr>
    <th>First Name</th>
    <th>Last Name</th>
    <th>Email</th>
  </tr>
  <tr th:each="person : ${personsList}">
    <td>[[${person.firstName}]]</td>
    <td>[[${person.lastName}]]</td>
    <td>[[${person.email}]]</td>
  </tr>
</table>

</body>
</html>

Tại thời điểm này, bạn có thể xác minh rằng nội dung tĩnh đang được phân phát.

Tạo và chạy ứng dụng bằng Maven:

$ ./mvnw spring-boot:run

Nhấp vào nút xem trước trong cửa sổ Cloud Shell và xác minh rằng bạn thấy trang chủ đang hiển thị. Tuy nhiên, chức năng nào trên giao diện người dùng sẽ không hoạt động vì chúng ta thiếu trình điều khiển web. Thông tin này sẽ được thêm trong bước tiếp theo.

5e38bb0d0e93002e.png.

Sau khi xem trước ứng dụng, nhấn CTRL+C để chấm dứt ứng dụng.

8. Chuyển Người đăng ký đến một chủ đề Pub/Sub

Ở bước này, chúng tôi sẽ triển khai tính năng giúp xuất bản tính năng mà người đăng ký gửi qua biểu mẫu trực tuyến dưới dạng một chủ đề trên Cloud Pub/Sub.

Thêm lớp dữ liệu

Trước tiên, chúng ta sẽ tạo một số lớp dữ liệu trong Kotlin; đây sẽ là các pháp nhân JPA của chúng tôi và cũng đóng vai trò là đại diện trung gian của chúng tôi đối với những người đăng ký đã gửi thông qua biểu mẫu này.

Trong gói minh hoạ, hãy thêm 2 tệp mới: lớp Person và Spring Data PersonRepository. Hai lớp này sẽ cho phép chúng ta dễ dàng lưu trữ và truy xuất các mục đăng ký từ cơ sở dữ liệu MySQL bằng cách sử dụng Spring Data JPA.

src/main/kotlin/com/example/demo/Person.kt

package com.example.demo

import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id

@Entity
data class Person(
    val firstName: String,
    val lastName: String,
    val email: String,
    @Id @GeneratedValue
    var id: Long? = 0)

src/main/kotlin/com/example/demo/PersonRepository.kt

package com.example.demo

import org.springframework.data.repository.CrudRepository

interface PersonRepository : CrudRepository<Person, Long>

Thêm Trình điều khiển web

Tiếp theo, chúng ta sẽ tạo một lớp Đơn vị kiểm soát. Lớp này sẽ xử lý người đăng ký trong biểu mẫu và gửi thông tin đến chủ đề Cloud Pub/Sub mà bạn đã tạo trước đó. Bộ điều khiển này tạo hai điểm cuối:

  • /registerPerson: Điểm cuối POST, trong đó thông tin của người đăng ký được gửi, sau đó được gửi đến chủ đề Pub/Sub. Trong hàm registerPerson(..), thông tin của người đăng ký được gửi đến chủ đề Pub/Sub bằng PubSubTemplate, một lớp tiện lợi trong các công cụ tích hợp Pub/Sub của Spring Cloud GCP, giúp giảm thiểu mã nguyên mẫu cần thiết để bắt đầu tương tác với Cloud Pub/Sub.
  • /registrants: Hiển thị tất cả những người đăng ký đã đăng ký thành công trong cơ sở dữ liệu. Thông tin này được truy xuất từ thực thể MySQL bằng cách sử dụng kho lưu trữ dữ liệu Spring mà chúng ta đã tạo ở bước trước.

Tạo lớp Trình điều khiển sau đây trong gói minh hoạ:

src/main/kotlin/com/example/demo/Controller.kt

package com.example.demo

import com.google.cloud.spring.pubsub.core.PubSubTemplate
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.servlet.ModelAndView
import org.springframework.web.servlet.view.RedirectView

@RestController
class Controller(val pubSubTemplate: PubSubTemplate, val personRepository: PersonRepository) {
  
  // The Pub/Sub topic name created earlier.
  val REGISTRATION_TOPIC = "registrations"

  @PostMapping("/registerPerson")
  fun registerPerson(
    @RequestParam("firstName") firstName: String,
    @RequestParam("lastName") lastName: String,
    @RequestParam("email") email: String): RedirectView {

    pubSubTemplate.publish(
        REGISTRATION_TOPIC,
        Person(firstName, lastName, email))
    return RedirectView("/")
  }

  @GetMapping("/registrants")
  fun getRegistrants(): ModelAndView {
    val personsList = personRepository.findAll().toList()
    return ModelAndView("registrants", mapOf("personsList" to personsList))
  }
}

Đơn vị kiểm soát sẽ đọc thông tin của người đăng ký được gửi qua biểu mẫu trên web, sau đó xuất bản thông tin đó theo chủ đề Pub/Sub.

Thêm hạt trình ánh xạ đối tượng JSON

Bạn có thể nhận thấy trong Trình kiểm soát rằng chúng ta xuất bản đối tượng Person cho chủ đề Pub/Sub chứ không phải Chuỗi. Điều này có thể xảy ra vì chúng tôi đã tận dụng khả năng hỗ trợ của Spring Cloud GCP để gửi các tải trọng JSON tuỳ chỉnh đến các chủ đề – thư viện cho phép bạn chuyển đổi tuần tự đối tượng thành JSON, gửi tải trọng JSON đến một chủ đề và giải tuần tự tải trọng khi nhận được.

Để tận dụng tính năng này, chúng ta phải thêm bean ObjectMapper vào ngữ cảnh ứng dụng của bạn. Hạt ObjectMapper này sẽ được dùng để chuyển đổi tuần tự các đối tượng sang và từ JSON khi ứng dụng của bạn gửi và nhận thông báo. Trong lớp DemoApplication.kt, hãy thêm Đậu mùa xuân JacksonPubSubMessageConverter:

src/main/kotlin/com/example/demo/DemoApplication.kt

package com.example.demo

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

// new imports to add
import org.springframework.context.annotation.Bean
import com.fasterxml.jackson.databind.ObjectMapper
import com.google.cloud.spring.pubsub.support.converter.JacksonPubSubMessageConverter

@SpringBootApplication
class DemoApplication {
  // This bean enables serialization/deserialization of
  // Java objects to JSON for Pub/Sub payloads
  @Bean
  fun jacksonPubSubMessageConverter(objectMapper: ObjectMapper) = 
      JacksonPubSubMessageConverter(objectMapper)
}

fun main(args: Array<String>) {
        runApplication<DemoApplication>(*args)
}

Tại thời điểm này, bạn có thể thử chạy lại ứng dụng bằng cách chạy:

$ ./mvnw spring-boot:run

Từ biểu mẫu web trên trang chính, bây giờ ứng dụng sẽ gửi thông tin tới chủ đề Pub/Sub mà bạn đã tạo. Tuy nhiên, tính năng này vẫn chưa hữu ích vì chúng ta vẫn cần đọc từ chủ đề Pub/Sub đó! Bạn có thể thực hiện việc này trong bước tiếp theo.

9. Người đăng ký đọc trong chủ đề Pub/Sub

Ở bước cuối cùng, chúng tôi sẽ xử lý thông tin của người đăng ký trong chủ đề Pub/Sub và lưu trữ thông tin đó vào cơ sở dữ liệu Cloud MySQL. Thao tác này sẽ hoàn tất đơn đăng ký, cho phép bạn gửi người đăng ký mới thông qua biểu mẫu và xem tất cả người dùng đã đăng ký qua điểm cuối /registrants.

Ứng dụng này sẽ tận dụng tính năng Tích hợp mùa xuân, cung cấp nhiều thành phần trừu tượng thuận tiện để xử lý thông báo. Chúng ta sẽ thêm PubSubInboundChannelAdapter để có thể đọc tin nhắn trong chủ đề Pub/Sub và đưa vào pubsubInputChannel để xử lý thêm. Sau đó, chúng ta sẽ định cấu hình hàm messageReceiver bằng cách sử dụng @ServiceActivator để được gọi bằng các thông báo đến trên pubsubInputChannel.

src/main/kotlin/com/example/demo/DemoApplication.kt

package com.example.demo

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

import org.springframework.context.annotation.Bean
import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.cloud.gcp.pubsub.support.converter.JacksonPubSubMessageConverter

// new imports to add
import com.google.cloud.spring.pubsub.core.PubSubTemplate
import com.google.cloud.spring.pubsub.integration.AckMode
import com.google.cloud.spring.pubsub.integration.inbound.PubSubInboundChannelAdapter
import com.google.cloud.spring.pubsub.support.BasicAcknowledgeablePubsubMessage
import com.google.cloud.spring.pubsub.support.GcpPubSubHeaders
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.integration.annotation.ServiceActivator
import org.springframework.integration.channel.DirectChannel
import org.springframework.messaging.MessageChannel
import org.springframework.messaging.handler.annotation.Header

@SpringBootApplication
class DemoApplication {

  private val REGISTRANT_SUBSCRIPTION = "registrations-sub"

  @Autowired
  private lateinit var personRepository: PersonRepository

  // New Spring Beans to add
  @Bean
  fun pubsubInputChannel() = DirectChannel()

  @Bean
  fun messageChannelAdapter(
      @Qualifier("pubsubInputChannel") inputChannel: MessageChannel,
      pubSubTemplate: PubSubTemplate): PubSubInboundChannelAdapter {

    val adapter = PubSubInboundChannelAdapter(
        pubSubTemplate, REGISTRANT_SUBSCRIPTION)
    adapter.outputChannel = inputChannel
    adapter.ackMode = AckMode.MANUAL
    adapter.payloadType = Person::class.java
    return adapter
  }

  @ServiceActivator(inputChannel = "pubsubInputChannel")
  fun messageReceiver(
      payload: Person,
      @Header(GcpPubSubHeaders.ORIGINAL_MESSAGE) message: BasicAcknowledgeablePubsubMessage) {
    personRepository.save(payload)
    print("Message arrived! Payload: $payload")
    message.ack()
  }

  // ObjectMapper bean from previous step
  @Bean
  fun jacksonPubSubMessageConverter(objectMapper: ObjectMapper) = JacksonPubSubMessageConverter(objectMapper)
}

fun main(args: Array<String>) {
        runApplication<DemoApplication>(*args)
}

Lúc này, bạn đã hoàn tất việc thiết lập cho ứng dụng. Để xác minh rằng ứng dụng hoạt động đúng cách, hãy chạy mã:

$ ./mvnw spring-boot:run

Nhấp lại vào nút Xem trước và thử đăng ký người dùng bằng cách điền vào biểu mẫu rồi gửi.

e0d0b0f0c94120c2.png

Nhấp vào đường liên kết Người đã đăng ký để xác minh rằng người đăng ký mới sẽ xuất hiện trong bảng.

ab3b980423d0c51.png

Xin chúc mừng, bạn hiện đã hoàn tất! Chấm dứt ứng dụng bằng cách nhấn CTRL+C trong cửa sổ dòng lệnh.

10. Dọn dẹp

Để dọn dẹp môi trường, bạn cần xoá chủ đề Pub/Sub và phiên bản Cloud MySQL mà bạn đã tạo.

Xoá phiên bản Cloud MySQL

$ gcloud sql instances delete codelab-instance

Xoá tài nguyên Pub/Sub

$ gcloud pubsub subscriptions delete registrations-sub
$ gcloud pubsub topics delete registrations

11. Xin chúc mừng!

Bạn hiện đã hoàn tất việc viết một ứng dụng Kotlin mùa xuân có tích hợp với Cloud Pub/Sub và Cloud SQL (MySQL).

Tìm hiểu thêm

Giấy phép

Tác phẩm này được cấp phép theo Giấy phép chung Ghi nhận tác giả Creative Commons 2.0.