Month: August 2021

  • Triển khai CI/CD cho iOS – In house Distribution với DeployGate

    Triển khai CI/CD cho iOS – In house Distribution với DeployGate

    Một ngày đẹp trời, anh ấy nhận được một cái mail giới thiệu anh là chuyên gia về tài khoản Apple… đó chính ngày định mệnh mở ra con đường Enterprise. Many thanks anh Vũ Béo, người nhanh tay mang ánh sáng về và đặt những bước chân đầu tiên.

    Sam

    Overview

    DeployGate hỗ trợ rất nhiều chế độ Distribution, tuy nhiên để tạo ra sự đa dạng cho series, ở bài viết này chúng ta sẽ sử dụng Enterprise (In house) kết hợp với DeployGate để tạo thành một quy trình CD.

    Nói thêm một chút về DeployGate, đây là một nền tảng hỗ trợ phân phối ứng dụng di động (iOS & Android). Người dùng có thể upload app package (ipa & apk) lên và chia sẻ link cài đặt cho người khác. Sử dụng DeployGate, Tester sẽ không cần phải cài đặt ứng dụng trực tiếp với ipa hay apk file, và cũng không cần sử dụng Window hoặc MacOS để cài đặt. DeployGate cũng giảm bớt sự phụ thuộc của người dùng trong quá trình test vào Test Flight khi thời gian process một số ứng dụng có thể lên tới hàng chục giờ đồng hồ.

    Bài viết sẽ gồm có 3 phẩn:

    1. Distribute IPA sử dụng Command Line
    2. Cấu hình DeployGate để upload IPA bằng Command Line
    3. Cấu hình file .gitlab-ci.yml cho GitlabCI

    Distribute IPA sử dụng Command Line

    Bước đầu tiên của quá trình vẫn là tạo ra được file IPA để upload lên Deploy Gate. Như ở bài trước đã hướng dẫn, ta sẽ sử dụng các câu lệnh sau để thực hiện tạo ra file IPA.

    xcodebuild archive -archivePath "cicd-test" -scheme cicd-test
    xcodebuild -exportArchive  -archivePath "cicd-test.xcarchive" -exportPath "ipa" -exportOptionsPlist ExportOptions.plist -allowProvisioningUpdates

    Với chế độ In House, chúng ta sẽ sử dụng file ExportOptions.plist với nội dung như sau:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>method</key>
    	<string>enterprise</string>
    </dict>
    </plist>

    Sau khi export xong, chúng ta sẽ có một file IPA với đường dẫn tương đối so với vị trí của runner như sau:

    ipa/cicd-test.ipa

    Việc tiếp theo sẽ là upload file IPA lên DeployGate.

    Cấu hình DeployGate để upload IPA bằng Command Line

    Đầu tiên chúng ta cần upload ít nhất một bản IPA lên Deploy Gate, sau đó bật Distribution lên bằng cách ấn vào nút Add a link for sharing trong ảnh sau:

    Ấn vào button [+ Add a link for sharing] phía bên phải

    Sau đó, trang web sẽ điều hướng đến Distribution Page, đừng hoảng, ta chỉ cần copy đường dẫn của trang đó là được. Đường dẫn sẽ có dạng như sau:

    https://deploygate.com/distributions/818c15431b824aac1763f074931ecacaed2a03d5
    DISTRIBUTION_KEY = 818c15431b824aac1763f074931ecacaed2a03d5

    Ta sẽ lưu key phía sau của đường dẫn lại, tạm gọi là DISTRIBUTION_KEY như trên.

    Tiếp đó ta quay lại Dashboard của app như trong ảnh trên và lấy thông tin user từ đường dẫn như sau:

    https://deploygate.com/users/gstdn_test/platforms/ios/apps/com.magz.techover.ios
    USER = gstdn_test
    USER_API_HOST = https://deploygate.com/api/users/gstdn_test/apps

    Cuối cùng của việc cấu hình và thu thập thông tin lên Deploy Gate, ta vào mục Account Setting -> Profile và copy API Key ở dưới cùng của page.

    Copy API Key này nhé bạn

    Ta sẽ có một bộ các thông tin sau:

    USER_API_HOST = https://deploygate.com/api/users/gstdn_test/apps
    DISTRIBUTION_KEY = 818c15431b824aac1763f074931ecacaed2a03d5
    API_KEY = 246147bb-3ab7-4cc8-8fbe-ahihidongoc

    Tiếp đó, ta chỉ cần thực hiện upload IPA file lên Deploy Gate sử dụng các thông tin trên với Command sau:

    Curl -H "Authorization: token $API_KEY" -F "file=@ipa/cicd-test.ipa" -F "message=New distribution" -F "distribution_key=$DISTRIBUTION_KEY" -F "release_note=Release Note" "$USER_API_HOST"

    Response trả về sẽ có dạng Json như sau, nếu error = false thì tức là quá trình upload thành công.

    Response trả về của Curl upload IPA lên Deploy Gate

    Refresh lại Dashboard của app ta sẽ thấy có một bản build mới được upload lên với message “New distribution” như ảnh sau:

    Bản build đã lên với message đi kèm

    Tiếp tục qua trang Update Distribution, ta sẽ thấy bản build mới upload sẽ tự động được cập nhật thành phiên bản được phân phối với Release Notes là “Release Note”.

    Bản build vừa upload được tự động phân phối với Release Note mới

    Như vậy là ta đã hoàn thành việc upload và cập nhật bản build trên Deploy Gate một cách tự động. Tiếp đến là cấu hình các câu lệnh trên vào file .gitlab-ci.yml.

    Cấu hình .gitlab-ci.yml cho GitlabCI

    Rồi, lại tới công chuyện tiếp! Đầu tiên ta cần ném các thông tin Key của Deploy Gate vào mục Variables thay vì setting cứng trong file.

    Luôn đặt các thông tin key, môi trường vào Variables

    Tiếp đến, nội dung của file .gitlab-ci.yml cơ bản sẽ như sau:

    stages:
      - build
    
    build_project:
      stage: build
      script:
        - echo 'Hello bitches, welcome to lazy boys world!'
        - echo 'Just commit code, serve yourself a cup of coffee. Let gitlab build your app!'
        - xcodebuild archive -archivePath "cicd-test" -scheme cicd-test
        - xcodebuild -exportArchive  -archivePath "cicd-test.xcarchive" -exportPath "ipa" -exportOptionsPlist ExportOptions.plist -allowProvisioningUpdates
        - Curl -H "Authorization: token ${API_KEY}" -F "file=@ipa/cicd-test.ipa" -F "message=New distribution" -F "distribution_key=${DISTRIBUTION_KEY}" -F "release_note=Release Note" "${USER_API_HOST}"
      tags:
        - main

    Vậy là xong, sau khi code được commit/merge vào main, GitlabCI sẽ tự động chạy Jobs build IPA và đẩy lên DeployGate. Hẹn gặp lại các bạn ở bài viết tiếp theo!

    P/S: Sẽ rất tiện lợi nếu có thể cấu hình để tuỳ chỉnh Upload Message, Release Note để ghi các thay đổi cho Tester hay thông báo khi có bản build mới lên Deploy Gate. Nên mình sẽ dành riêng một bài trong series để hướng dẫn cách cấu hình các tuỳ chỉnh này.

  • Triển khai CI/CD cho iOS – GitlabCI Artifact

    Triển khai CI/CD cho iOS – GitlabCI Artifact

    Ngày đông giá rét, thay vì ngồi dài cổ đợi ae commit code lên để build cho Tester. Bạn có thể đơn giản add Tester vào Gitlab, cài một con CD Artifact đơn giản và ném vào mặt nó phần việc nhàm chán kia. Còn bạn có thể nhàn nhã mò ra Highlands, nhâm nhi cốc cafe nóng và xem cơm chó của ngày Noel buồn…

    Sam, gửi Cương Good, Anh Mẹc và Very Good Team

    Overview

    Tiếp tục với series CI/CD cho iOS, hôm nay chúng ta sẽ chuyển sang chuyên mục CD với phương thức Deploy đơn giản nhất – GitlabCI Artifact.

    Vì đây là bài viết đầu tiên liên quan đến CD, chúng ta sẽ cần đề cập đến phương thức Archive và Distribute ứng dụng sử dụng command line.

    Distribute IPA sử dụng Command Line

    Để triển khai CD, mọi công việc đều phải thực hiện thông qua Shell Command, do đó từ các công việc Build, Test, Archive hay Distribute IPA đều phải thực hiện bằng các câu lệnh. Rất may, Apple cung cấp sẵn một bộ Command Line Tools được tích hợp kèm với Xcode, ta có thể sử dụng ngay khi máy đã cài đặt Xcode. Các bạn có thể tham khảo hướng dẫn các command tại đây.

    Đầu tiên, chúng ta sẽ cài đặt setting project sang Automatic Signing, đảm bảo thiết bị chạy runner đã đăng nhập tài khoản hợp lệ và build thành công App bằng Xcode.

    Setting Automatically trong Xcode

    Sau khi thành công, ta sẽ thử build project bằng câu lệnh với cú pháp:

    xcodebuild build -scheme cicd-test

    Với tham số -scheme là chỉ định scheme/target để build.

    Build thành công Project trên Terminal

    Sau khi thành công, chứng tỏ là project đã được setting đúng cách, chúng ta sẽ thực hiện archive App bằng câu lệnh sau:

    xcodebuild archive -archivePath "cicd-test" -scheme cicd-test

    Với tham số -archivePath chỉ định tên và đường dẫn export ra .xcarchive file.

    Sau khi chạy xong, chúng ta sẽ thấy có một file được export ra với tên cicd-test.xcarchive trông như ảnh sau:

    Output của quá trình archive app

    Sau khi đã có .xcarchive file, chúng ta cần thực hiện export ra IPA file. Để export được IPA file, chúng ta cần một file ExportOptions.plist, ở đây chúng ta sẽ export bằng chế độ adhoc, file sẽ có nội dung như sau:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>method</key>
    	<string>ad-hoc</string>
    </dict>
    </plist>

    Trong trường hợp IPA cần export ở các chế độ khác, ta sẽ thay ad-hoc bằng các keyword tương ứng sau:

    • Development: development
    • Adhoc: ad-hoc
    • AppStore: app-store
    • Enterprise: enterprise

    Sau đó, thực hiện export IPA bằng câu lệnh sau:

    xcodebuild -exportArchive  -archivePath "cicd-test.xcarchive" -exportPath "ipa" -exportOptionsPlist ExportOptions.plist -allowProvisioningUpdates

    Với các tham số sau đây:

    • -exportPath: Chỉ định thư mục sẽ export ra file IPA
    • exportOptionsPlist: Chỉ định file chưa các config export
    • -allowProvisioningUpdates: Cần phải có nếu Project setting chế độ Automatic Signing. Không cần sử dụng nếu setting manual signing.

    Sau khi export xong, chúng ta sẽ nhận được file IPA ở thư mục như hình sau:

    Vị trí file IPA được export ra

    Như vậy là ta đã tạo xong file IPA, tiếp đến sẽ là setting với GitlabCI

    Cấu hình .gitlab-ci.yml cho GitlabCI

    Rồi tới công chuyện, giờ chúng ta chỉ cần chuyển toàn bộ các câu lệnh ở trên vào phần script của file .gitlab-ci.yml và cấu hình để GitlabCI nhận file IPA làm Artifact là xong.

    File .gitlab-ci.yml cơ bản sẽ có nội dung như sau:

    stages:
      - build
    
    build_project:
      stage: build
      script:
        - echo 'Hello bitches, welcome to lazy boys world!'
        - echo 'Just commit code, serve yourself a cup of coffee. Let gitlab build your app!'
        - xcodebuild archive -archivePath "cicd-test" -scheme cicd-test
        - xcodebuild -exportArchive  -archivePath "cicd-test.xcarchive" -exportPath "ipa" -exportOptionsPlist ExportOptions.plist -allowProvisioningUpdates
      tags:
        - main
      artifacts:
        paths:
          - ipa/cicd-test.ipa

    Sau đó, hãy commit các thay đổi lên và chờ đợi thành quả!

    Thành quả của quá trình là đây

    Như bạn thấy trong ảnh trên, phía bên phải của Jobs Detail sẽ có một section để tải về Job Artifacts chứa file IPA có thể cài được. Ở đây, ta chỉ cần ấn nút Download IPA thực hiện cài đặt ứng dụng vào điện thoại.

    Như vậy là ta đã hoàn thành cấu hình CD đơn giản cho iOS với GitlabCI Artifact. Hẹn gặp các bạn ở bài viết tiếp theo.

  • Tổng quan về Activity Diagram

    Tổng quan về Activity Diagram

    Activity Diagram là gì?

    Activity Diagram là một mô hình logic dùng để mô hình hóa các hoạt động trong một quy trình nghiệp vụ, giúp developer, tester hay chính bản thân BA dễ dàng nắm được các hướng đi của hệ thống.

    Activity diagram là sơ đồ luồng xử lí của hệ thống, bao gồm luồng đi của dòng dữ liệu, dòng sự kiện. Mô tả các hoạt động trong một chức năng của hệ thống – luồng xử lý của một use case. 

    Các thành phần của activity diagram 

    1. Start

    Kí hiệu:

    Đặc điểm:

    • Khởi tạo một hoạt động.
    • Một activity diagram có thể có nhiều trạng thái Start.

    2. Transition

    Kí hiệu:

    Đặc điểm: Mô tả sự chuyển đổi trạng thái của các hoạt động

    3. Activity

    Kí hiệu:

    Đặc điểm:

    • Mô tả hành vi của đối tượng trong quy trình
    • Tên hoạt động phải ngắn gọn, đủ nghĩa. Nên đặt là động từ và mô tả đầy đủ ý nghĩa tổng thể của hoạt động nhất có thể.

    4. Decision

    Kí hiệu:

    Đặc điểm: Đây là kí hiệu biểu thị nút điều kiện chuyển hướng. Tùy theo trường hợp đúng hay sai của kết quả mà có hướng di chuyển tiếp theo tương ứng.

    Decision bao gồm hai loại sau: Branch và Merge

    5. Branch

    Kí hiệu:

    Đặc điểm:

    • Mô tả điều kiện rẽ nhánh
    • Chỉ một dòng điều khiển đi vào
    • Hai hoặc nhiều dòng điều khiển đi ra
    • Chỉ một dòng điều khiển dẫn đến kết quả
    • Mỗi dòng chứa một điều kiện (guard), guard phải liên quan đến điều kiện và loại trừ nhau

    6. Merge

    Kí hiệu:

    Đặc điểm:

    • Có hai hoặc nhiều dòng điều khiển đi vào
    • Chỉ một dòng điều khiển đi ra

    7. Synchronization bar

    Kí hiệu:

    Đặc điểm:

    • Khi có các trường hợp cần hội tụ đủ nhiều luồng điều khiển một lúc để gộp thành một luồng xử lí thì cần dùng JOIN.
    • Khi cần phải tách một luồng điều khiển ra hai hoặc nhiều luồng khác biệt nhau thì cần dùng FORK. Mỗi luồng của FORK hoàn toàn không lệ thuộc nhau.

    Synchronization bar bao gồm hai loại sau: Join và Fork

    8. Join

    Kí hiệu:

    Đặc điểm:

    • Kết hợp các dòng điều khiển song song (FORK)
    • Có hai hoặc nhiều dòng điều khiển vào
    • Chỉ có một dòng điều khiển ra, dòng điều khiển ra được tạo khi tất cả các dòng cần thiết đã vào

    9. Fork

    Kí hiệu:

    Đặc điểm:

    • Mô tả một dòng điều khiển được tách ra thực hiện song song
    • Chỉ có một dòng điều khiển đi vào
    • Có hai hoặc nhiều dòng điều khiển đi ra
    • Dùng FORK khi các hoạt động thực hiện không quan tâm thứ tự

    10. End

    Kí hiệu:

    Đặc điểm:

    • Mô tả trạng thái kết thúc quy trình
    • Một activity diagram có thể có một hoặc nhiều trạng thái kết thúc

    Tổng kết

    Trên đây là những nội dung cơ bản về Activity Diagram, dựa vào nó hi vọng các bạn có thể dễ dàng hình dung và nhanh chóng áp dụng trong công việc!

    Author

    NgânLTM

  • Tổng quan về Business Process Model and Notation (BPMN)

    Tổng quan về Business Process Model and Notation (BPMN)

    Tổng quan về Business Process Model and Notation (BPMN)

    1. BPMN là gì?

    • BPMN là viết tắt của Business Process Model and Notation, trong đó ‘Notation’ nghĩa là ký hiệu, tức BPMN là tập hợp các ký hiệu chuẩn để mô tả quy trình của doanh nghiệp. Hay để mô hình hoá quy trình của doanh nghiệp,
    • BPMN là một trong những vũ khí tối quan trọng. Vì trong công việc mình phải tiếp cận và lắng nghe rất nhiều quy trình nghiệp vụ từ khách hàng.
    • Lắng nghe xong phải tạo document lại. Với mỗi khách hàng khác nhau, mỗi quy trình phức tạp thì document phải cho gọn, cho dễ đọc mà vẫn giữ được nội dung gốc ban đầu thì BPMN chính là công cụ hỗ trợ.
    • Khi mình hiểu được khách hàng, quy trình mà họ thực hiện hàng ngày thì mới nhận ra được đâu là điểm tối ưu trong quy trình của họ và truyền đạt lại những hiện trạng và yêu của khách hàng cho cả team cùng hiểu. Khi đó BPMN là phương pháp tối ưu nhất để truyền đạt lại quy trình này.

    2. Phân biệt BPMN và UML

    • UML là Unified Modeling Language – ngôn ngữ mô hình thống nhất. Là tập hợp các diagram và các ký hiệu để mô tả phần mềm.
    • BPMN hướng tới các quy trình nghiệp vụ, phục vụ cho việc build phần mềm.
    • UML hướng tới xây dựng phần mềm, từng đối tượng cụ thể để phục vụ
    • BPMN tiếp cận theo hướng process – oriented, còn UML tiếp cận theo hướng object – oriented
    • Process – oriented: Tập trung trả lời cho câu hỏi khách hàng phải làm bao nhiêu bước, đó là những bước gì, trong thời gian bao lâu để hoàn thành được công việc, mục tiêu.
    • Object – oriented: Tập trung cho việc mổ xẻ đối tượng theo nhiều chiều khác nhau làm rõ ràng hơn cho việc thiết kế và xây dựng hệ thống. Do đó để có nhiều cách nhìn hơn thì UML có 1 bộ diagram khác nhau, mỗi diagram có một chức năng riêng. Còn BPMN chỉ có 1 diagram duy nhất, bới vì nó chỉ có một mục đích duy nhất là thể hiện được quy trình nghiệp vụ
    • Tóm lại BPMN và UML là hai khái niệm khác nhau hoàn toàn. Nó không những tương phản mà lại còn thích hợp nhau, hỗ trợ nhau trong việc tạo document đầy đủ và cover hết các khía cạnh.

    3. Chi tiết về BPMN

    a) Swim lane

    • Được xem như là linh hồn của BPMN, khác hẳn những diagram khác, nó bao gồm pool và lane
    • Pool là một tổ chức, một bộ phận, phòng ban, một vai trò hoặc một hệ thống nào đó.
    • Lane thể hiện những cá nhân riêng lẻ, người sẽ làm các hoạt động cụ thể.

    b) Activities

    Tập trung vào trả lời câu hỏi làm gì, tức là mô tả tất cả các công việc có trong quy trình.

    Có 4 loại:

    Là những công việc nhỏ, gộp lại thành một quy trình lớn.
    Các giao dịch, nó có thể gồm nhiều task nhỏ khác, mà các task này nó phải logic với nhau.
    Sub-process là các quy trình con nằm trong một quy trình lớn.
    Là bước gọi những step từ quy trình khác mà không cần define lại từ đầu ngay trong quy trình này. Hay hiểu đơn giản là gọi một quy trình đã define trước đó.

    c) Activity Markers

    Thể hiện được hành vi thực hiện các hành động, bao gồm:

    1. Loop: Là một hành động lặp đi lặp lại theo thứ tự

    2. Multi-Instance

    • Đây là một kí hiệu rất dễ nhầm lẫn với loop, cũng là hành động lặp đi lặp lại nhiều lần nhưng cần data set khác nhau.
    • Có 2 loại Parallel (lặp lại nhưng đồng thời, cùng lúc) và Sequential (từng cái một).
    • Để chi tiết hơn có thể note vào quy trình, lặp lại bao nhiêu lần thì mới cho tiến trình chuyển qua bước tiếp.

    3. AdHoc

    • Được hình thành khi cần thiết và dành cho mục đích cụ thể nhất định
    • Sẽ thể hiện ở các task đặc biệt, có một mục đích chuyên đùng cụ thể, thể hiện một thứ gì đó rất đặc biệt và sinh ra chỉ để phục vụ cho một đối tượng hoặc một mục đích duy nhất

    4. Compensation: Cũng chỉ là 1 task bình thường nhưng khác ở chỗ chỉ duy nhất xảy ra sau 1 task cụ thể nào đó.

    d) Task Types

    1. User Task

    • Là task được thực hiện bởi người dùng, trên hệ thống và không thể tách nhỏ ra được nữa.

    Tóm lại BPMN gồm 6 phần chính:k thể hiện sự nhận/ gửi thông tin, tái hiện hoặc 1 data object.

    3. Manual Task

    • Là task được thực hiện bởi người dng, ngoài hệ thống và dược thực hiện một ách thủ công

    4. Service Task

    • Là task được thực hiện t- pt” ở đây có nghĩa là 1 đoạn code được viếc ra để chạy và thực hiện công việc.

    6. Business Rule Task

    • Thể hiện một task mà task đó dựa vào rule nào đó

    => Task type giúp BA thể hiện được tính chất, bản chất của hoạt động. Biết được task này làm việc trong hệ thống hay ngoài hệ thống. Hoặc là task này sẽ chạy tự động hay user sẽ làm

    e) Flow

    1. Sequence Flow

    Thể hiện luồng quy trình

    2. Default Flow

    Luồng đi mặc định của hệ thống, nếu không có gì thay đổi hệ thống sẽ đi theo đường này

    3. Message Flow
    Thể hiện thông tin được trao đổi giữa các lane và pool với nhau

    4. Conditional Flow

    Luồng này luôn đi kèm với 1 điều kiện cụ thể. Khi điều kiện này đạt được, thì quy trình mới chạy theo luông này

    f) Gateways

    • Là cái cổng mà khi đi qua thì luồng sẽ thay đổi tuỳ vào điều kiện khác nhau
    • Có nhiều gateways nhưng BPMN thường dùng 4 loại

    1. Exclusive Gateway
    Hay còn gọi là XOR gateway. Nó thể hiện nhánh này hoặc nhanh kia nhưng chỉ được phép 1 trong 2

    2. Inclusive Gateway
    Cũng tương tự như exclusive gateway nhưng khác ở chỗ nó cho phép xảy ra nhiều nhánh, chứ không duy nhất 1 nhánh như XOR. Tuy nhiên 1 khi các nhánh được active nó phải hoàn thành hết trước khi được merge lại.

    3. Parallel Gateway
    Nghĩa là các nhánh phải cùng xảy ra song song với nhau chỉ cần 1 trong các nhánh chưa được hoàn thành thì các nhánh khác không thể merge lại và quy trình không thể đi tiếp được.

    4. Event – Driven

    • Tức là dưạ vào Event, hướng theo Event mà chạy. Vì cơ bản nó cũng khá giống với vì hai cái này chỉ cho phép một nhánh chạy duy nhất. Nhưng nó khác ở chỗ Exclusive Gateway thì dựa vào điều kiện để chạy, còn Event – Driven Gateway dựa vào event để chạy, tức là khi có một sự kiện nào đó xảy ra thì nó sẽ kích nhánh của điều kiện đó chạy.
    • Condition: đơn giản, trả lời cho câu hỏi ở task trước đó.
    • Event: phức tạp hơn, các event gán vào các nhánh sẽ trả lời chi tiết hơn về các trường hợp thông tin: thời gian, ai làm, làm như thế nào?, sự việc gì xảy ra?

    g) Event

    • Diễn tả một sự việc xảy ra trong quy trình, thường mang yếu tố bên ngoài.
    • Chia làm 3 giai đoạn:
    • Start: bắt đầu
    • Intermedia: ngay tức thì/ở giữa
    • End: kết thúc
    • Event có rất nhiều loại, mỗi loại thể hiện một ý nghĩa khác nhau và không phải lúc nào cũng sử dụng hết. Có hai loại được dùng nhiều nhất đó là:
    • Message Event: diễn tả sự việc gửi và nhận thông tin, có đầy đủ Start, Intermedia, End.
    • Time Event: diễn tả một sự việc liên quan đến thời gian, nhưng chỉ có Start và Intermedia không có End.
    • Phân biệt Start, Intermedia, End event:
    • Start: một vòng nhạt bên ngoài
    • Intermedia: hai vòng tròn bên ngoài
    • End event: một vòng đậm bên ngoài
    • Boundany Event: được thể hiện bởi các Event dính liền với hình chữ nhật bao quanh task
    • Cách dùng này trực diện và đơn giản hơn rất nhiều so với Event – Driven
    • Boundany Event để bắt đầu qua một event khác, đó là:
      • Interrupting Event là khi task A đạt được trong thời gian X và hành động Y xảy ra, thì khi đó quy trình chuyển sang C và dừng lại toàn bộ A.
      • Non – Interrupting Event cũng tương tự nhưng khi qua C, task A vẫn diễn ra bình thường.

    h) Information Artifact

    Thể hiện một thứ rất quan trọng trong bất kỳ quy trình nào, đó là thông tin, dữ liệu

    Tóm lại BPMN gồm 6 phần chính:

    • Swim lance: linh hồn của BPMN, thể hiện hành động theo các vai trò một cách rõ ràng.
    • Activity: thể hiện hành động.
    • Flow: thể hiện luồng đi của hành động.
    • Gateway: thể hiện các cổng điều kiện có trong quy trình.
    • Event: thể hiện sự việc xảy ra trong suốt quá trình.
    • Information Artìact: thể hiện các dữ liệu liên quan.

    Author

    NgânLTM

  • [Spring] ApplicationContext trong Spring Framework

    [Spring] ApplicationContext trong Spring Framework

    Trong bài viết này chúng ta sẽ tìm hiểu chi tiết về ApplicationContext interface.

    ApplicationContext?

    Ta hãy cùng nhớ lại 2 khái niệm DI(Dependency Injection) và IoC(Inversion of Control) gây thương nhớ cho những developer của Spring framework. IoC Container chính là lõi của Spring Framework. IoC Container có chức năng tạo ra các đối tượng, liên kết chúng lại với nhau, cấu hình chúng, và quản lí vòng đời của chúng từ khi tạo ra đến khi bị hủy. IoC container sẽ sử dụng DI để quản lí các thành phần tạo nên một ứng dụng.

    Trong Spring framwork IoC được mô tả qua BeanFactory và ApplicationContext interface. BeanFactory là root interface truy cập vào Spring IoC, cung cấp chức năng cơ bản để quản lí Bean. Còn ApplicationContext là sub-interface cúa BeanFactory interface. Do đó, nó cung cấp tất cả các chức năng cơ bản của BeanFactory cùng nhưng chức năng tiên tiến hơn cho các ứng dụng Spring và phù hợp hơn cho những ứng dụng J2EE.

    Spring Bean

    Trước khi đi chi tiết hơn về ApplicationContext interface ta cần xem qua khái niệm về Spring Bean.

    In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container.
    

    Hay hiểu đơn giản với các ứng dụng Spring, Bean là object được tạo ra và quản lí bới Spring IoC container.

    Cấu hình Bean trong Container

    Để ApplicationContext có thể quản lí được các Bean, ứng dụng phải cũng cấp cấu hình bean cho ApplicationContext container. Ta sẽ có những cách khác nhau cấu hình để cấu hình bean:

    1. XML-Based Configuration
    2. Java-Based Configuration
    3. Annotation-Based Configuration

    XML-Based Configuration

    Cuối cùng với cách cấu hình dựa trên XML, ta sẽ khai báo tất cả các cấu hình của Bean trong một file XML.

    Ta sẽ khai báo Bean cho class UserConfiguration trong một file user-config.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
      <bean id="userService" class="com.cuongnm.applicationcontext.UserService">
        <constructor-arg name="userRepository" ref="userRepository" />
      </bean>
      
      <bean id="userRepository" class="com.cuongnm.applicationcontext.UserRepository" />
    </beans>
    

    Java-Based Configuration

    Cấu hình dựa trên Java bằng cách sử dụng @Bean annotation bên trong 1 lớp @Configuration. Với mỗi @Bean annotation được khai báo đánh dấu cho một method để tạo ra 1 Spring Bean. Và những phương thức này đc chứa trong 1 class được đánh dấu là @Configuration – một class chứa các cấu hình Spring bean.

    Ví dụ:

    @Configuration
    public class UserConfig {
    
      @Bean
      public UserService userService() {
        return new AccountService(userRepository());
      }
    
      @Bean
      public UserRepository userRepository() {
        return new UserRepository();
      }
    }
    

    Bằng cách đưa ra @Configuration ta sẽ xử lí class UserConfig như thẻ bean trong XML

    Annotation-Based Configuration

    Để sử dụng được phương pháp này, đầu tiên ta sẽ cấu hình trong XML để cho phép sử dụng Annotation-Based Configuration trong ứng dụng.

    <context:annotation-config/>
    <context:component-scan base-package="com.cuongnm.applicationcontext"/>
    

    Thẻ context:annotation-config để khai báo cho việc sử dụng annotation-based mappings và thẻ context:component-scan với tham số base-package cho Spring tìm được package chưa các annotated classes.

    Sau đó, ta sẽ sử dụng các annotation được cung cấp bởi Spring để đánh dấu cho các class, method, constructor, field trong Java để cấu hình cho Bean như @Component, @Controller, @Service, @Repository, @Autowired.

    Ví dụ với class UserService được khai báo là một Bean sử dụng @Component annotation:

    @Component
    public class UserService {
      
    }
    

    Ta có thể lấy ra Bean này bằng cách:

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext/user-bean-config.xml");
    UserService userService = context.getBean(UserService.class);
    assertNotNull(userService);
    

    Cách sử dụng ApplicationContext

    Cũng như việc cấu hình cho Bean thì cũng có rất nhiều cách sử dụng ApplicationContext interface.

    1) ClassPathXmlApplicationContext

    Phương pháp này sẽ tải các Bean config từ các file XML nằm trong đường dẫn classpath.

    ApplicationContext context = new ClassPathXmlApplicationContext ("user-bean-config.xml");
    

    2) FileSystemXmlApplicationContext

    Sử dụng các Bean config từ các file XML trong FileSystem hay từ URL.

    ApplicationContext context = new FileSystemXmlApplicationContext (“c: /myconfig.xml”);
    

    3) AnnotationConfigApplicationContext

    AnnotationConfigApplicationContext được sử dụng với Java-Based Configuration cho các cấu hình Bean.

    Ví dụ:

    public static void main(String[]args){
    /* Creating Spring IoC Container Without XML configuration file*/
    ApplicationContext context= new AnnotationConfigApplicationContext(UserConfig.class);
    MyBean beanObj = context.getBean(UserService.class);
    }
    

    Với ví dụ này ApplicationContext được lấy từ UserConfig class. Chúng ta lấy các cấu hình Bean từ một class được chú thích @Configuratation và nó sẽ được khai báo:

    @Configuration
    public class UserConfig {
    
      @Bean
      public UserService userService() {
        return new AccountService(userRepository());
      }
    
      @Bean
      public UserRepository userRepository() {
        return new UserRepository();
      }
    }
    

    3) XmlWebApplicationContext và AnnotationConfigWebApplicationContext

    XmlWebApplicationContext được sử dụng để đại diện cho Spring container trong ứng dụng Web. Và nó tải các cấu hình bean từ những file XML với mặc định từ đường dẫn “/WEB-INF/applicationContext.xml”. Chúng ta cũng có thể chỉ định được dẫn của nó qua tham số contextConfigLocation của ContextLoaderListener hoặc DispatcherServlet trong web.xml.

    Giống như XmlWebApplicationContext là class tương ứng với ClassPathXmlApplicationContext và FileSystemXmlApplicationContext và được sử dụng để tạo ra ApplicationContext cho các ứng dụng web, tương tự, AnnotationConfigWebApplicationContext là class tương ứng với AnnotationConfigApplicationContext.

    Lời kết

    Tóm tắt lại những gì mình muốn nói ở bài viết này, mục đích giúp chúng ta hiểu về ApplicationContext trong Spring, hiểu cách sử dụng, triển khai ApplicationContext. Cũng như cách gọi Spring container bằng ApplicationContext mang đến nhiều chức năng hơn so với BeanFactory.

    Bài viết được tham khảo từ “https://www.baeldung.com/spring-application-context“.

    Cảm ơn các bạn đã đọc bài viết!

  • AWS CDK là gì ?

    AWS CDK là gì ?

    Infrastructure as Code

    Khái niệm này đã có rất nhiều bài viết nói về. Nên mình chỉ trích dẫn nội dung chính như bên dưới.

    Infrastructure as code (IaC) is the process of managing and provisioning computer data centers through machine-readable definition files, rather than physical hardware configuration or interactive configuration tools. The IT infrastructure managed by this process comprises both physical equipment, such as bare-metal servers, as well as virtual machines, and associated configuration resources. The definitions may be in a version control system. It can use either scripts or declarative definitions, rather than manual processes, but the term is more often used to promote declarative approaches.

    Để hiểu rõ hơn về IaC, mọi người đọc link bên dưới nhé. https://magz.techover.io/2021/08/19/infrastructure-as-code/

    AWS CDK

    • AWS (AWS CDK) là một framework phát triển phần mềm mã nguồn mở để xác định cơ sở hạ tầng đám mây trong mã và cung cấp nó thông qua AWS CloudFormation.

    • Nó cung cấp tính trừu tượng hướng đối tượng mức cao để xác định tài nguyên AWS một cách phân cấp bằng cách sử dụng sức mạnh của các ngôn ngữ lập trình hiện đại. Sử dụng thư viện cấu trúc cơ sở hạ tầng của CDK, bạn có thể dễ dàng đóng gói các phương pháp hay nhất của AWS vào định nghĩa cơ sở hạ tầng của mình và chia sẻ nó mà không cần lo lắng về logic bản soạn sẵn.

    • AWS CDK có hỗ trợ hạng nhất cho TypeScript, JavaScript, Python, Java và C #.

    cdk

    Tại sao nên sử dụng AWS CDK ?

    • AWS CDK cho phép phát triển hạ tầng với code và triển khai nó lên AWS qua CloudFormation. Bạn sẽ nhận được toàn bộ lợi ích của CloudFormation.

    • Sử dụng các ngôn ngữ lập trình, công cụ và quy trình làm việc quen thuộc – AWS CDK cho phép bạn phát triển cơ sở hạ tầng bằng TypeScript, Python, Java và .NET.

    • Triển khai cơ sở hạ tầng và runtime code cùng nhau – AWS CDK cho phép bạn tham chiếu các runtime code của mình trong cùng một dự án với cùng một ngôn ngữ lập trình

    • Sử dụng logic (câu lệnh if, vòng lặp for, v.v.) khi xác định cơ sở hạ tầng của bạn

    • Sử dụng các kỹ thuật hướng đối tượng để tạo mô hình hệ thống của bạn

    • Xác định các nội dung tóm tắt ở cấp độ cao, chia sẻ và xuất bản chúng cho nhóm, công ty hoặc cộng đồng của bạn

    • Tổ chức dự án của bạn thành các mô-đun hợp lý

    • Chia sẻ và sử dụng lại cơ sở hạ tầng của bạn làm thư viện

    • Kiểm tra mã cơ sở hạ tầng của bạn bằng các giao thức tiêu chuẩn ngành

    cdk

    Cấu trúc CDK Code

    Apps

    • Chạy chương trình
    • Render and triển khai cfn templates

    Stacks

    • Đơn vị triển khai
    • Gồm thông tin region và account id

    Constructs

    • Đại diện các tài nguyên AWS
    • Có thể hình thành cấu trúc cây phân cấp

    cdk

    • Chúng là các tệp bao gồm mọi thứ cần thiết để triển khai ứng dụng của bạn lên môi trường đám mây.

    • Đơn vị triển khai trong AWS CDK được gọi là stack. Tất cả các tài nguyên AWS được xác định trong phạm vi của một stack, trực tiếp hoặc gián tiếp, đều được cung cấp như một đơn vị duy nhất. Vì AWS CDK stack được triển khai thông qua AWS CloudFormation stack nên chúng có những hạn chế giống như trong AWS CloudFormation.

    • Construct là các khối xây dựng cơ bản của ứng dụng AWS CDK. Một cấu trúc đại diện cho một "thành phần đám mây" và đóng gói mọi thứ AWS CloudFormation cần để tạo thành phần đó.

    CDK Lifecycle

    • CDK (với sự trợ giúp của AWS CLI) biên dịch App của nó (App sẽ chạy chương trình có chứa các StackConstruct)
    • CDK tổng hợp mã để chuyển nó thành mẫu CloudFormation. Khi bạn chạy cdk, hãy triển khai mã mà chúng tôi đã đặt trong lib / <code_name> .ts được phân tích cú pháp bởi CDK Framework, sau đó tạo một mẫu CloudFormation nằm trong thư mục cdk.out và cuối cùng triển khai nó vào CloudFormation.
    • Mẫu CloudFormation được triển khai trong tài khoản AWS và chạy để tạo tất cả các thành phần AWS

    cdk

    AWS workflow

    cdk

    Đây chỉ là phần giới thiệu về AWS CDK trong chuỗi bài viết về AWS CDK, mình sẽ làm demo ở bài viết sau nhé. Mong mọi người ủng hộ.

    Tham khảo: https://dev.to/aws-builders/everything-about-aws-cdk-489m

  • AWS Certificate Manager là gì ?

    AWS Certificate Manager là gì ?

    Chứng chỉ SSL miễn phí

    Khi nói đến chứng chỉ SSL miễn phí, chắc hẳn bạn sẽ nghĩ ngay đến Let’s Encrypt. Nhưng thật ra thì, AWS Certificate Manager cũng cung cấp chứng chỉ SSL miễn phí. Bản chất ACM là một dịch vụ sẵn có miễn phí, cung cấp chức năng quản lý chứng chỉ SSL. Bạn không cần phải trả thêm gì khác ngoài chi phí cho các tài nguyên AWS mà bạn tạo ra để chạy ứng dụng.

    AWS Certificate Manager

    Với AWS Certificate Manager, bạn có thể nhanh chóng yêu cầu một chứng chỉ và triển khai chứng chỉ đó trên các tài nguyên AWS được tích hợp ACM( chẳng hạn như các dịch vụ Elastic Load Balancer, Amazon CloudFront và API Gateway,…) đồng thời cho phép AWS Certificate Manager xử lý các yêu cầu gia hạn chứng chỉ. Dịch vụ này còn cho phép bạn tạo các chứng chỉ riêng cho các tài nguyên nội bộ trong hệ thống mạng của mình và quản lý vòng đời của chứng chỉ một cách tập trung.

    acm

    Cách cấu hình

    Ở phần này mình sẽ không nói cách cấu hình như nào vì các bạn có thể tham khảo trên tài liệu của AWS đã có hướng dẫn rất đầy đủ. Mình sẽ tập trung nói về các điểm lợi điểm hại của các cách cấu hình.Với ACM chúng ta sẽ có 3 cách cấu hình chính:

    Cách 1: Import certificate

    Cách này chỉ dùng khi chúng ta đăng kí domain từ bên thứ 3 khác không phải là AWS. Với domain mà bạn tự mua thì có thể dễ dàng sẽ lấy được certificate và key chain. Nhưng nếu domain của khách hàng của bạn thì họ sẽ rất khó để cung cấp chúng cho bạn. Đôi khi họ cũng chỉ là nguời mới không lưu trữ cái đó chả hạn. Đặc biệt khi domain hết hạn cần gia hạn lại thì họ cũng phải cung cấp lại các thông tin certificate mới của domain để mình import lại. Nó sẽ làm tốn thêm công sức nhiều. Cho nên cách này mình không khuyến cáo sử dụng.

    case1

    • Certificate body: Certificate issued for a particular domain name
    • Certificate private key: Unencrypted (created without a password) private key.
    • Certificate chain: CA bundle of the issuing Certificate Authority

    Cách cấu hình: https://docs.aws.amazon.com/acm/latest/userguide/import-certificate-api-cli.html

    Cách 2: Request a certificate with email

    Cách này chúng ta sẽ cần điền thông tin email mà mình hoặc khách hàng đã dùng để đăng kí domain từ bên thứ 3 khác. Đôi khi khách hàng họ sẽ quên mất email đăng kí domain là email nào. Hoặc đơn giản họ chỉ là người mới tiếp quản công việc không thể nào biết được. Đặc biệt cách này cũng cần xử lý khi domain hết hạn mà gia hạn lại. Cho nên cách này mình không khuyến cáo sử dụng.

    case1

    Cách cấu hình: https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html

    Cách 3: Request a certificate with DNS validation

    Sau khi đã hoàn thành các bước thì chúng ta sẽ cần export DNS từ phần đăng ký ACM. Chúng ta cần thêm thông tin này trên trang quản trị domain. Với cách này sẽ đảm bảo khách hàng dễ xử lý với việc thêm nó và an toàn cho thông tin certificate domain của khách hàng.

    case1

    Ví dụ: Hệ thống khách hàng xây dựng trên AWS, nhưng lại đăng kí domain với Godday. Chúng ta có thể vào GoDaddy thêm 1 record với type là CNAME. Sau đó lấy các thông tin export từ ACM để điền vào. Hoàn thành bước này thì chúng ta đã đảm bảo phần có thể active được ACM. Ngoài ra với cách này chúng ta sẽ không cần lo lắng về việc khi domain hết hạn và gia hạn lại. Mình sẽ không phải làm gì thêm từ phía ACM. Mình khuyến khích nên sử dụng cách này. Nó sẽ vừa dễ dàng cho mình và cho khách có thể xử lý được mà không bị phụ thuộc certificate của domain hoặc email đã đăng kí.

    godady

    Cách cấu hình: https://docs.aws.amazon.com/acm/latest/userguide/dns-validation.html

  • How to make a super app?

    How to make a super app?

    Ngày nay, các ứng dụng Super app ngày càng phổ biến. Đứng ở phía người dùng, super app là 1 app mà "thứ gì cũng có". Sự xuất hiện của Super app hướng đến sự tiện lợi dành cho người dùng khi mà họ có thể làm mọi thứ trên cùng 1 ứng dụng, từ việc thanh toán tiền điện, nước, đặt xe, đặt vé máy bay, đặt phòng, shopping, …

    Còn đứng ở trên góc nhìn của 1 developer thì sao? Làm thế nào để có thể đưa 1 app vào thành 1 ứng dụng nhỏ bên trong 1 app khác? Nếu đưa nhiều ứng dụng vào trong 1 super app như vậy, size của super app chắc chắn sẽ phải tăng lên rất nhiều. 1 app thông thường sẽ có size từ khoảng 50-150MB. Vậy tại sao 1 super app như shopee, grab, … có rất nhiều mini app lại chỉ có size 300MB?… Đó là 2 trong những câu hỏi mình đã từng băn khoăn về super app và chưa có câu trả lời. Sau 1 khoảng thời gian trực tiếp tham gia phát triển 1 super app, mình đã hiểu hơn về cách phát triển 1 super app.

    Nội dung

    • Super app app, mini app là gì?
    • Nguồn gốc của Super app?
    • Lợi ích của super app?
    • Tạo ra 1 super app?
    • Tổng kết
    • Reference

    Super app, mini app là gì?

    2 thuật ngữ super app và mini app đi song hành cùng với nhau.

    Super app là những app cung cấp nhiều services khác nhau, và những service này có thể được làm từ những team khác nhau.

    Mỗi service mà super app cung cấp được coi là 1 mini app (hay mini programs).

    Lợi ích của super app

    Đối với người dùng

    • 1 Ứng dụng cung cấp nhiều services cho người dùng => Người dùng có thể trải nghiệm nhiều loại dịch vụ, tiện ích ngay trên cùng 1 ứng dụng mà không cần phải chuyển app, hay download 1 app mới. Ví dụ: Zalo là 1 super app, gồm nhiều mini app như: Thanh toán tiền điện/nước, mua vé máy bay, nạp thẻ điện thoại, đặt xe, shoping, … => Người dùng không cần phải down thêm nhiều app mà chỉ cần 1 app là đủ.
    • Tiết kiệm dung lượng điện thoại vì không cần tải các app khác.

    Đối với công ty

    • Chia sẻ được lượng người dùng giữa các super app và mini app với nhau. Ví dụ: Zalo là 1 super app, chứa Lazada là 1 mini app nhỏ => Lazada có thể hưởng được lượng user hiện có của Zalo.
    • super app trở nên sinh động, nhiều tính năng hơn để cạnh tranh với các app khác.
    Công ty xây dựng 1 hệ sinh thái lớn mạnh, thu hút người dùng

    Super App và Mini App kết nối với nhau thế nào?

    Hãy thử suy nghĩ 1 vài câu hỏi sau đây trước khi đọc câu trả lời.

    Câu hỏi 1: Làm thế nào để SuperApp có thể mở được 1 MiniApp?
    Câu trả lời đó là source code của super app phải chứa code của mini app. Nhưng source code của mini app này sẽ được đóng gói dưới dạng framework.
    Team MiniApp sẽ build service mà họ muốn được tích hợp vào super app thành framework, và gửi cho team super app để team super app embed vào source code của họ. Các framework này có những yêu cầu sau:

    • Phải cung cấp 1 public function trả ra 1 View – view này là đầu vào của mini app.
    • Team MiniApp sẽ chỉ build phần service mà họ muốn đưa vào super app thành framework, chứ không build toàn bộ application của họ thành framework. Bởi nếu build toàn bộ app thành framework -> size của framework sẽ tăng lên đáng kể -> size của super app cũng sẽ tăng lên 1 tương đương. Vậy thì mỗi super app sẽ có size lên đến hàng nghìn MB chứ không còn là 300MB nữa.
      Ví dụ: Zalo muốn đưa Service Zalo Pay vào 1 super app khác, thì họ sẽ chỉ build service này thành framework, và đưa cho bên super app tích hợp, chứ ko phải build cả app Zalo thành 1 framework.

    Câu hỏi 2: Nếu mỗi mini app cung cấp 1 kiểu function có tên khác nhau, thì super app phải xử lí thế nào?
    Team SuperApp sẽ tạo ra 1 Interface / Protocol. Interface này sẽ là chuẩn chung cho toàn bộ MiniApp. Sau đó, team SuperApp sẽ đóng gói interface này thành 1 framework, và đưa cho phía mini app implement.

    Triển khai

    Step 1: Xây dựng 1 interface làm chuẩn chung cho các mini app, và dóng gói nó lại thành 1 framework và đưa cho mini app sử dụng.

    Step 2: Team MiniApp implement interface đó, và sau đó build source code thành framework và gửi cho team SuperApp.

    Step 3: SuperApp lấy ra input view mà team MiniApp đã cung cấp để hiển thị.

    Kết quả:

    Tổng kết:

    • Bài viết này chỉ xây dựng một demo đơn giản về xây dựng 1 super app để đem lại 1 cái nhìn tổng quan về cách thức super app và mini app kết nối với nhau.
    • Trên thực tế, để xây dựng 1 super app còn gặp nhiều khó khăn khác như: Authen giữa super app và mini app, thanh toán giữa super app và mini app, … Đó cũng là những bài toán hay cần phải giải quyết.

    Reference

    https://hoangatuan.medium.com/create-a-xcframework-for-ios-986c4fc1421e: Cách tạo framework
    https://www.brandsvietnam.com/congdong/topic/27240-WeChat-da-khoi-nguon-thuat-ngu-Super-App-nhu-the-nao: Lịch sử của super app

    Source code:

  • Software Architecture: Bắt đầu từ đâu? –  Phần cuối: Hard skills và tổng kết

    Software Architecture: Bắt đầu từ đâu? – Phần cuối: Hard skills và tổng kết

    Như mình đã nói ở phần đầu hard skill của developer và software architect khá rõ ràng về mặt tiếp cận, có nhiều nguồn tài liệu để đọc mình có thể list ra ở đây

    • Domain-Driven Design: Tackling Complexity in the Heart of Software
    • Software Architecture for Developers
    • Software Systems Architecture
    • Design It! – From Programmer to Software Architect
    • Software Architecture in Practice
    • Design Patterns – Elements of Reusable Object-Oriented Software
    • Domain Driven Design
    • Systems Architecting: Creating & Building Complex Systems
    • Systemantics: How Systems Work and Especially How They Fail
    • Release It!: Design and Deploy Production-Ready Software (Pragmatic Programmers)
    • The Clean Architecture
    • Patterns of Enterprise Application Architecture
    • The Art of Scalability: Scalable Web Architecture, Processes, and Organizations for the Modern Enterprise
    • Martin Fowler – Patterns of Enterprise Application Architecture (2002)

    Trong đó quyển của Martin Fowler khá đầy đủ và chi tiết.

    Vậy chúng ta cần đọc bao nhiêu sách, biết bao nhiêu loại pattern? Câu trả lời luôn là càng nhiều càng tốt

    Chọn architecture cho dự án

    Hay nói đúng hơn là khi bắt đầu dự án, chúng ta sẽ chọn kiến trúc nào: microservice, event-driven hay layered theo cách truyền thống. Đấy là câu hỏi thường gặp và chả có gì sai khi hỏi như vậy cả vì ai cũng biết rằng phần mềm mà đưa ra thị trường kiểu gì chẳng được thiết kế theo kiến trúc nào đó. Tuy nhiên câu trả lời lại thường khiến chúng ta bất ngờ

    Big bang architecture

    Nghe giống như Big Bang Model (một loại mô hình phát triển phần mềm), và đúng là như thế.

    Khi dự án mới bắt đầu, chúng ta chưa hiểu gì về hệ thống cả, chỉ nên thiết kế và làm kiến trúc chỉ những gì cần thiết. Ví dụ chúng ta chỉ nên quyết định có thể cần integrate 2 hệ thống với nhau mà chưa cần quyết định xem sẽ làm việc đó như nào. Về cơ bản, chúng ta cần tiến hóa architecture theo dự án: những đều chúng ta biết thêm về hệ thống.

    Rất lạ là yêu cầu phần mềm, công nghệ có thể sử dụng và đã sử dụng và business của công ty cũng như khách hàng cần thay đổi hằng ngày, nhưng chúng ta thường nghĩ rằng architecture cần phải cố định.

    Thường thì mình sẽ chọn một architecture vừa đủ dùng trong một thời gian phù hợp với dự án và đội phát triển (tất nhiên không phải là phần mềm kiểu enterprise rồi)

    Và gần như kiến trúc này sẽ được cải tiến cùng với CI/CD trong phần trước đó, nếu kiến trúc đó có vấn đề khi tích hợp với Pipeline thì có nghĩa rằng kiến trúc hoặc Pipeline hoặc cả 2 đều có vấn đề và chúng cần được cải tiến.

    Một dự án cần phát triển một ứng dụng như Tiki chẳng hạn, nhưng Architect lại được bắt đầu với multi tier truyền thống và bạn sẽ có một monolithic web application, ai cũng sẽ thấy rằng, khi bạn cần sửa dù chỉ một phần nhỏ trong header của request, bạn sẽ cần deploy lại cả hệ thống, điều đó không sai nhưng rõ ràng có vấn đề. Điều tất yếu xảy ra kiến trúc sẽ được cải tiến.

    Gần như hiện tại trong quá trình làm dự án, chúng ta có thể thấy rằng nếu như hệ thống có hình dáng giống với một hệ thống nào đó trong quá khứ thì chúng ta sẽ gần như kế thừa và giữ nguyên, trong khi đó các hệ thống chưa xuất hiện bao giờ thì sẽ được quyết định bởi trực giác của Architect trong một quá trình khám phá có kiểm soát.

    Các quyết định này có thể đúng, sai, tăng tiến độ hoặc thậm chí phá hỏng mọi thứ và chúng ta phải rework.

    Khi đó chúng ta có một thứ gọi là Accidental Architecture, tuy nhiên, điều này chưa hẳn đã xấu vì gần như chúng ta không thể tránh khỏi trong quá trình làm dự án và xây dựng hệ thống. Chỉ khi bắt đầu biến những kiến trúc ngẫu nhiên này thành những kiến trúc có chủ đích, chúng ta mới nâng cao hiểu biết của mình về kiến trúc phần mềm.

    Final words

    Có lẽ serires này sẽ dừng ở đây, mình sẽ cố gắng sắp xếp lại một số bài viết liên quan đến chủ đề này trong nhưng bài viết khác.

    THE END.

  • Sử dụng Nginx để truy cập tới một Private S3 Bucket

    Sử dụng Nginx để truy cập tới một Private S3 Bucket

    Bài toán

    Mình được giao nhiệm vụ phát triển một ứng dụng quản lý chi tiêu cho khách hàng. Thông tin các hoá đơn và ảnh trong ứng dụng sẽ được lưu trên S3. Khách hàng có yêu cầu có thể xem được ảnh lưu trên S3 bằng domain của họ thay vì bằng đường link trực tiếp từ S3. Hệ thống Backend của họ đang sử dụng Nginx với Python Flask và mong muốn không sử dụng đến dịch vụ CloudFront.

    Giải pháp

    Sau hồi nguyên cứu mình đã tìm ra giải pháp là có thể dùng Nginx để truy cập tới một private S3 bucket.

    Để có thể demo được giải pháp nên mình sẽ lược bỏ hệ thống cho nó đơn giản hơn so với hệ thống của khách hàng. Đầu tiên giả sử hệ thống trên AWS đã được cấu hình như bên dưới:

    • VPC(10.0.0.0/16) với public subnet và private subnet
    • VPC Endpoint cho s3
    • A static web on ECS Fargate with Nginx
    • 1 trang web tĩnh được triển khai trên dịch vụ ECS Fargate với việc dùng Nginx
    • 1 private S3 bucket để lưu ảnh của trang web.

    Alt Text

    Kết quả sau khi cấu hình xong chúng ta sẽ có 1 trang web như bên dưới. Nhưng hình ảnh mọi nguời thấy là hình ảnh được tải từ trên mạng. Alt Text

    Bây giờ mình sẽ cần thay thể ảnh trên mạng này với ảnh trên S3. Để làm được điều đó các bạn theo dõi tiếp bên dưới nhé. Alt Text

    Thiết lập Nginx và S3

    1. Thay đổi S3 bucket policy để chỉ cho phép lấy dữ liệu từ VPC Endpoint.

    {
        "Version": "2008-10-17",
        "Id": "PolicyForCloudFrontPrivateContent",
        "Statement": [
            {
                "Sid": "Access-to-specific-VPCE-only",
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::demo-static-s3/*",
                "Condition": {
                    "StringEquals": {
                        "aws:sourceVpce": "vpce-0d92e50f230bc8070"
                    }
                }
            }
        ]
    }
    

    2. Tiếp theo là việc quan trọng nhất, chúng ta sẽ cần cấu hình Nginx để có thể tải ảnh từ private S3

    location ~^/image/(.+)$ {
            resolver 10.0.0.2;
            proxy_pass http://s3-ap-southeast-1.amazonaws.com/demo-static-s3/image/$1; 
    }
    
    • resolver: Địa chỉ IP của DNS server trong VPC mà mình đã tạo.

      Ví dụ, VPC của mình tạo có CIRD là 10.0.0.0/16. AWS sẽ dùng 5 IPs bên dưới cho các mục đích bên của họ và mình sẽ không thể sử dụng các IP đó.

      • 10.0.0.0: Network address.
      • 10.0.0.1: Reserved by AWS for the VPC router.
      • 10.0.0.2: Reserved by AWS. The IP address of the DNS server is the base of the VPC network range plus two. For VPCs with multiple CIDR blocks, the IP address of the DNS server is located in the primary CIDR. We also reserve the base of each subnet range plus two for all CIDR blocks in the VPC. For more information, see Amazon DNS server.
      • 10.0.0.3: Reserved by AWS for future use.
      • 10.0.0.255: Network broadcast address. We do not support broadcast in a VPC, therefore we reserve this address.

      => Resolver sẽ có giá trị là 10.0.0.2

      Tham khảo: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Subnets.html

    • proxy_pass: s3 link

      Định dạng: http://s3-ap-southeast-1.amazonaws.com/[main_bucket]/[sub_bucket]/$1

    3. Thay đổi dường dẫn của tải ảnh của trang web

    <div class="container">
        <h1>Hey there</h1>
        <img src="https://cleandevs.com/image/668c1d479e27bb8750823655c83a6c9bd90263f9_hq.jpg"/>
      </div>
    

    4. Cuối cùng mình sẽ deploy lại trang web lên dịch vụ ECS Fargate. Kết quả sẽ như hình bên dưới. Trang web đã hiển thị ảnh được tải từ private S3 bucket

    Alt Text