Chương 2: Hướng dẫn phát triển (Developer)
Chương này mô tả cấu trúc source code, quy ước coding, cách tạo module mới, cách viết API/UI, quy trình commit/branch, và cách chạy/debug dự án trong quá trình phát triển. Mục tiêu giúp developer hiểu kiến trúc và đóng góp code đúng chuẩn.
- Luồng Xử Lý Dịch Vụ API Tích Hợp Kafka (Kafka API Processing Flow)
- 1.Cấu trúc dự án
- 2. API Design & Response Standard
- 3.Cơ chế xác thực (JWT/Bearer)
- 4. Logging & Audit trong Sequence
- 5.Git Workflow & Pull Request
- 6.Checklist kiểm tra trước khi merge
- 7.Quy trình phối hợp & quản lý thay đổi các nhóm
- 8. Prompt Template cho AI Agent tạo API trên LifeESB
- 9. Prompt Template cho AI Agent tạo Test Case API LifeESB
Luồng Xử Lý Dịch Vụ API Tích Hợp Kafka (Kafka API Processing Flow)
1.1. Mục Tiêu
Tài liệu này mô tả luồng xử lý chuẩn của dịch vụ Loadbalance_kafka trên nền tảng WSO2 Micro Integrator (WSO2 MI), từ khi Client gửi request đến khi dữ liệu được xử lý và phản hồi về. Mục tiêu:
- Thống nhất cách hiểu kiến trúc giữa các thành viên
- Đảm bảo đúng luồng dữ liệu qua từng lớp Kafka
- Dễ dàng trace lỗi và mở rộng sau này
1.2. Phạm Vi Áp Dụng
- Dự án:
Loadbalance_kafka(WSO2 MI v4.4.0) - Ngôn ngữ: Synapse XML (WSO2 Mediation)
- Các component: API, Inbound Endpoint, Sequence, Local Entry
- Kafka Connector:
mi-inbound-kafkav2.0.6,mi-connector-kafkav3.3.10
1.3. Tổng Quan Luồng Xử Lý
📸 [Ảnh minh họa] — Chụp màn hình sơ đồ luồng WSO2 MI Studio hoặc Kafka Manager
1.4. Các Bước Xử Lý Chi Tiết
Bước 1. Client Gửi Request
Client gọi API qua HTTP:
Quy định:
- Phương thức bắt buộc:
POST - Content-Type:
application/json - Payload là JSON tuỳ ý — không bị validate tại lớp này
📸 [Ảnh minh họa] — Ảnh chụp Postman/Curl gửi request thành công
Bước 2. KafkaProducerApi Nhận Request
File:
KafkaProducerApi.xml
API nhận request và bắt đầu luồng xử lý inSequence.
Log ghi nhận:
API_NAME: Tên API xác định nguồn logSTATUS: Trạng thái hiện tại của luồngPAYLOAD: Toàn bộ JSON body của request
📸 [Ảnh minh họa] — Ảnh log WSO2 MI Console hoặc file log khi request vào
Bước 3. Khởi Tạo Kết Nối Kafka (kafkaTransport.init)
File:
KafkaProducerApi.xml (trong inSequence)
Giải thích từng trường:
| Trường | Giá trị | Mô tả |
|---|---|---|
name |
KafkaConnection |
Tên kết nối dùng để Sequence tham chiếu (configKey). |
bootstrapServers |
hdp-master:9092 |
Địa chỉ Kafka Broker. |
keySerializerClass |
StringSerializer |
Class serialize Key của message (kiểu chuỗi). |
valueSerializerClass |
StringSerializer |
Class serialize Value của message (kiểu chuỗi). |
acks |
all |
Broker phải xác nhận ghi đủ trên mọi replica mới coi là thành công. |
requestTimeout |
10000 |
Timeout cho mỗi request gửi lên Kafka (ms). |
maxBlock |
5000 |
Thời gian tối đa chờ nếu buffer đầy hoặc Kafka chưa sẵn sàng (ms). |
Bước 4. Publish Message vào Kafka
File:
KafkaProducerApi.xml
Giải thích:
topic:test_topic_01— Topic nhận dữ liệu đầu vào.- Nội dung message là toàn bộ
payloadnhận từ Client. - Không có key, partition cụ thể → Kafka tự điều phối vào các partition.
Bước 5. Trả Response Cho Client (Producer)
Sau khi publish xong, API trả ngay về Client mà không chờ xử lý phía Consumer.
Response thành công:
Response thất bại (faultSequence):
Bước 6. Inbound Endpoint Lắng Nghe Kafka
File:
Load_balance_example.xml
Đây là thành phần chạy ngầm liên tục, tự động poll message từ Kafka.
Toàn bộ tham số cấu hình:
| Tham số | Giá trị | Mô tả |
|---|---|---|
interval |
100 |
Khoảng cách giữa 2 lần poll (ms). |
sequential |
false |
false = đa luồng, tận dụng tối đa CPU. |
coordination |
true |
Tránh consume trùng khi chạy cluster nhiều node. |
suspend |
false |
false = khởi động ngay, không dừng. |
bootstrap.servers |
hdp-master:9092 |
Địa chỉ Kafka Broker kết nối đến. |
topic.name |
test_topic_01 |
Topic mà Inbound Endpoint theo dõi. |
group.id |
group1 |
Tên Consumer Group. Nhiều node cùng group sẽ chia partition. |
contentType |
application/json |
Định dạng nội dung message nhận về. |
poll.timeout |
5000 |
Thời gian chờ khi không có dữ liệu (ms). |
key.deserializer |
StringDeserializer |
Class giải mã Key của message. |
value.deserializer |
StringDeserializer |
Class giải mã Value của message. |
avro.use.logical.type.converters |
false |
Không dùng Avro logical type. |
enable.auto.commit |
true |
Tự commit offset sau khi đọc xong. |
auto.commit.interval.ms |
5000 |
Chu kỳ tự commit offset (ms). |
auto.offset.reset |
latest |
Bắt đầu đọc từ message mới nhất nếu không có offset cũ. |
exclude.internal.topics |
true |
Bỏ qua các topic nội bộ của Kafka. |
check.crcs |
true |
Kiểm tra tính toàn vẹn dữ liệu (CRC). |
partition.assignment.strategy |
RangeAssignor |
Chiến lược phân chia partition cho consumer. |
max.poll.interval.ms |
300000 |
Thời gian tối đa xử lý một đợt poll (5 phút). |
max.poll.records |
500 |
Số message tối đa lấy về mỗi đợt poll. |
fetch.max.wait.ms |
500 |
Thời gian chờ tối đa fetch từ broker nếu chưa đủ data (ms). |
receive.buffer.bytes |
65536 |
Kích thước buffer nhận dữ liệu TCP (64KB). |
send.buffer.bytes |
131072 |
Kích thước buffer gửi dữ liệu TCP (128KB). |
request.timeout.ms |
305000 |
Timeout cho mỗi request gửi đến Broker (ms). |
reconnect.backoff.ms |
50 |
Thời gian chờ trước khi kết nối lại sau lỗi (ms). |
retry.backoff.ms |
100 |
Thời gian chờ trước khi thử lại request thất bại (ms). |
connections.max.idle.ms |
540000 |
Đóng kết nối nếu idle quá thời gian này (9 phút). |
security.protocol |
PLAINTEXT |
Giao thức bảo mật (tắt mã hóa). |
metrics.num.samples |
2 |
Số mẫu dùng để tính metrics. |
metrics.recording.level |
INFO |
Mức độ ghi metrics. |
metrics.sample.window.ms |
30000 |
Cửa sổ thời gian lấy mẫu metrics (30 giây). |
Bước 7. Sequence Xử Lý Message Nhận Được
File:
Load_balance_example-inboundSequence.xml
7.1. Lấy Payload từ Kafka
Các property được tạo:
| Property | Giá trị / Expression | Mô tả |
|---|---|---|
PAYLOAD |
json-eval($) |
Nội dung JSON toàn bộ của message từ Kafka. |
7.2. Gọi Backend API
Thông tin endpoint:
| Trường | Giá trị | Mô tả |
|---|---|---|
uri |
http://192.168.0.133:8080/api/v1/plannings |
URL Backend API nhận dữ liệu. |
Authorization |
Bearer <jwt_token> |
Token xác thực gửi kèm header. |
Content-Type |
application/json |
Định dạng body gửi đến Backend. |
initialDuration |
1000 |
Chờ 1 giây trước khi retry khi lỗi (ms). |
progressionFactor |
1.0 |
Hệ số tăng thời gian retry (1.0 = không tăng). |
maximumDuration |
60000 |
Thời gian chờ tối đa khi retry (60 giây). |
7.3. Lưu Response từ Backend
Các property lưu kết quả:
| Property | Expression | Mô tả |
|---|---|---|
API_RESPONSE |
json-eval($) |
Toàn bộ JSON response từ Backend API. |
HTTP_STATUS |
$axis2:HTTP_SC |
Mã HTTP status code (200, 500...) của Backend. |
RESPONSE_SIZE |
fn:string-length(...) |
Độ dài chuỗi JSON của response (dùng để log). |
7.4. Đóng Gói Lại Dữ Liệu (payloadFactory)
Cấu trúc JSON đầu ra:
| Trường | Giá trị | Kiểu | Mô tả |
|---|---|---|---|
eventType |
transaction |
String (cố định) |
Phân loại sự kiện. |
source |
bank-transactions |
String (cố định) |
Nguồn gốc dữ liệu. |
data |
${payload} |
Object (JSON động) |
Toàn bộ message gốc nhận từ Kafka. |
7.5. Publish Kết Quả vào Topic Phản Hồi
Các trường publish:
| Trường | Giá trị | Mô tả |
|---|---|---|
configKey |
KafkaConnection |
Tham chiếu đến Local Entry kết nối Kafka. |
topic |
processed_topic |
Topic nhận kết quả đã xử lý. |
partitionNo |
0 |
Partition cố định (0 = partition đầu tiên). |
forwardExistingHeaders |
None |
Không chuyển tiếp header gốc. |
customHeaders |
[] |
Không thêm header tuỳ chỉnh. |
Bước 8. Local Entry - Cấu Hình Kết Nối Kafka Tái Sử Dụng
File:
KafkaConnection.xml
Giải thích:
| Trường | Giá trị | Mô tả |
|---|---|---|
key |
KafkaConnection |
Tên Local Entry dùng để gọi qua configKey. |
connectionType |
KAFKA |
Loại kết nối. |
bootstrapServers |
hdp-master:9092 |
Kafka Broker. |
poolingEnabled |
false |
Không dùng connection pool. |
Bước 9. Xử Lý Lỗi (Error Sequence)
File:
Load_balance_example-inboundErrorSequence.xml
Khi Inbound Endpoint bị lỗi (không parse được message, mất kết nối...), WSO2 MI sẽ kích hoạt sequence lỗi này.
⚠️ Ghi chú: Hiện tại sequence lỗi chỉ log thông báo. Cần bổ sung logic retry hoặc dead-letter queue cho production.
1.5. Luồng Phát Triển & Deploy
Bước 10. Build Project
Output: File Loadbalance_kafka_1.0.0.car trong thư mục target/.
Bước 11. Deploy lên WSO2 MI Server
Tự động qua Maven:
Hoặc copy file .car vào thư mục <WSO2MI_HOME>/repository/deployment/server/carbonapps/.
Cấu hình server deploy (trong
pom.xml):
| Trường | Giá trị | Mô tả |
|---|---|---|
serverUrl |
http://192.168.0.167:9201 |
địa chỉ WSO2 MI Management API. |
userName |
adminvp |
Tài khoản admin MI. |
serverType |
mi |
Loại server WSO2. |
operation |
deploy |
Hành động thực hiện. |
📸 [Ảnh minh họa] — Ảnh chụp Deploy thành công trong WSO2 MI Dashboard
1.6. Sơ Đồ Tổng Thể API Lifecycle
1.7. Phụ Lục: Cấu Hình Build (
pom.xml)
| Tham số | Giá trị | Mô tả |
|---|---|---|
artifactId |
Loadbalance_kafka |
Tên artifact Maven. |
groupId |
com.microintegrator.projects |
Group package. |
version |
1.0.0 |
Phiên bản hiện tại. |
project.runtime.version |
4.4.0 |
Phiên bản WSO2 MI. |
dockerfile.base.image |
wso2/wso2mi:4.4.0 |
Docker base image. |
dockerfile.name |
loadbalance_kafka:1.0.0 |
Tên Docker image output. |
mi-inbound-kafka |
2.0.6 |
Phiên bản connector nhận message từ Kafka. |
mi-connector-kafka |
3.3.10 |
Phiên bản connector gửi message lên Kafka. |
mi-connector-http |
0.1.14 |
Phiên bản connector gọi HTTP. |
1.Cấu trúc dự án
1.1. Mục tiêu chương
Chương này quy định cấu trúc dự án chuẩn và phạm vi quản lý artifact giữa Core Team và các đơn vị Partner, nhằm:
-
Đảm bảo tính ổn định của hệ thống tích hợp
-
Tránh xung đột cấu hình và artifact giữa các đơn vị phát triển
-
Chuẩn hóa cách tổ chức integration artifact trong toàn dự án
-
Tăng khả năng bảo trì, mở rộng và triển khai hệ thống
1.2. Khái niệm và phạm vi áp dụng
Tài liệu này được áp dụng cho:
-
Tất cả các dự án sử dụng nền tảng WSO2 Micro Integrator
-
Core Team: Đội phát triển lõi, chịu trách nhiệm quản lý hạ tầng, cấu hình hệ thống và các thành phần dùng chung
-
Partner Team: Các đơn vị đối tác, chịu trách nhiệm phát triển các luồng nghiệp vụ cụ thể
1.3. Cấu trúc dự án chuẩn
Cấu trúc dự án được tổ chức theo tiêu chuẩn nhằm phân tách rõ ràng giữa cấu hình hệ thống, tài nguyên tích hợp và logic nghiệp vụ, đảm bảo tính nhất quán và khả năng mở rộng trong quá trình phát triển.
Ý Nghĩa Từng thư mục
* Root level
.mvn, mvnw, pom.xml
Project build bằng Maven
-
pom.xml→ quản lý dependency, plugin build WSO2 -
.mvn→ config Maven wrapper
+ deployment/
Cấu hình runtime & deploy
-
deployment.toml→ config server (port, datasource, kafka...) -
docker/→ chạy container (nếu có) -
libs/→ thêm JAR custom (Kafka client, connector...)
+ docs/
Tài liệu project (thiết kế, API spec...)
* Source chính
+ src/main/java
Nếu có custom Java (hiện tại bạn chưa dùng)
+ src/main/wso2mi
Đây là toàn bộ logic integration
+ artifacts/
+ apis/
API nhận request từ client
-
KafkaProducerApi.xml
→ API nhận request → đẩy vào Kafka (producer) -
PlanningDirectApi.xml
→ API gọi trực tiếp backend (không qua Kafka)
+ inbound-endpoints/
Kafka Consumer (cực kỳ quan trọng)
-
Load_balance_example.xml
→ Lắng nghe Kafka topic
→ Khi có message → trigger sequence xử lý
Đây chính là chỗ load balancing bằng Kafka
+ sequences/
Logic xử lý nghiệp vụ
-
Load_balance_example-inboundSequence.xml
→ Xử lý message lấy từ Kafka
→ gọi backend -
Load_balance_example-inboundErrorSequence.xml
→ xử lý lỗi khi fail
+ endpoints/
Định nghĩa backend service
Ví dụ:
-
HTTP endpoint
-
REST API backend
+ local-entries/
Config dùng chung
-
KafkaConnection.xml
→ cấu hình Kafka broker (host, port, topic...)
+ message-stores/
Lưu message (queue trung gian)
Dùng khi:
-
retry
-
đảm bảo không mất dữ liệu
+ message-processors/
Xử lý message từ store
Ví dụ:
-
retry gửi lại
-
xử lý batch
+ proxy-services/
Proxy service (SOAP/HTTP)
Thường dùng khi:
-
wrap service cũ
-
expose service trung gian
+ data-services/
Kết nối database
Tạo API CRUD trực tiếp DB
+ data-sources/
Cấu hình kết nối DB
+ tasks/
Job chạy định kỳ (cron job)
+ templates/
Template tái sử dụng
Giúp:
-
tránh lặp code sequence / endpoint
+ resources/
Tài nguyên bổ trợ
-
conf/→ config runtime (properties) -
connectors/→ Kafka connector JAR -
api-definitions/→ Swagger/OpenAPI -
metadata/→ metadata của artifact
1.4. Quy định chính
1.4.1. Phân quyền quản lý artifact
| Khu vực | Đơn vị quản lý | Quyền chỉnh sửa |
|---|---|---|
deployment/** |
Core Team | Partner không được phép chỉnh sửa |
artifacts/local-entries/** |
Core Team | Partner không được phép chỉnh sửa |
resources/conf/** |
Core Team | Partner không được phép chỉnh sửa |
resources/connectors/** |
Core Team | Partner không được phép chỉnh sửa |
artifacts/apis/** |
Core Team + Partner | Được phép phát triển |
artifacts/sequences/** |
Core Team + Partner | Được phép phát triển |
artifacts/inbound-endpoints/** |
Core Team + Partner | Được phép phát triển |
artifacts/endpoints/** |
Core Team + Partner | Được phép phát triển |
1.4.2. Quy định bắt buộc
Partner không được phép chỉnh sửa trực tiếp các khu vực sau:
-
deployment/** -
artifacts/local-entries/** -
resources/conf/** -
resources/connectors/**
Mọi thay đổi liên quan đến các khu vực trên phải tuân theo quy trình kiểm soát của Core Team, bao gồm:
-
Tạo yêu cầu thay đổi (Core Change Request)
-
Được Core Team xem xét và đánh giá
-
Được Core Team phê duyệt và thực hiện thay đổi
1.5. Cách thực hiện / Quy trình
1.5.1. Quy trình thay đổi artifact dùng chung
Bước 1: Partner xác định nhu cầu thay đổi đối với các khu vực do Core Team quản lý.
Bước 2: Tạo ticket trên hệ thống quản lý công việc (Jira, Redmine hoặc YouTrack) với tiêu đề:
Ví dụ:[CORE CHANGE REQUEST] Thêm Kafka topic mới vào KafkaConnection local-entry
Luồng xử lý
Trạng thái ticket
| Trạng thái | Ý nghĩa |
|---|---|
Open |
Ticket được tạo mới |
Under Review |
Core Team đang đánh giá |
Approved |
Được chấp thuận thực hiện |
Rejected |
Bị từ chối (kèm lý do) |
Implemented |
Core Team đã hoàn thành thay đổi |
Merged |
Đã merge vào nhánh develop |
Bước 3: Core Team thực hiện đánh giá dựa trên các tiêu chí:
-
Phạm vi ảnh hưởng đến các luồng hiện tại
-
Rủi ro liên quan đến cấu hình (ví dụ: Kafka, endpoint, connection)
-
Tính cần thiết và mức độ ảnh hưởng đến hệ thống
Bước 4: Nếu thay đổi được chấp thuận:
-
Core Team thực hiện cập nhật
-
Merge vào nhánh
develop
Bước 5: Partner cập nhật code mới và tiếp tục phát triển.
1.6. Ví dụ minh họa
1.6.1. Trường hợp hợp lệ
Tình huống: Bổ sung xử lý lỗi cho inbound sequence Kafka
artifacts/sequences/Load_balance_example-inboundErrorSequence.xml
→ Được phép chỉnh sửa trực tiếp và tạo Pull Request.
Tình huống: Thêm API mới để nhận dữ liệu
→ Được phép tạo mới hoặc chỉnh sửa, sau đó tạo Pull Request để Core Team review.
1.6.2. Trường hợp không hợp lệ
Tình huống: Thêm Kafka topic vào cấu hình kết nối
→ Không được phép chỉnh sửa trực tiếp.
Phải thực hiện theo quy trình:
-
Tạo ticket:
[CORE CHANGE REQUEST] Thêm topic planning_topic vào KafkaConnection -
Chờ Core Team phê duyệt
-
Core Team thực hiện thay đổi và merge
Tình huống: Thay đổi cấu hình Kafka bootstrap server
resources/conf/config.properties
→ Không được phép chỉnh sửa trực tiếp. Phải tạo Core Change Request.
1.7. Checklist áp dụng
Trước khi commit hoặc tạo Pull Request, cần đảm bảo:
-
Artifact nằm trong các thư mục được phép chỉnh sửa (
artifacts/apis/,artifacts/sequences/,artifacts/inbound-endpoints/,artifacts/endpoints/) -
Không chỉnh sửa
artifacts/local-entries/** -
Không chỉnh sửa
deployment/** -
Không chỉnh sửa
resources/conf/** -
Không chỉnh sửa
resources/connectors/** -
Pull Request đã được Core Team review (nếu ảnh hưởng đến luồng chung)
-
Đã kiểm thử luồng Kafka producer/consumer sau khi thay đổi (nếu có)
Tài liệu này thuộc phạm vi quản lý của Core Team. Mọi thay đổi nội dung phải được Core Team phê duyệt.
2. API Design & Response Standard
2.1. Mục Tiêu Chương
Chương này quy định cấu trúc chuẩn của mỗi integration flow và trách nhiệm của từng artifact layer nhằm:
- Tách biệt rõ ràng các tầng xử lý trong luồng tích hợp
- Giảm phụ thuộc giữa các thành phần artifact
- Dễ bảo trì, mở rộng và kiểm thử từng layer độc lập
- Đảm bảo tính nhất quán giữa các flow trong toàn hệ thống
2.2. Khái Niệm / Phạm Vi Áp Dụng
Quy tắc này áp dụng cho:
- Tất cả các integration flow trong thư mục
artifacts/** - Cả Core Team và Partner Team
- Tất cả các luồng tích hợp mới được phát triển
Cấu Trúc Artifact Chuẩn
Mỗi integration flow gồm các thành phần sau:
Ý Nghĩa Từng Artifact Layer
| Layer | Artifact | Vai trò | Ví dụ |
|---|---|---|---|
| API Layer | apis/*.xml |
Nhận request từ client và trả response |
|
| Mediation Layer | sequences/*-inboundSequence.xml |
Xử lý logic, điều phối luồng |
|
| Error Layer | sequences/*-inboundErrorSequence.xml |
Xử lý và cô lập lỗi |
|
| Consumer Layer | inbound-endpoints/*.xml |
Nhận message từ Kafka topic |
|
| Connection Layer | local-entries/*.xml |
Cấu hình kết nối dùng chung |
|
| Endpoint Layer | endpoints/*.xml |
Định nghĩa backend endpoint | Backend API address |
2.3. Quy Định Chính
Trách Nhiệm Từng Layer
API Layer (apis/)
- Nhận request HTTP từ client (hoặc từ WSO2 APIM Gateway)
- Gọi backend trực tiếp hoặc publish message lên Kafka
- Trả response chuẩn về client
- Không chứa logic nghiệp vụ phức tạp
Mediation Layer (sequences/*-inboundSequence.xml)
- Xử lý message nhận từ Kafka consumer
- Điều phối lời gọi đến backend API
- Phân loại kết quả theo HTTP status code (2xx / 4xx / 5xx)
- Publish kết quả vào
processed_topichoặcerror_topic - Không xử lý lỗi kỹ thuật (dành cho Error Layer)
Error Layer (sequences/*-inboundErrorSequence.xml)
- Bắt lỗi kỹ thuật khi consume message từ Kafka
- Log đầy đủ thông tin:
ERROR_CODE,ERROR_MESSAGE,ORIGINAL_PAYLOAD - Đóng gói và publish message lỗi vào
error_topic - Không retry — chỉ ghi nhận và chuyển sang error topic
Consumer Layer (inbound-endpoints/)
- Kết nối đến Kafka broker và subscribe topic
- Khai báo
sequence(luồng thành công) vàonError(luồng lỗi) - Không chứa logic xử lý
Connection Layer (local-entries/)
- Lưu thông tin kết nối Kafka dùng chung toàn hệ thống
- Chỉ Core Team được phép chỉnh sửa
Quy Tắc Bắt Buộc
API Layer không được chứa logic nghiệp vụ phức tạp
Mọi response trả về client phải theo cấu trúc JSON chuẩn
Error sequence phải luôn publish message vào error_topic
Mediation sequence phải phân loại HTTP status (2xx / 4xx / 5xx)
Cấu Trúc Response Chuẩn
Thành công:
{
"success": true,
"message": "Hồ sơ đã được gửi thành công"
}
Thành công kèm data:
{
"eventType": "transaction",
"source": "<sequence-name>",
"data": { ... }
}
Lỗi từ API Layer:
{
"success": false,
"httpStatus": "400",
"error": { ... }
}
Lỗi kỹ thuật (Error Sequence ghi vào error_topic):
{
"errorSource": "Load_balance_example-inboundEndpoint",
"sourceTopic": "test_topic_01",
"errorType": "KAFKA_CONSUME_ERROR",
"errorCode": "...",
"errorMessage": "...",
"originalPayload": { ... },
"timestamp": "..."
}
2.4. Cách Thực Hiện / Quy Trình
Quy Trình Phát Triển Một Integration Flow Mới
Bước 1: Khai báo Connection (nếu chưa có)
Tạo hoặc tái sử dụng local-entries/KafkaConnection.xml.
Chỉ Core Team thực hiện bước này.
Bước 2: Tạo Inbound Endpoint
Tạo file inbound-endpoints/<flow-name>.xml:
- Khai báo Kafka broker, topic, group ID
- Trỏ
sequenceđến inbound sequence - Trỏ
onErrorđến error sequence
Bước 3: Tạo Error Sequence
Tạo file sequences/<flow-name>-inboundErrorSequence.xml:
- Log đầy đủ
ERROR_CODE,ERROR_MESSAGE,ORIGINAL_PAYLOAD - Build payload lỗi chuẩn
- Publish vào
error_topic
Bước 4: Tạo Inbound Sequence
Tạo file sequences/<flow-name>-inboundSequence.xml:
- Log message nhận được
- Set header xác thực
- Gọi backend API (
<call>) - Phân loại theo HTTP status:
200 / 201→ publish vàoprocessed_topic4xx→ đóng gói lỗi dữ liệu → publish vàoerror_topic5xx→ đóng gói lỗi backend → publish vàoerror_topic
Bước 5: Tạo API (nếu cần điểm vào HTTP)
Tạo file apis/<flow-name>Api.xml:
- Khai báo context path và method
- Set header, gọi backend hoặc publish Kafka
- Trả response chuẩn theo HTTP status
2.5. Ví Dụ Minh Họa
Ví Dụ Đúng — Inbound Sequence phân loại HTTP Status
<!-- Thành công: publish vào processed_topic -->
<filter xpath="get-property('HTTP_STATUS') = '200' or get-property('HTTP_STATUS') = '201'">
<then>
<log level="custom">
<property name="STATUS" value="[KafkaConsumer][SUCCESS] Backend xử lý thành công"/>
</log>
<payloadFactory media-type="json" template-type="default">
<format>{
"eventType": "transaction",
"source": "Load_balance_example-inboundSequence",
"data": ${payload}
}</format>
</payloadFactory>
<kafkaTransport.publishMessages configKey="KafkaConnection">
<topic>processed_topic</topic>
</kafkaTransport.publishMessages>
</then>
<else>
<!-- Lỗi: publish vào error_topic -->
<kafkaTransport.publishMessages configKey="KafkaConnection">
<topic>error_topic</topic>
</kafkaTransport.publishMessages>
</else>
</filter>
Đúng vì:
- Phân loại rõ 2xx (thành công) và lỗi
- Kết quả thành công đi vào
processed_topic - Lỗi được tách riêng vào
error_topic - Sequence không xử lý lỗi kỹ thuật (để cho Error Sequence)
Ví Dụ Đúng — Error Sequence đóng gói lỗi chuẩn
<sequence name="Load_balance_example-inboundErrorSequence">
<!-- Bước 1: Lưu thông tin lỗi -->
<property name="ERROR_CODE" expression="get-property('ERROR_CODE')" scope="default"/>
<property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')" scope="default"/>
<property name="ORIGINAL_PAYLOAD" expression="json-eval($)" scope="default"/>
<!-- Bước 2: Log chi tiết -->
<log level="custom">
<property name="STATUS" value="[KafkaConsumer][ERROR] Lỗi khi xử lý message"/>
<property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
<property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
</log>
<!-- Bước 3: Đóng gói payload lỗi -->
<payloadFactory media-type="json">
<format>{
"errorSource": "Load_balance_example-inboundEndpoint",
"sourceTopic": "test_topic_01",
"errorType": "KAFKA_CONSUME_ERROR",
"errorCode": "$1",
"errorMessage":"$2",
"originalPayload": $3
}</format>
</payloadFactory>
<!-- Bước 4: Publish vào error_topic -->
<kafkaTransport.publishMessages configKey="KafkaConnection">
<topic>error_topic</topic>
</kafkaTransport.publishMessages>
</sequence>
Ví Dụ Sai — Không phân loại HTTP Status
<!-- SAI: Không kiểm tra status, trả về luôn -->
<call>
<endpoint>
<address uri="http://192.168.0.133:8080/api/v1/plannings"/>
</endpoint>
</call>
<respond/>
Sai vì:
- Không kiểm tra HTTP status code từ backend
- Lỗi 4xx / 5xx không được phân loại, không vào
error_topic - Không log trạng thái xử lý
Ví Dụ Sai — API trả về raw data không theo chuẩn
<!-- SAI: Không wrap response theo chuẩn -->
<payloadFactory media-type="json">
<format>{"data": "ok"}</format>
</payloadFactory>
<respond/>
Sai vì:
- Response không nhất quán với chuẩn
success / errortoàn hệ thống
2.6. Checklist Áp Dụng
Trước khi commit integration flow mới:
- Có đủ:
inbound-endpoint,inboundSequence,inboundErrorSequence - Inbound Sequence có phân loại HTTP status (2xx / 4xx / 5xx)
- Thành công publish vào
processed_topic - Lỗi publish vào
error_topic - Error Sequence log đầy đủ:
ERROR_CODE,ERROR_MESSAGE,ORIGINAL_PAYLOAD - Error Sequence đóng gói payload lỗi theo cấu trúc chuẩn
- API Layer trả response theo cấu trúc JSON chuẩn (
success,error) - Không hardcode thông tin kết nối trong Sequence (dùng
local-entries) - PR đã được Core Team review
Tài liệu này thuộc phạm vi quản lý của Core Team — mọi thay đổi phải được Core Team phê duyệt.
3.Cơ chế xác thực (JWT/Bearer)
3.1. Mục Tiêu Chương
Chương này quy định chuẩn xác thực và nguyên tắc thiết kế bảo mật nhằm:
- Đảm bảo cơ chế xác thực thống nhất giữa các integration flow và đơn vị phát triển
- Giúp artifact dễ đọc, dễ hiểu và dễ bảo trì
- Giảm lỗi phát sinh do xử lý token không đúng chuẩn
- Tăng hiệu quả review và kiểm soát chất lượng artifact
- Đảm bảo toàn bộ luồng từ Client → APIM → MI → Backend đều có xác thực nhất quán
- Tích hợp đúng với WSO2 Identity Server (IS) làm trung tâm cấp và xác thực token
3.2. Khái Niệm / Phạm Vi Áp Dụng
Quy định này áp dụng cho:
- Toàn bộ artifact xử lý hoặc chuyển tiếp request qua xác thực
- Core Team và Partner Team
- Tất cả các API, Sequence, Inbound Endpoint trong
artifacts/** - Cấu hình APIM và IS do Core Team quản lý
Kiến Trúc Xác Thực Tổng Thể
Ba Tầng Xác Thực
| Tầng | Thành phần | Vai trò xác thực |
|---|---|---|
| Cấp token | WSO2 Identity Server (IS) | OAuth2 Authorization Server, cấp JWT/Access Token |
| Validate token | WSO2 API Manager (APIM) | Xác thực token tại Gateway trước khi route vào MI |
| Forward token | WSO2 Micro Integrator (MI) | Set Authorization: Bearer header khi gọi backend |
3.3. Quy Định Chính
3.3.1. Quy Tắc Đặt Tên Artifact
Các artifact liên quan xác thực phải đặt tên theo quy ước thống nhất:
| Thành phần | Quy tắc đặt tên | Ví dụ |
|---|---|---|
| REST API | <Name>Api.xml |
|
| Inbound Sequence | <flow>-inboundSequence.xml |
|
| Error Sequence | <flow>-inboundErrorSequence.xml |
|
| Inbound Endpoint | <flow>.xml |
|
| Connection Entry | <Name>Connection.xml |
|
| Backend Endpoint | <Name>Endpoint.xml |
PlanningBackendEndpoint.xml |
3.3.2. Quy Tắc Đặt Property Trong Sequence
Dùng tên property nhất quán khi xử lý token/header:
<!-- Đúng: Tên property rõ ràng, đúng chuẩn -->
<property name="PAYLOAD" expression="json-eval($)" scope="default"/>
<property name="HTTP_STATUS" expression="$axis2:HTTP_SC" scope="default"/>
<property name="ERROR_CODE" expression="get-property('ERROR_CODE')" scope="default"/>
<property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')" scope="default"/>
<!-- Sai: Tên không mô tả ý nghĩa -->
<property name="x" expression="json-eval($)" scope="default"/>
<property name="code" expression="$axis2:HTTP_SC" scope="default"/>
3.3.3. Quy Định Về Logging Xác Thực
Không được bỏ qua bước log khi xử lý request:
<!-- Sai: Không log trạng thái -->
<call>
<endpoint>
<address uri="http://192.168.0.133:8080/api/v1/plannings"/>
</endpoint>
</call>
Phải log đầy đủ các bước:
<!-- Đúng: Log đầy đủ theo chuẩn dự án -->
<log level="custom">
<property name="API_NAME" value="PlanningDirectApi"/>
<property name="STATUS" value="Nhận request, gọi thẳng Backend..."/>
<property name="PAYLOAD" expression="get-property('PAYLOAD')"/>
</log>
3.3.4. Quy Định Về Token / Header Xác Thực
Token dùng để gọi backend phải được set từ local-entries hoặc config.properties — không hardcode trong Sequence:
<!-- SAI: Hardcode token trong Sequence -->
<header name="Authorization" scope="transport"
value="Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiJ9..."/>
<!-- ĐÚNG: Lấy token từ property/config -->
<property name="BACKEND_TOKEN"
expression="get-property('conf:backend.auth.token')"
scope="default"/>
<header name="Authorization" scope="transport"
expression="fn:concat('Bearer ', get-property('BACKEND_TOKEN'))"/>
3.4. Nguyên Lý Tách Biệt Trách Nhiệm (Separation of Concerns)
Tương đương nguyên lý SOLID áp dụng trong hệ thống WSO2:
3.4.1. S — Mỗi Artifact Một Trách Nhiệm
Mỗi artifact chỉ được thực hiện một nhiệm vụ:
| Artifact | Chỉ được làm |
|---|---|
apis/ |
Nhận HTTP request, set header auth, gọi backend/Kafka, trả response |
sequences/*-inboundSequence.xml |
Điều phối luồng message từ Kafka đến backend |
sequences/*-inboundErrorSequence.xml |
Ghi nhận lỗi và publish vào error_topic |
inbound-endpoints/ |
Kết nối Kafka, subscribe topic |
local-entries/ |
Lưu thông tin kết nối và cấu hình dùng chung |
Sai — Error logic nằm trong inbound sequence:
<!-- SAI: Inbound sequence tự xử lý lỗi kỹ thuật -->
<sequence name="myFlow-inboundSequence">
<call>...</call>
<property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
<kafkaTransport.publishMessages configKey="KafkaConnection">
<topic>error_topic</topic>
</kafkaTransport.publishMessages>
<!-- Đây là nhiệm vụ của inboundErrorSequence -->
</sequence>
Đúng — Error sequence riêng biệt:
<inboundEndpoint
sequence="myFlow-inboundSequence"
onError="myFlow-inboundErrorSequence">
3.4.2. O — Mở Rộng Không Sửa Artifact Cũ
Khi thêm topic/luồng mới, tạo artifact mới — không sửa sequence của luồng khác:
<!-- Thêm luồng mới: tạo file riêng -->
<!-- planning_topic-inboundSequence.xml -->
<!-- planning_topic-inboundErrorSequence.xml -->
<!-- planning_topic.xml (inbound endpoint) -->
3.4.3. L — Consumer Tuân Thủ Contract Sequence
Inbound Endpoint phải trỏ đúng sequence và error sequence đã khai báo:
<!-- Sai: onError trỏ sai sequence -->
<inboundEndpoint name="Load_balance_example"
sequence="Load_balance_example-inboundSequence"
onError="someOtherSequence"/> <!-- không tồn tại -->
<!-- Đúng -->
<inboundEndpoint name="Load_balance_example"
sequence="Load_balance_example-inboundSequence"
onError="Load_balance_example-inboundErrorSequence"/>
3.4.4. I — Tách Riêng Local Entry Theo Chức Năng
Không nhét tất cả cấu hình vào một local entry:
<!-- Sai: Một local entry chứa tất cả -->
<localEntry key="AllConfig">
<!-- Kafka config, backend URL, token, ... -->
</localEntry>
<!-- Đúng: Tách riêng -->
<localEntry key="KafkaConnection">...</localEntry>
<localEntry key="BackendConfig">...</localEntry>
3.4.5. D — Phụ Thuộc Config, Không Hardcode
Sequence phụ thuộc vào local-entries và config.properties — không hardcode URL hay token:
<!-- Sai -->
<address uri="http://192.168.0.133:8080/api/v1/plannings"/>
<!-- Đúng -->
<address uri="{$ctx:backend.planning.url}"/>
3.5. Luồng Xác Thực Chuẩn Trong Hệ Thống
3.5.1. Luồng Chuẩn Từ Client Đến Backend
Client
→ [1] Lấy token từ WSO2 IS (/oauth2/token)
→ [2] Gọi API qua WSO2 APIM với Bearer token
→ [3] APIM validate token với WSO2 IS (introspect / JWT verify)
→ [4] APIM route request vào WSO2 MI
→ [5] MI set header Authorization khi gọi backend
→ [6] Backend (Spring Boot) validate JWT
3.5.2. Luồng Kafka Consumer Không Đi Qua APIM
Kafka Topic (test_topic_01)
→ [1] MI Inbound Endpoint consume message
→ [2] MI Inbound Sequence xử lý
→ [3] MI set header Authorization: Bearer <token>
→ [4] MI gọi Backend API
→ [5] Backend validate JWT
→ [6] Kết quả: published_topic hoặc error_topic
Luồng Kafka consumer bypass APIM Gateway — token phải được quản lý thủ công trong MI (lấy từ IS hoặc dùng service account token).
3.5.3. Không Được Phép
<!-- Sai: Gọi backend không có Authorization header -->
<call>
<endpoint>
<address uri="http://192.168.0.133:8080/api/v1/plannings"/>
</endpoint>
</call>
<!-- Sai: API tại APIM không bật Security Scheme -->
<!-- Mọi API publish lên APIM đều phải bật OAuth2 hoặc API Key -->
3.5.4. Luồng Token Trong Kafka Consumer (Chuẩn)
<!-- Bước 1: Lấy token từ config -->
<property name="BACKEND_TOKEN"
expression="get-property('conf:backend.auth.token')"
scope="default"/>
<!-- Bước 2: Set Authorization header -->
<header name="Authorization" scope="transport"
expression="fn:concat('Bearer ', get-property('BACKEND_TOKEN'))"/>
<property name="Content-Type" value="application/json" scope="transport"/>
<!-- Bước 3: Gọi backend -->
<call>
<endpoint>
<address uri="{$ctx:backend.planning.url}">
<suspendOnFailure>
<initialDuration>1000</initialDuration>
<progressionFactor>2.0</progressionFactor>
<maximumDuration>60000</maximumDuration>
</suspendOnFailure>
</address>
</endpoint>
</call>
3.6. Cấu Hình Xác Thực WSO2 APIM & IS
3.6.1. WSO2 IS — Key Manager
WSO2 IS đóng vai trò Key Manager cho APIM:
| Chức năng | Endpoint WSO2 IS |
|---|---|
| Lấy Access Token | POST /oauth2/token |
| Introspect Token | POST /oauth2/introspect |
| Lấy Public Key (JWKS) | GET /oauth2/jwks |
| Revoke Token | POST /oauth2/revoke |
Lấy token từ IS (client_credentials):
POST https://<IS_HOST>:9443/oauth2/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(clientId:clientSecret)>
grant_type=client_credentials&scope=<scope>
3.6.2. WSO2 APIM — API Gateway Security
Mọi API publish lên APIM phải cấu hình:
| Thuộc tính | Giá trị chuẩn |
|---|---|
| Security Type | OAuth2 hoặc API Key |
| Token Validation | IS Introspection / JWT verify |
| Throttling | Theo chính sách dự án |
| CORS | Cấu hình theo môi trường |
3.6.3. JWT Claims Chuẩn Của Hệ Thống
Token JWT cấp bởi WSO2 IS phải chứa:
{
"sub": "admin",
"role": "ADMIN",
"iat": 1771917707,
"exp": 1772004107,
"iss": "https://<IS_HOST>:9443/oauth2/token",
"aud": "...client_id...",
"scope": "..."
}
3.7. Cách Thực Hiện / Quy Trình
Quy Trình Thêm Xác Thực Cho Luồng Mới
Bước 1: Đăng ký OAuth2 Application trong WSO2 IS
- Tạo Service Provider
- Lấy
clientIdvàclientSecret
Bước 2: Cấu hình token trong
backend.auth.token=<access_token_từ_IS>
backend.planning.url=http://192.168.0.133:8080/api/v1/plannings
Bước 3: Trong Sequence, đọc token từ config
<property name="BACKEND_TOKEN"
expression="get-property('conf:backend.auth.token')"/>
<header name="Authorization" scope="transport"
expression="fn:concat('Bearer ', get-property('BACKEND_TOKEN'))"/>
Bước 4: Publish API lên APIM với OAuth2 Security
- Import OpenAPI spec từ
resources/api-definitions/ - Enable Security: OAuth2
- Set Key Manager: WSO2 IS
Bước 5: Test luồng xác thực end-to-end
- Lấy token từ IS
- Gọi API qua APIM với Bearer token
- Verify log trong MI:
STATUS,HTTP_STATUS,PAYLOAD
3.8. Ví Dụ Minh Họa
Ví Dụ Sai — Sequence Không Có Authorization Header
<sequence name="myFlow-inboundSequence">
<call>
<endpoint>
<address uri="http://192.168.0.133:8080/api/v1/plannings"/>
</endpoint>
</call>
<respond/>
</sequence>
Sai vì:
Ví Dụ Sai — Hardcode Token Trong Sequence
<header name="Authorization" scope="transport"
value="Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiJ9..."/>
Sai vì:
- Token hardcode sẽ hết hạn, phải sửa code mỗi lần
- Lộ thông tin xác thực trong source code
- Không thể thay đổi theo môi trường (dev / staging / prod)
Ví Dụ Đúng — Sequence Xác Thực Và Gọi Backend Chuẩn
<sequence name="Load_balance_example-inboundSequence">
<!-- 1. Lưu payload gốc -->
<property name="PAYLOAD" expression="json-eval($)" scope="default"/>
<log level="custom">
<property name="STATUS" value="[KafkaConsumer] Message nhận được từ Kafka"/>
<property name="TOPIC" value="test_topic_01"/>
<property name="PAYLOAD" expression="get-property('PAYLOAD')"/>
</log>
<!-- 2. Set Authorization header từ config -->
<property name="BACKEND_TOKEN"
expression="get-property('conf:backend.auth.token')" scope="default"/>
<header name="Authorization" scope="transport"
expression="fn:concat('Bearer ', get-property('BACKEND_TOKEN'))"/>
<property name="Content-Type" value="application/json" scope="transport"/>
<!-- 3. Gọi backend -->
<call>
<endpoint>
<address uri="{$ctx:backend.planning.url}">
<suspendOnFailure>
<initialDuration>1000</initialDuration>
<progressionFactor>2.0</progressionFactor>
<maximumDuration>60000</maximumDuration>
</suspendOnFailure>
</address>
</endpoint>
</call>
<!-- 4. Kiểm tra phản hồi -->
<property name="HTTP_STATUS" expression="$axis2:HTTP_SC" scope="default"/>
<property name="API_RESPONSE" expression="json-eval($)" scope="default"/>
<log level="custom">
<property name="STATUS" value="[KafkaConsumer] Phản hồi Backend"/>
<property name="HTTP_STATUS" expression="get-property('HTTP_STATUS')"/>
</log>
<!-- 5. Phân loại kết quả -->
<filter xpath="get-property('HTTP_STATUS') = '200' or get-property('HTTP_STATUS') = '201'">
<then>
<kafkaTransport.publishMessages configKey="KafkaConnection">
<topic>processed_topic</topic>
</kafkaTransport.publishMessages>
</then>
<else>
<kafkaTransport.publishMessages configKey="KafkaConnection">
<topic>error_topic</topic>
</kafkaTransport.publishMessages>
</else>
</filter>
</sequence>
[Chỗ này thêm ảnh: WSO2 MI log viewer — hiển thị STATUS, HTTP_STATUS sau khi gọi backend thành công]
Ví Dụ Đúng — API APIM Với OAuth2 Security
# resources/api-definitions/KafkaProducerApi.yaml
openapi: 3.0.0
info:
title: Kafka Producer API
version: 1.0.0
paths:
/kafka-producer:
post:
summary: Publish message lên Kafka
security:
- OAuth2: [] # Bắt buộc xác thực OAuth2 tại APIM
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
'200':
description: Thành công
components:
securitySchemes:
OAuth2:
type: oauth2
flows:
clientCredentials:
tokenUrl: https://<IS_HOST>:9443/oauth2/token
scopes: {}
3.9. Checklist Áp Dụng
Trước khi commit hoặc tạo PR:
Naming
- API artifact:
<Name>Api.xml - Inbound Sequence:
<flow>-inboundSequence.xml - Error Sequence:
<flow>-inboundErrorSequence.xml - Connection Entry:
<Name>Connection.xml
Token & Xác Thực
- Không hardcode Bearer token trong Sequence
- Token lấy từ
config.properties hoặc
local-entries - Mọi lời gọi backend đều có
Authorization: Bearerheader - API publish lên APIM đã bật OAuth2 Security
- Key Manager trỏ đúng về WSO2 IS
Logging
- Sequence log
STATUS,PAYLOADkhi nhận request - Sequence log
HTTP_STATUS,API_RESPONSEsau khi gọi backend - Error Sequence log
ERROR_CODE,ERROR_MESSAGE,ORIGINAL_PAYLOAD
Separation of Concerns
- API Layer không chứa logic điều phối phức tạp
- Error handling nằm trong Error Sequence riêng
- Kết nối Kafka trong
local-entries, không khai báo lại trong Sequence - URL backend lấy từ config, không hardcode
Architecture
- Inbound Endpoint trỏ đúng
sequencevàonError - Luồng thành công publish vào
processed_topic - Luồng lỗi publish vào
error_topic - Không có luồng nào bỏ qua xác thực với backend
3.10. Cấu Trúc Chuẩn Của Một Sequence Xử Lý Nghiệp Vụ
3.10.1. Mục Tiêu
Quy định cấu trúc thống nhất của một inboundSequence nhằm:
- Dễ đọc và dễ review
- Tách rõ: nhận dữ liệu → xác thực → gọi backend → phân loại kết quả
- Tránh thiếu log hoặc thiếu xử lý HTTP status
- Chuẩn hóa cách publish kết quả vào Kafka topic
3.10.2. Cấu Trúc Bắt Buộc
Một inboundSequence phải theo thứ tự:
1. Lưu payload gốc vào property
2. Log thông tin message nhận được
3. Set Authorization header (Bearer token)
4. Gọi backend API (<call>)
5. Lưu HTTP status và response
6. Log phản hồi backend
7. Phân loại theo HTTP status (filter)
- 2xx → publish vào processed_topic
- 4xx → đóng gói lỗi dữ liệu → publish vào error_topic
- 5xx → đóng gói lỗi backend → publish vào error_topic
3.10.3. Quy Định Chi Tiết Từng Bước
1. Lưu payload:
<property name="PAYLOAD" expression="json-eval($)" scope="default"/>
2. Log input:
<log level="custom">
<property name="STATUS" value="[KafkaConsumer] Message nhận được từ Kafka"/>
<property name="PAYLOAD" expression="get-property('PAYLOAD')"/>
</log>
3. Set header xác thực (từ config, không hardcode):
<property name="BACKEND_TOKEN"
expression="get-property('conf:backend.auth.token')"/>
<header name="Authorization" scope="transport"
expression="fn:concat('Bearer ', get-property('BACKEND_TOKEN'))"/>
4. Gọi backend:
<call>
<endpoint>
<address uri="{$ctx:backend.planning.url}">
<suspendOnFailure>
<initialDuration>1000</initialDuration>
<progressionFactor>2.0</progressionFactor>
<maximumDuration>60000</maximumDuration>
</suspendOnFailure>
</address>
</endpoint>
</call>
5–6. Lưu và log phản hồi:
<property name="HTTP_STATUS" expression="$axis2:HTTP_SC" scope="default"/>
<property name="API_RESPONSE" expression="json-eval($)" scope="default"/>
<log level="custom">
<property name="HTTP_STATUS" expression="get-property('HTTP_STATUS')"/>
<property name="RESPONSE_BODY" expression="get-property('API_RESPONSE')"/>
</log>
7. Phân loại kết quả:
<filter xpath="get-property('HTTP_STATUS') = '200' or get-property('HTTP_STATUS') = '201'">
<then>
<!-- publish processed_topic -->
</then>
<else>
<filter xpath="get-property('HTTP_STATUS') >= '400' and get-property('HTTP_STATUS') < '500'">
<then>
<!-- 4xx: lỗi dữ liệu → error_topic -->
</then>
<else>
<!-- 5xx: lỗi backend → error_topic -->
</else>
</filter>
</else>
</filter>
3.10.4. Ví Dụ Sequence Sai
Sai vì: Không có Bearer token, không log, không phân loại HTTP status, không publish kết quả.
3.10.5. Checklist Review Sequence
Khi review một inboundSequence:
- Có lưu
PAYLOADvào property trước khi xử lý - Có log thông tin nhận message
- Có set
Authorization: Bearerheader (từ config, không hardcode) - Có log HTTP status sau khi gọi backend
- Có phân loại HTTP status: 2xx / 4xx / 5xx
- 2xx →
processed_topic - 4xx và 5xx →
error_topic - Không xử lý lỗi kỹ thuật trong sequence này (để cho Error Sequence)
Tài liệu này thuộc phạm vi quản lý của Core Team — mọi thay đổi phải được Core Team phê duyệt.
4. Logging & Audit trong Sequence
4.1. Mục tiêu chương
Chương này quy định cách kiểm soát các thay đổi liên quan đến cấu trúc dữ liệu nhằm:
-
Tránh mất dữ liệu hoặc lỗi hệ thống
-
Đảm bảo tương thích giữa các module
-
Ngăn xung đột schema khi nhiều đơn vị cùng phát triển
-
Bảo vệ các field và bảng dữ liệu chuẩn của hệ thống
4.2. Khái niệm / phạm vi áp dụng
Quy định này áp dụng cho:
-
Tất cả các entity trong hệ thống
-
Tất cả các bảng database
-
Core Team và Partner Team
-
Mọi thay đổi liên quan đến:
Các loại thay đổi cần kiểm soát
-
Thêm field mới
-
Xóa field
-
Sửa field
-
Đổi kiểu dữ liệu
-
Thay đổi quan hệ entity
-
Thêm/xóa bảng database
4.3. Quy định chính
4.3.1. Không được tự ý thay đổi các field chuẩn
Các field chuẩn hệ thống:
-
id
-
created_at
-
created_by
-
updated_at
-
updated_by
-
deleted / status
-
tenant_id (nếu có)
Quy định bắt buộc
Không được:
-
Xóa field chuẩn
-
Đổi kiểu dữ liệu
-
Đổi tên field
-
Thay đổi ý nghĩa nghiệp vụ của field
Các field này được coi là system fields và được dùng chung cho:
-
Audit
-
Logging
-
Multi-tenant
-
Phân quyền
-
Tích hợp hệ thống
4.3.2. Thêm field mới trong module
Partner chỉ được phép thêm field khi:
-
Phục vụ nghiệp vụ của module
-
Không trùng với dữ liệu core
-
Không phá vỡ cấu trúc hiện tại
-
Có migration script
-
Có mô tả trong Pull Request
-
Được Core Team review
4.3.3. Các thay đổi bắt buộc xin phép Core Team
Các thay đổi sau không được tự ý thực hiện:
-
Đổi kiểu dữ liệu field
-
Xóa field
-
Đổi tên field
-
Thay đổi quan hệ entity
-
Thêm field liên quan:
-
user
-
role
-
permission
-
tenant
-
audit
Tất cả các trường hợp trên phải qua:
Data Model Change Request
4.4. Cách thực hiện / quy trình
Trường hợp 1: Thêm field trong module
Bước 1: Cập nhật entity trong:
modules/<module>/entity/**
Bước 2: Tạo migration script:
V<timestamp>__add_<field>_to_<table>.sql
Bước 3: Tạo Pull Request, trong PR phải có:
-
Mô tả field mới
-
Lý do nghiệp vụ
-
Migration script
Bước 4: Core Team review:
-
Không trùng core data
-
Không phá vỡ hệ thống
Bước 5: Merge vào develop
Trường hợp 2: Thay đổi field hoặc quan hệ entity
Bước 1: Tạo ticket: các phần mềm quản lý công việc liên quan (Jira / Redmine / YouTrack) hoặc nội bộ
[DATA MODEL CHANGE REQUEST] <mô tả thay đổi>
Bước 2: Cung cấp thông tin:
-
Entity bị ảnh hưởng
-
Field thay đổi
-
Kiểu dữ liệu cũ và mới
-
Migration script
-
Lý do thay đổi
Bước 3: Core Team review:
-
Đánh giá ảnh hưởng hệ thống
-
Kiểm tra backward compatibility
Bước 4: Nếu được duyệt:
-
Core Team thực hiện thay đổi
-
Merge vào develop
4.5. Ví dụ minh họa
Trường hợp hợp lệ
Partner thêm field vào entity module:
@Column(name = "PRIORITY")
private Integer priority;
Và có migration:
ALTER TABLE PLANNING ADD PRIORITY INT;
→ Được phép.
Trường hợp không hợp lệ
Partner sửa:
@Column(name = "CREATED_AT")
private String createdAt;
→ Đổi kiểu dữ liệu từ timestamp sang string.
→ Không được phép.
Phải tạo:
[DATA MODEL CHANGE REQUEST]
Trường hợp cần xin phép
Partner muốn:
-
Xóa field status
-
Đổi tên description → detail
-
Thêm quan hệ với bảng user_account
4.6. Checklist áp dụng
Trước khi commit hoặc tạo PR:
-
Có thay đổi field chuẩn không?
-
Nếu có → phải tạo Data Model Change Request
-
Có đổi kiểu dữ liệu field không?
-
Nếu có → phải xin phép Core Team
-
Có migration script chưa?
-
Field mới có trùng dữ liệu core không?
-
PR đã mô tả rõ thay đổi chưa?
5.Git Workflow & Pull Request
5.1. Mục tiêu chương
Chương này quy định chuẩn commit và quy trình merge code nhằm:
-
Đảm bảo lịch sử thay đổi rõ ràng, dễ truy vết
-
Giảm xung đột giữa các nhóm phát triển
-
Đảm bảo chất lượng code trước khi đưa vào nhánh chính
-
Chuẩn hóa quy trình phát triển giữa Core Team và Partner
5.2. Khái niệm / phạm vi áp dụng
Quy định này áp dụng cho:
-
Tất cả repository của dự án
-
Core Team và Partner Team
-
Mọi commit và Pull Request (PR)
Quy trình phát triển tuân theo:
-
Chuẩn format commit
-
Chiến lược branch
Điều kiện merge bắt buộc
5.3. Quy định chính
5.3.1. Format commit
Tất cả commit phải theo format:
<type>: <description>
Trong đó:
-
<type>: loại thay đổi
-
<description>: mô tả ngắn gọn nội dung thay đổi
Ví dụ commit hợp lệ
feat: add planning API
fix: validate file upload
refactor: optimize planning service
docs: update API guideline
test: add unit test for planning service
chore: update dependency versions
Type hợp lệ
|
Type |
Ý nghĩa |
|
feat |
Thêm chức năng mới |
|
fix |
Sửa lỗi |
|
refactor |
Tối ưu, không đổi logic |
|
docs |
Cập nhật tài liệu |
|
test |
Thêm hoặc sửa test |
|
chore |
Thay đổi cấu hình, build, dependency |
5.3.2. Branch strategy
Hệ thống sử dụng mô hình branch chuẩn:
|
Branch |
Mục đích |
|
main |
Bản stable, dùng cho production |
|
develop |
Bản tích hợp, nơi merge các feature |
|
feature/* |
Phát triển chức năng mới |
|
fix/* |
Sửa lỗi |
Quy tắc làm việc với branch
-
Không commit trực tiếp vào main
-
Không commit trực tiếp vào develop
-
Mọi thay đổi phải qua Pull Request
-
Branch phải được đặt tên đúng quy tắc
Ví dụ tên branch hợp lệ
feature/planning-create-api
feature/document-upload
fix/login-null-pointer
fix/planning-date-validation
5.3.3. Điều kiện merge Pull Request
Pull Request chỉ được merge khi đáp ứng đầy đủ các điều kiện:
-
Build thành công
Không sửa:
common/**
config/**
Có review từ Core Team
5.4. Cách thực hiện / quy trình
Quy trình phát triển tính năng
Bước 1: Tạo branch từ develop
git checkout develop
git pull
git checkout -b feature/planning-create-api
Bước 2: Thực hiện commit theo chuẩn
git commit -m "feat: add planning create API"
Bước 3: Push branch lên remote
git push origin feature/planning-create-api
Bước 4: Tạo Pull Request vào develop
Bước 5: Core Team review
Bước 6: Nếu đạt yêu cầu → merge vào develop
Quy trình sửa lỗi
Bước 1: Tạo branch fix
git checkout develop
git checkout -b fix/planning-null-error
Bước 2: Commit
git commit -m "fix: handle null planning name"
Bước 3: Tạo PR và chờ review
5.5. Ví dụ minh họa
Trường hợp commit sai
Sai vì:
-
Không theo format chuẩn
-
Không có type
Trường hợp commit đúng
fix: handle null planning name
Trường hợp merge sai
Partner:
-
Commit trực tiếp vào develop
-
Không tạo PR
-
Không có review
→ Vi phạm quy trình.
Trường hợp merge đúng
-
Tạo branch feature/planning-api
-
Commit theo chuẩn
-
Tạo PR vào develop
-
Core Team review
-
Build pass
-
Merge
5.6. Checklist áp dụng
Trước khi tạo Pull Request:
-
Commit đúng format <type>: <description>
-
Branch đúng quy tắc feature/* hoặc fix/*
-
Không commit trực tiếp vào main hoặc develop
-
Build thành công
-
Không sửa:
-
common/**
-
config/**
-
shared entity
-
PR đã được Core Team review
6.Checklist kiểm tra trước khi merge
6.1. Mục tiêu chương
Chương này quy định checklist bắt buộc trước khi merge code nhằm:
-
Đảm bảo chất lượng code trước khi tích hợp
-
Tránh vi phạm các quy định về kiến trúc và dữ liệu
-
Giảm rủi ro lỗi khi build hoặc triển khai
-
Chuẩn hóa quy trình review giữa Core Team và Partner
6.2. Khái niệm / phạm vi áp dụng
Checklist này áp dụng cho:
-
Tất cả Pull Request (PR)
-
Core Team và Partner Team
-
Mọi module trong hệ thống
Checklist được dùng trong:
-
Code review
-
Kiểm tra trước khi merge vào develop
Kiểm tra trước khi release
6.3. Quy định chính
Pull Request chỉ được phép merge khi đáp ứng đầy đủ các điều kiện sau:
Code nằm trong khu vực được phép:
modules/**
- Không sửa các khu vực bị cấm:
common/**
config/**
common/entity/**
- Nếu có thay đổi database:
-
Phải có migration script
-
API phải đúng chuẩn:
/api/v1/<module-name>
-
Response phải dùng:
ApiResponse<T>
7.Build phải thành công
6.4. Cách thực hiện / quy trình
Quy trình kiểm tra trước khi merge
Bước 1: Dev hoàn thành feature hoặc fix bug
Bước 2: Tạo Pull Request vào develop
Bước 3: Dev tự kiểm tra checklist
Bước 4: Core Team review theo checklist
Bước 5: Nếu đạt yêu cầu → merge
Nếu không đạt:
-
PR bị reject
-
Dev phải sửa lại theo checklist
6.5. Ví dụ minh họa
Trường hợp hợp lệ
PR:
Chỉ sửa code trong:
modules/planning/**
- Có migration: V20260210__add_priority_to_planning.sql
- API: /api/v1/planning
-
Build thành công
→ Được merge.
Trường hợp không hợp lệ
PR:
Sửa file:
common/entity/UserEntity.java
→ Vi phạm quy định shared entity.
→ PR bị từ chối.
Trường hợp bị từ chối do thiếu migration
PR:
Thêm field trong entity:
private Integer priority;
-
Không có migration SQL
→ PR bị reject.
6.6. Checklist áp dụng
Dev phải tick đủ các mục sau trước khi merge:
[ ] Code nằm trong modules/**
[ ] Không sửa common/**
[ ] Không sửa config/**
[ ] Có migration nếu thay đổi DB
[ ] API đúng chuẩn /api/v1/
[ ] Response dùng ApiResponse
[ ] Build thành công
Core Team chỉ merge khi checklist đạt đầy đủ.
7.Quy trình phối hợp & quản lý thay đổi các nhóm
7.1. Mục tiêu chương
Chương này quy định cách phối hợp giữa nhiều đơn vị phát triển nhằm:
-
Tránh xung đột giữa FE, BE và Database
-
Đảm bảo tích hợp ổn định
-
Giữ tính tương thích giữa các module
-
Kiểm soát các thay đổi ảnh hưởng hệ thống
7.2. Khái niệm / phạm vi áp dụng
Áp dụng khi:
-
Có nhiều đơn vị cùng phát triển
-
FE và BE tách source
-
Nhiều FE dùng chung BE
-
BE tách thành nhiều service
Mọi thay đổi liên quan:
-
API contract
-
Entity/Database
-
Auth
-
Domain/CORS
đều phải thông qua Core Team.
7.3. Quy định chính
Nguyên tắc chung
-
Dùng contract-first (OpenAPI là nguồn chuẩn)
-
Mọi thay đổi API hoặc DB phải được kiểm soát
-
Mọi thay đổi breaking phải qua Core Team
Trường hợp FE và BE khác source, dùng chung DB
Rủi ro:
-
Sai contract API
-
Response làm FE vỡ
-
Migration xung đột
Quy định:
-
BE thay đổi API/DB phải update OpenAPI
-
Mọi thay đổi DB phải có migration
-
Staging dùng DB chung
Quy trình:
-
FE tạo ticket: API CONTRACT ISSUE
-
BE/Core xác nhận
-
Fix backward compatible hoặc tạo API v2
Trường hợp FE và BE dùng DB riêng khi dev
Quy định:
-
Có DB baseline chung
-
Staging dùng DB chung
Quy trình:
-
Nếu staging lỗi → so version migration
-
Không cho merge nếu thiếu migration
Trường hợp nhiều FE dùng chung một BE
Quy định:
-
Dùng IdP chung (WSO2/Keycloak)
-
Mỗi FE là một OAuth client riêng
-
Gọi API bằng JWT
Quy trình:
-
FE đăng ký client_id
-
Core cấu hình redirectUri, scope
-
Core cấp quyền
Trường hợp FE chung source, BE nhiều service
Quy định:
-
FE cấu hình baseURL theo service
-
Auth dùng token chung
-
CORS do Core Team quản lý
Quy trình:
-
Thêm service → tạo Integration Checklist
-
Core cấu hình CORS và token audience
Trường hợp thay đổi response làm FE vỡ
Quy định:
-
Chỉ được thêm field (non-breaking)
-
Không đổi kiểu dữ liệu
-
Không rename field
-
Breaking change phải tạo /api/v2
Quy trình:
-
Tạo BREAKING CHANGE REQUEST
-
Core duyệt
-
Thông báo FE
Trường hợp xung đột entity/model
Quy định:
-
Entity dùng chung → coi là shared model
-
Phải qua Data Model Change Request
Quy trình:
-
Partner đề xuất field + migration
-
Core review
-
Approve hoặc yêu cầu sửa
Trường hợp migration xung đột
Quy định:
-
Không sửa migration đã merge
-
Tạo migration mới để fix forward
Quy trình:
-
Rebase
-
Tạo migration mới
-
Test staging
Trường hợp seed/master data bị sửa
Quy định:
-
Seed core do Core Team quản lý
-
Partner chỉ được đề xuất
Quy trình:
-
Tạo MASTER DATA REQUEST
-
Core duyệt và triển khai
7.4. Quy trình triển khai tính năng nhiều tầng
-
Tạo ticket Feature
-
Chốt API contract (OpenAPI)
-
Chốt entity/migration
-
BE implement
-
FE integrate
-
Test staging
-
Release
7.5.Ví dụ minh họa
1. bảng mô tả các môi trường hệ thống:
| Env | FE URL | BE URL | DB | Auth |
|---|---|---|---|---|
| dev | http://localhost:4200 | http://localhost:8080 | local | mock |
| staging | https://staging.app.vn | https://staging.api.vn | shared | WSO2 thật |
| prod | https://app.vn | https://api.vn | prod | WSO2 thật |
8. Prompt Template cho AI Agent tạo API trên LifeESB
8.1. Vai trò và Nhiệm vụ (System Prompt)
Copy đoạn văn bản sau đưa cho AI:
Vai trò: Bạn là một Chuyên gia Kiến trúc Tích hợp (Integration Architect) hệ thống WSO2 Micro Integrator (MI) 4.4.0. Nhiệm vụ của bạn là đọc các bản đặc tả API (Use Cases) từ người dùng và tự động sinh ra mã nguồn XML chuẩn xác, có thể chạy được ngay của WSO2 MI.
Tiêu chuẩn Thiết kế (Bắt buộc tuân thủ 100%):
- Kiến trúc REST: Mọi API phải được bọc trong thẻ
<api context="/... " name="...">. Các Use Case bên trong được chia thành các thẻ<resource methods="..." uri-template="...">.- Phân tách Endpoint: Cấm hardcode URL trực tiếp vào
<call>. Mọi URL gọi xuống backend phải được định dạng trong một file<endpoint>độc lập.- Cấu hình Môi trường: Trong file
<endpoint>, thuộc tínhuri-templatecủa<http>BẮT BUỘC phải dùng định dạng System Properties:$SYSTEM:TEN_BIEN_CUA_DICH_VU.- Xử lý Dữ liệu mặc định là XML: Payload đi qua hệ thống mặc định là XML. Trừ khi được yêu cầu đổi sang JSON, còn lại không tự ý dùng DataMapper hay
<property name="messageType" value="application/json"/>.- Trích xuất thông tin: Trong
inSequencecủa API, phải có các property sử dụng XPath để lấy các trường quan trọng từ payload XML đầu vào (nhưrequestId,procedureCode,registrationId...).- Ghi Log (Observability): Ngay sau khi vào
inSequencevà trích xuất property, phải có thẻ<log level="custom">để in ra Console thông tin request (bao gồm Use Case ID đang chạy và các biến vừa lấy).- Xử lý Ngoại lệ: Mọi
<resource>bắt buộc phải có<faultSequence>để bẫy lỗi và trả response.- Đầu ra (Output Mode): Chỉ in ra kết quả là các khối mã XML rõ ràng kèm tên file (comment ở dòng đầu), không giải thích dài dòng trừ khi người dùng hỏi.
8.2. Kiến thức Nền tảng (Few-Shot Examples)
Cung cấp cho AI đoạn mã mẫu sau làm chuẩn mực (Golden Template):
Dưới đây là Mẫu Code Tiêu Chuẩn bạn phải học theo:
Mẫu 1: File API định tuyến (ReceivingAPI.xml)
<?xml version="1.0" encoding="UTF-8"?> <api context="/api/v1/receiving/registrations" name="ReceivingAPI" xmlns="http://ws.apache.org/ns/synapse"> <resource methods="POST" uri-template="/"> <inSequence> <log level="custom"> <property name="Status" value="[UC-22] Received New Registration Request"/> <property name="requestId" expression="//requestId/text()"/> <property name="procedureCode" expression="//procedureCode/text()"/> </log> <call> <endpoint key="BackendReceivingCreateEndpoint"/> </call> <respond/> </inSequence> <outSequence/> <faultSequence> <log level="custom"><property name="Error" value="[UC-22] Failed"/></log> <respond/> </faultSequence> </resource> </api>Mẫu 2: File Endpoint độc lập (BackendReceivingCreateEndpoint.xml)
<?xml version="1.0" encoding="UTF-8"?> <endpoint name="BackendReceivingCreateEndpoint" xmlns="http://ws.apache.org/ns/synapse"> <http method="post" uri-template="$SYSTEM:URL_BACKEND_RECEIVING_CREATE"> <suspendOnFailure> <initialDuration>2000</initialDuration> <progressionFactor>1.0</progressionFactor> <maximumDuration>3000</maximumDuration> </suspendOnFailure> </http> </endpoint>
8.3. Cách thức làm việc (User Workflow)
Sau khi lưu 2 đoạn trên làm cấu hình cho Bot (System Instructions), bạn chỉ cần làm việc với nó qua các bước đơn giản mỗi lệnh:
Ví dụ một đoạn Chat bạn nhập vào:
Prompt: "Đây là tài liệu Use Case UC-26: [dán phần text tài liệu UC-26 Định tuyến thông điệp vào đây]. Yêu cầu: Generates file RoutingAPI.xml với context '/api/v1/routing' và các file Endpoints tương ứng. Chú ý sử dụng Switch mediator để rẽ nhánh procedureCode."
Kết quả hoàn hảo bot trả về: Bot sẽ lập tức sinh ra 1 file API có Switch mediator dùng XPath //procedureCode/text() cực chuẩn xác và 2-3 file cấu hình Endpoint $SYSTEM: cho nó.
9. Prompt Template cho AI Agent tạo Test Case API LifeESB
Bản Prompt này được tối ưu để hướng dẫn AI sinh ra các kịch bản kiểm thử (Test Cases), cURL commands, và Postman Collection dựa trên tài liệu đặc tả API và file mã nguồn WSO2 MI.
9.1. Vai trò và Nhiệm vụ (System Prompt)
Copy đoạn văn bản sau đưa cho AI:
Vai trò: Bạn là một QA / API Testing Engineer cấp cao chuyên về nền tảng tích hợp WSO2 Micro Integrator (MI). Nhiệm vụ của bạn là đọc các bản đặc tả Use Case và đoạn mã XML API của WSO2, từ đó sinh ra bộ Test Case hoàn chỉnh để kiểm thử API hoạt động đúng nghiệp vụ.
Tiêu chuẩn Thiết kế Test Case (Bắt buộc tuân thủ 100%):
- Dữ liệu Mặc định là XML: Mặc dù đặc tả có thể mô tả bằng JSON, nhưng Client giao tiếp với MI qua định dạng XML. Tất cả các Test Case payload (
Body) BẮT BUỘC phải viết dưới dạng chuỗi XML hợp lệ.- Cấu trúc Test Case: Mỗi Use Case phải có ít nhất 2 nhóm Test Case gốc:
- Happy Path (Thành công): Dữ liệu chuẩn, mô phỏng luồng đi trót lọt (
HTTP 200/202).- Negative Path (Báo lỗi): Dữ liệu cố tình làm sai (VD: thiếu dòng/sai XML, logic sai như thiếu chữ ký...) để kiểm thử khối
<faultSequence>hoặc logic Validate của backend.- Cú pháp Đầu ra (Output Format): Mỗi Test Case phải trình bày rõ ràng 4 phần:
- Tên Test Case: (VD: TC01 - Tiếp nhận đăng ký thành công)
- Endpoint & Method: (VD:
POST http://localhost:8290/api/v1/receiving/registrations)- Headers: Định nghĩa rõ
Content-Type: application/xml(hoặcapplication/jsonnếu có yêu cầu dị biệt).- Request Body (XML): Cấu trúc XML chuẩn xác theo nghiệp vụ.
- Postman/cURL Script: Cung cấp câu lệnh
cURLtương ứng cho nhóm Happy Path để người dùng dễ dàng dán vào Terminal hoặc Import vào Postman test nhanh.- Tập trung vào Giao diện (Integration Edge): Bạn chỉ test lớp Integration (Gateway/MI). Hãy chú ý truyền đúng các Param/Path Variable/Body mà WSO2
inSequenceđang cần dùng (nhưrequestId,procedureCode).
9.2. Kiến thức Nền tảng (Few-Shot Examples)
Cung cấp cho AI ví dụ Test Case chuẩn mực sau:
Dưới đây là Mẫu Test Case Tiêu Chuẩn bạn phải học theo:
Use Case Mẫu: UC-22 Tiếp nhận hồ sơ mới (Nhận XML Ingestion)
TC01: Happy Path - Đăng ký hồ sơ thành công (Dữ liệu XML chuẩn mực)
- Method:
POST- URL:
http://localhost:8290/api/v1/receiving/registrations- Headers:
Content-Type: application/xmlAccept: application/xml- Body Raw (XML):
<request> <requestId>REQ_20250228001</requestId> <procedureCode>HQ01</procedureCode> <enterpriseId>DN001</enterpriseId> <documents> <document> <documentType>INV</documentType> <content>Base-64-Encoded-Content</content> </document> </documents> <signature> <signedData>...</signedData> </signature> </request>
- Expected Result: Nhận về HTTP Status
200 OK(Hoặc 202 tuỳ backend) với form Output Payload do Backend nhả ra qua WSO2 MI.cURL để Test nhanh TC01:
bash curl -X POST -H 'Content-Type: application/xml' -H 'Accept: application/xml' -d '<request><requestId>REQ_20250228001</requestId><procedureCode>HQ01</procedureCode><enterpriseId>DN001</enterpriseId><documents><document><documentType>INV</documentType><content>Base-64-Encoded-Content</content></document></documents><signature><signedData>...</signedData></signature></request>' http://localhost:8290/api/v1/receiving/registrationsTC02: Negative Path - Payload XML bị khuyết cấu trúc nghiêm trọng (Lỗi Missing Mandatory Field)
- Mô tả: Gửi cố tình xoá cụm
<procedureCode>để xem khối WSO2 Fault Sequence hoặc Backend có bẫy được không.- Body Raw (XML):
<request> <requestId>REQ_20250228_ERR02</requestId> <!-- Cố tình thiếu procedureCode và enterpriseId --> </request>
- Expected Result: Nhận về chuỗi XML mô tả lỗi, HTTP Code dạng
400 Bad Requesthoặc500.
9.3. Cách thức làm việc (User Workflow)
Sau khi nhập 2 khối trên vào System Context, quy trình bạn ra lệnh sẽ như sau:
Ví dụ một đoạn Chat bạn nhập vào:
Prompt: "Tôi vừa viết xong WSO2 API cho UC-23 (Sửa hồ sơ
/{registrationId}/amend). Đây là nguyên văn tài liệu: [Dán tài liệu UC-23]. Yêu cầu sinh Test Case cho API này theo định dạng XML. Context API gốc chày trên máy tôi là port 8290."
Kết quả hoàn hảo bot trả về: Bot sẽ sinh ra các bộ câu hỏi kiểm thử: HTTP Body (XML) sửa hồ sơ, Path params id kèm cURL Script. Bạn chỉ việc Copy ném vào Postman là bắn test luôn không phải typing mỏi tay định dạng từng dấu ngoặc.