1. บทนำ
Spring Framework 5.0 เพิ่มการรองรับ Kotlin โดยเฉพาะเพื่อให้นักพัฒนาซอฟต์แวร์ Kotlin ใช้ Spring ได้โดยง่าย การเปลี่ยนแปลงเหล่านี้ส่งผลให้การผสานรวม Google Cloud จาก Spring Cloud GCP ทำงานใน Kotlin ได้อย่างราบรื่น ใน Codelab นี้ คุณจะได้ทราบว่าการเริ่มใช้บริการของ Google Cloud ในแอปพลิเคชัน Kotlin นั้นทำได้ง่ายเพียงใด
Codelab นี้จะแนะนำการตั้งค่าแอปพลิเคชันการลงทะเบียนอย่างง่ายใน Kotlin ซึ่งสาธิตการใช้บริการ GCP ซึ่งรวมถึง Cloud Pub/Sub และ Cloud SQL
สิ่งที่คุณจะสร้าง
ใน Codelab นี้ คุณจะต้องตั้งค่าแอปพลิเคชัน Kotlin Spring Boot ซึ่งยอมรับข้อมูลผู้จดทะเบียน เผยแพร่ข้อมูลนี้ไปยังหัวข้อ Cloud Pub/Sub และดำเนินการต่อไปในฐานข้อมูล Cloud MySQL
สิ่งที่คุณจะได้เรียนรู้
วิธีผสานรวมกับบริการ Google Cloud ในแอปพลิเคชัน Kotlin Spring
สิ่งที่คุณต้องมี
- โปรเจ็กต์ Google Cloud Platform
- เบราว์เซอร์ เช่น Chrome หรือ Firefox
คุณจะใช้บทแนะนำนี้อย่างไร
คุณจะให้คะแนนประสบการณ์ในการสร้างเว็บแอป HTML/CSS อย่างไร
คุณจะให้คะแนนความพึงพอใจสำหรับประสบการณ์การใช้บริการ Google Cloud Platform อย่างไร
2. การตั้งค่าและข้อกำหนด
การตั้งค่าสภาพแวดล้อมตามเวลาที่สะดวก
- ลงชื่อเข้าใช้ Cloud Console และสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ (หากยังไม่มีบัญชี Gmail หรือ G Suite คุณต้องสร้างบัญชี)
โปรดจดจำรหัสโปรเจ็กต์ ซึ่งเป็นชื่อที่ไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมด (ชื่อด้านบนมีคนใช้แล้ว และจะใช้ไม่ได้ ขออภัย) และจะมีการอ้างอิงใน Codelab ว่า PROJECT_ID
ในภายหลัง
- ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร Google Cloud
การใช้งาน Codelab นี้น่าจะไม่มีค่าใช้จ่ายใดๆ หากมี ตรวจสอบว่าคุณได้ทำตามวิธีการใน "การล้างข้อมูล" ซึ่งจะแนะนำคุณเกี่ยวกับวิธีปิดทรัพยากรเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ ผู้ใช้ใหม่ของ Google Cloud จะมีสิทธิ์เข้าร่วมโปรแกรมทดลองใช้ฟรี$300 USD
Google Cloud Shell
แม้ Google Cloud จะทำงานจากระยะไกลได้จากแล็ปท็อป แต่ใน Codelab นี้ เราจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมแบบบรรทัดคำสั่งที่ทำงานในระบบคลาวด์
เปิดใช้งาน Cloud Shell
- คลิกเปิดใช้งาน Cloud Shell จาก Cloud Console
หากคุณไม่เคยเริ่มต้นใช้งาน Cloud Shell มาก่อน คุณจะเห็นหน้าจอตรงกลาง (ครึ่งหน้าล่าง) ซึ่งอธิบายว่านี่คืออะไร หากเป็นเช่นนั้น ให้คลิกดำเนินการต่อ (คุณจะไม่เห็นการดำเนินการนี้อีก) หน้าจอแบบครั้งเดียวมีลักษณะดังนี้
การจัดสรรและเชื่อมต่อกับ Cloud Shell ใช้เวลาเพียงไม่กี่นาที
เครื่องเสมือนนี้เต็มไปด้วยเครื่องมือการพัฒนาทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีหลักขนาด 5 GB ที่ทำงานอย่างต่อเนื่องใน Google Cloud ซึ่งจะช่วยเพิ่มประสิทธิภาพของเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก งานส่วนใหญ่ใน Codelab นี้สามารถทำได้โดยใช้เบราว์เซอร์หรือ Chromebook เท่านั้น
เมื่อเชื่อมต่อกับ Cloud Shell คุณควรเห็นว่าได้รับการตรวจสอบแล้ว และโปรเจ็กต์ได้รับการตั้งค่าเป็นรหัสโปรเจ็กต์แล้ว
- เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคุณได้รับการตรวจสอบสิทธิ์แล้ว
gcloud auth list
เอาต์พุตจากคำสั่ง
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
gcloud config list project
เอาต์พุตจากคำสั่ง
[core] project = <PROJECT_ID>
หากไม่ใช่ ให้ตั้งคำสั่งด้วยคำสั่งนี้
gcloud config set project <PROJECT_ID>
เอาต์พุตจากคำสั่ง
Updated property [core/project].
3. จัดสรรทรัพยากร Pub/Sub
ก่อนอื่น คุณจะต้องตั้งค่าหัวข้อและการสมัครใช้บริการ Cloud Pub/Sub ในแอปพลิเคชันนี้ เราจะเผยแพร่ข้อมูลการลงทะเบียนไปยังหัวข้อ Pub/Sub จากนั้นข้อมูลจะถูกอ่านจากหัวข้อนี้และคงไว้ในฐานข้อมูล
ในบทแนะนำนี้ เราจะใช้ Cloud Shell ในการจัดสรรทรัพยากร โปรดทราบว่าผู้ดูแลระบบอาจกำหนดค่าทรัพยากร Pub/Sub ผ่านส่วน Cloud Pub/Sub ใน Google Cloud Console ได้เช่นกัน
เปิดใช้ Pub/Sub API ในเทอร์มินัล Cloud Shell ก่อน
$ gcloud services enable pubsub.googleapis.com
ต่อไปเราจะสร้างหัวข้อ Pub/Sub ชื่อ registrations
สำหรับแอปพลิเคชันนี้ ระบบจะเผยแพร่ข้อมูลการลงทะเบียนที่ส่งผ่านใบสมัครไปยังหัวข้อนี้
$ gcloud pubsub topics create registrations
สุดท้ายให้สร้างการสมัครรับข้อมูลสำหรับหัวข้อนั้น การสมัครใช้บริการ Pub/Sub ช่วยให้คุณได้รับข้อความจากหัวข้อ
$ gcloud pubsub subscriptions create registrations-sub --topic=registrations
คุณสร้างหัวข้อ Cloud Pub/Sub และการสมัครใช้บริการสำหรับแอปพลิเคชันเรียบร้อยแล้ว
4. สร้างอินสแตนซ์และฐานข้อมูล Cloud SQL (MySQL)
สำหรับแอปพลิเคชันตัวอย่าง เรายังต้องตั้งค่าอินสแตนซ์ฐานข้อมูลเพื่อเก็บข้อมูลผู้จดทะเบียนด้วย ขั้นตอนนี้จะใช้เทอร์มินัล Cloud Shell ในการจัดสรรทรัพยากร Cloud SQL ด้วย โปรดทราบว่าคุณอาจดูและกำหนดค่าอินสแตนซ์ Cloud SQL ผ่าน Google Cloud Console ได้เช่นกัน
ขั้นแรก ให้เปิดใช้ Cloud SQL Admin API
$ gcloud services enable sqladmin.googleapis.com
ถัดไป เราจะจัดสรรอินสแตนซ์ Cloud SQL (MySQL) คำสั่งนี้อาจใช้เวลาสักครู่
$ gcloud sql instances create codelab-instance --region=us-east1
หลังจากสร้างอินสแตนซ์ Cloud SQL เรียบร้อยแล้ว ให้สร้างฐานข้อมูลใหม่ในอินสแตนซ์ชื่อ registrants
$ gcloud sql databases create registrants --instance codelab-instance
ตอนนี้คุณได้ตั้งค่าอินสแตนซ์ Cloud SQL และฐานข้อมูลสำหรับแอปพลิเคชันเสร็จสมบูรณ์แล้ว
5. เริ่มต้นแอปพลิเคชัน Spring Boot
ตอนนี้เราพร้อมเริ่มเขียนใบสมัครแล้ว ขั้นตอนถัดไปจะใช้ Cloud Shell ตามที่อธิบายไว้ในขั้นตอนการตั้งค่าต่อไป
ขั้นแรก เราจะใช้ Initializr เพื่อสร้างโค้ดร่างสำหรับโครงการ ในหน้าต่าง Cloud Shell ให้เรียกใช้
$ 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
คำสั่งนี้จะสร้างการตั้งค่าโปรเจ็กต์ Maven เริ่มต้น รวมถึงโค้ดโครงสร้างสำหรับแอปพลิเคชันของคุณในไดเรกทอรี registrations-codelab/
ส่วนต่อไปนี้จะอธิบายการแก้ไขโค้ดที่จำเป็นต่อการสร้างแอปพลิเคชันที่ใช้งานได้
ตัวแก้ไขโค้ด Cloud Shell
วิธีที่ง่ายที่สุดในการเริ่มแก้ไขและดูโค้ดในสภาพแวดล้อม Cloud Shell คือการใช้ตัวแก้ไขโค้ด Cloud Shell ในตัว
เมื่อเปิดอินสแตนซ์ Cloud Shell แล้ว ให้คลิกไอคอนดินสอเพื่อเปิดตัวแก้ไขโค้ด เครื่องมือแก้ไขควรช่วยให้คุณแก้ไขไฟล์โปรเจ็กต์ที่สร้างโดย Initialzr ได้โดยตรง
6. การกำหนดค่าฐานข้อมูล
ก่อนอื่นให้กำหนดค่าแอปพลิเคชันให้เชื่อมต่อกับฐานข้อมูล Cloud MySQL ที่คุณตั้งค่าไว้ ไลบรารี Spring Cloud GCP มีเงื่อนไขเริ่มต้น Cloud MySQL ซึ่งมีทรัพยากร Dependency ที่จำเป็นสำหรับการเชื่อมต่อกับอินสแตนซ์ Cloud MySQL
เพิ่มทรัพยากร Dependency spring-cloud-gcp-starter-sql-mysql
ไปยังโปรเจ็กต์ 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>
นอกจากนี้คุณต้องแก้ไขไฟล์การกำหนดค่า application.properties
เพื่ออธิบายการกำหนดค่าฐานข้อมูล คัดลอกพร็อพเพอร์ตี้ต่อไปนี้ลงในไฟล์ application.properties
ค้นหาชื่อการเชื่อมต่ออินสแตนซ์ไปยังฐานข้อมูลดังนี้
$ gcloud sql instances describe codelab-instance \ --format 'value(connectionName)'
เอาต์พุตของนี้จะใช้ในไฟล์ application.properties
เพื่อกำหนดค่าข้อมูลการเชื่อมต่อ
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
พร็อพเพอร์ตี้เดียวที่คุณต้องแก้ไขคือชื่อการเชื่อมต่ออินสแตนซ์ ค่านี้ต้องอยู่ในรูปแบบค่าที่คั่นด้วยโคลอนโดยมีรูปแบบดังนี้ YOUR_GCP_PROJECT_ID:REGION:DATABASE_INSTANCE_NAME
7. การสร้างเนื้อหาแบบคงที่
ขั้นแรก เราจะสร้างฟรอนท์เอนด์สำหรับแอปพลิเคชัน ใบสมัครควรมีแบบฟอร์มที่ให้ผู้ใช้ลงทะเบียนบุคคลธรรมดาได้ และมีมุมมองที่แสดงผู้ลงทะเบียนที่สำเร็จทั้งหมด
สำหรับหน้าแรก ให้สร้าง index.html
ที่มีแบบฟอร์มการลงทะเบียน
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>
ต่อไป เราจะสร้างเทมเพลต Thymeleaf ชื่อ registrants.html
เพื่อแสดงผู้ใช้ที่ลงทะเบียน Thymeleaf เป็นเฟรมเวิร์กเทมเพลตเทมเพลตที่เราใช้สร้างและแสดง HTML ที่สร้างขึ้นแบบไดนามิก คุณจะเห็นว่าเทมเพลตมีลักษณะเหมือน HTML เว้นแต่ว่าจะมีองค์ประกอบมาร์กดาวน์เพิ่มเติมบางอย่างเพื่อใช้จัดการกับเนื้อหาแบบไดนามิก เทมเพลตนี้ยอมรับพารามิเตอร์เดียวที่ชื่อว่า personsList
ซึ่งมีผู้จดทะเบียนทั้งหมดที่ลงทะเบียนผ่านแอปพลิเคชัน
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>
ในขั้นนี้ คุณสามารถยืนยันได้ว่าเนื้อหาคงที่กำลังแสดงอยู่
สร้างและเรียกใช้แอปโดยใช้ Maven ดังนี้
$ ./mvnw spring-boot:run
คลิกปุ่มแสดงตัวอย่างในหน้าต่าง Cloud Shell และตรวจสอบว่าคุณเห็นหน้าแรกที่แสดงผลอยู่ อย่างไรก็ตาม ฟังก์ชันใน UI จะไม่ทำงานเนื่องจากไม่มีตัวควบคุมเว็บ ระบบจะเพิ่มข้อมูลนี้ในขั้นตอนถัดไป
หลังจากดูตัวอย่างแอปพลิเคชันแล้ว ให้กด CTRL+C
เพื่อยุติแอปพลิเคชัน
8. การส่งผู้ลงทะเบียนไปยังหัวข้อ Pub/Sub
ในขั้นตอนนี้ เราจะใช้ฟีเจอร์ซึ่งจะมีการเผยแพร่ผู้ลงทะเบียนที่ส่งผ่านเว็บฟอร์มไปยังหัวข้อ Cloud Pub/Sub
เพิ่มคลาสข้อมูล
ก่อนอื่น เราจะสร้างคลาสข้อมูล Kotlin จำนวนหนึ่ง ข้อมูลเหล่านี้จะเป็นหน่วยงาน JPA ของเราและยังทำหน้าที่เป็นตัวแทนระดับกลางของผู้จดทะเบียนที่ส่งผ่านแบบฟอร์มนี้
ในแพ็กเกจเดโม ให้เพิ่มไฟล์ใหม่ 2 ไฟล์ ได้แก่ คลาส Person
และข้อมูลฤดูใบไม้ผลิ PersonRepository
ทั้ง 2 คลาสนี้จะช่วยให้เราจัดเก็บและเรียกข้อมูลรายการลงทะเบียนจากฐานข้อมูล MySQL ได้โดยใช้ 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>
เพิ่ม Web Controller
ถัดไป เราจะสร้างคลาสตัวควบคุมซึ่งประมวลผลผู้จดทะเบียนจากแบบฟอร์มและส่งข้อมูลไปยังหัวข้อ Cloud Pub/Sub ที่คุณสร้างไว้ก่อนหน้านี้ ตัวควบคุมนี้จะสร้างปลายทาง 2 จุด ได้แก่
/registerPerson
: ปลายทาง POST ที่ส่งข้อมูลผู้จดทะเบียนแล้วส่งไปยังหัวข้อ Pub/Sub ในฟังก์ชันregisterPerson(..)
ระบบจะส่งข้อมูลผู้จดทะเบียนไปยังหัวข้อ Pub/Sub โดยใช้PubSubTemplate
ซึ่งเป็นคลาสอำนวยความสะดวกจากการผสานรวม Pub/Sub ของ GCP สำหรับ Cloud ในฤดูใบไม้ผลิซึ่งจะลดโค้ดต้นแบบที่ต้องใช้เพื่อเริ่มโต้ตอบกับ Cloud Pub/Sub/registrants
: แสดงผู้จดทะเบียนทั้งหมดที่ลงทะเบียนในฐานข้อมูลเรียบร้อยแล้ว ข้อมูลนี้ดึงมาจากอินสแตนซ์ MySQL โดยใช้ที่เก็บ Spring Data ที่เราสร้างไว้ในขั้นตอนก่อนหน้า
สร้างคลาสตัวควบคุมต่อไปนี้ในแพ็กเกจเดโม:
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))
}
}
ตัวควบคุมจะอ่านข้อมูลผู้จดทะเบียนที่ส่งผ่านเว็บฟอร์ม แล้วเผยแพร่ข้อมูลไปยังหัวข้อ Pub/Sub
การเพิ่มบีนการแมปออบเจ็กต์ JSON
คุณอาจสังเกตเห็นในตัวควบคุมว่าเราเผยแพร่ออบเจ็กต์ Person
ไปยังหัวข้อ Pub/Sub และไม่ใช่สตริง ซึ่งเป็นไปได้เพราะเราใช้ประโยชน์จากการสนับสนุน Spring Cloud GCP สำหรับเพย์โหลด JSON ที่กำหนดเองซึ่งจะส่งไปยังหัวข้อ ไลบรารีนี้ให้คุณเรียงลำดับออบเจ็กต์เป็น JSON ส่งเพย์โหลด JSON ไปยังหัวข้อ และดีซีเรียลเพย์โหลดเมื่อได้รับ
เราต้องเพิ่มถั่ว ObjectMapper
ลงในบริบทของแอปพลิเคชันเพื่อใช้ประโยชน์จากฟีเจอร์นี้ บีน ObjectMapper
นี้จะใช้ในการเรียงลำดับออบเจ็กต์ไปยังและจาก JSON เมื่อแอปพลิเคชันของคุณส่งและรับข้อความ ในชั้นเรียน DemoApplication.kt
ให้เพิ่มถั่วฤดูใบไม้ผลิ 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)
}
ในตอนนี้ คุณสามารถลองเรียกใช้แอปพลิเคชันอีกครั้งโดยเรียกใช้:
$ ./mvnw spring-boot:run
จากแบบฟอร์มบนเว็บในหน้าหลัก จากนี้ไปแอปพลิเคชันจะส่งข้อมูลไปยังหัวข้อ Pub/Sub ที่คุณสร้างขึ้น อย่างไรก็ตาม ยังไม่เกิดประโยชน์ใดๆ เพราะเรายังต้องอ่านจากหัวข้อ Pub/Sub นั้นอยู่ โดยดำเนินการได้ในขั้นตอนถัดไป
9. กำลังอ่านผู้ลงทะเบียนจากหัวข้อ Pub/Sub
ในขั้นตอนสุดท้าย เราจะประมวลผลข้อมูลผู้จดทะเบียนจากหัวข้อ Pub/Sub และยืนยันข้อมูลลงในฐานข้อมูล Cloud MySQL การดำเนินการนี้จะกรอกใบสมัครให้เสร็จสมบูรณ์ ซึ่งทำให้คุณส่งผู้จดทะเบียนใหม่ผ่านแบบฟอร์มและดูผู้ใช้ที่ลงทะเบียนทั้งหมดผ่านปลายทาง /registrants
ได้
แอปพลิเคชันนี้จะใช้ประโยชน์จาก Spring Integration ซึ่งมีเนื้อหาแอบสแตรกต์ที่สะดวกรวดเร็วในการจัดการกับการรับส่งข้อความ เราจะเพิ่ม PubSubInboundChannelAdapter
เพื่อให้เราอ่านข้อความจากหัวข้อ Pub/Sub ได้ และใส่ไว้ใน pubsubInputChannel
เพื่อประมวลผลต่อไป จากนั้นเราจะกำหนดค่าฟังก์ชัน messageReceiver
โดยใช้ @ServiceActivator
ให้เรียกใช้เมื่อมีข้อความที่มาถึงใน 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)
}
ในตอนนี้ คุณตั้งค่าแอปพลิเคชันเสร็จเรียบร้อยแล้ว หากต้องการยืนยันว่าแอปทำงานได้อย่างถูกต้อง ให้เรียกใช้
$ ./mvnw spring-boot:run
คลิกปุ่มดูตัวอย่างอีกครั้ง แล้วลองลงทะเบียนผู้ใช้โดยกรอกแบบฟอร์มและส่ง
คลิกลิงก์บุคคลที่จดทะเบียนเพื่อยืนยันว่าผู้จดทะเบียนใหม่ปรากฏในตาราง
ขอแสดงความยินดี คุณดำเนินการเสร็จแล้ว! ยุติแอปพลิเคชันโดยการกด CTRL+C
ในหน้าต่างเทอร์มินัล
10. ล้างข้อมูล
หากต้องการล้างสภาพแวดล้อม คุณต้องลบหัวข้อ Pub/Sub และอินสแตนซ์ Cloud MySQL ที่คุณสร้างขึ้น
การลบอินสแตนซ์ Cloud MySQL
$ gcloud sql instances delete codelab-instance
การลบทรัพยากร Pub/Sub
$ gcloud pubsub subscriptions delete registrations-sub $ gcloud pubsub topics delete registrations
11. ยินดีด้วย
ตอนนี้คุณเขียนแอปพลิเคชัน Spring Kotlin ที่ผสานรวมกับ Cloud Pub/Sub และ Cloud SQL (MySQL) เรียบร้อยแล้ว
ดูข้อมูลเพิ่มเติม
- ฤดูใบไม้ผลิในโปรเจ็กต์ GCP: http://cloud.spring.io/spring-cloud-gcp/
- Spring ในที่เก็บ GitHub ของ GCP: https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- Java บน Google Cloud Platform: https://cloud.google.com/java/
- ตัวอย่างแอปพลิเคชัน Kotlin ที่ใช้ GCP: https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/master/spring-cloud-gcp-kotlin-samples
ใบอนุญาต
ผลงานนี้ได้รับอนุญาตภายใต้ใบอนุญาตทั่วไปครีเอทีฟคอมมอนส์แบบระบุแหล่งที่มา 2.0