Red Hat OpenShift Messaging Berbasis Cloud Menggunakan Quarkus dan AMQ Online

Halo semuanya! Ini dia - pos terakhir kami dari seri Quarkus! (Ngomong-ngomong, lihat webinar kami "Ini adalah Quarkus - kerangka kerja asli Jawa Kubernetes . " Kami akan menunjukkan cara memulai dari awal atau mentransfer solusi yang sudah jadi)



Dalam posting sebelumnya kami melihat alat yang tepat yang dapat digunakan untuk mengukur peningkatan yang dilakukan sebagai hasil dari memodernisasi Java. aplikasi.

Dimulai dengan versi 0.17.0, Quarkus mendukung penggunaan Advanced Message Queuing Protocol ( AMQP ), yang merupakan standar terbuka untuk mentransfer pesan bisnis antara aplikasi atau organisasi.

Red Hat AMQ Online adalah layanan yang dibangun berdasarkan proyek EnMasse terbuka dan mengimplementasikan mekanisme pengiriman pesan berdasarkan platform Red Hat OpenShift . Pelajari lebih lanjut tentang cara kerjanya, lihat Di sini (untuk EN) . Hari ini kami menunjukkan cara menggabungkan AMQ Online dan Quarkus untuk membangun sistem pesan modern berbasis OpenShift menggunakan dua teknologi baru yang terkait dengan pemrosesan pesan.

Diasumsikan bahwa Anda telah menggunakan AMQ Online pada platform OpenShift (jika tidak, lihat panduan instalasi ).

Untuk memulai, kita akan membuat aplikasi Quarkus, yang akan menjadi sistem pemrosesan pesanan sederhana menggunakan pesan reaktif. Aplikasi ini akan menyertakan generator pesanan yang mengirim pesanan ke antrian pesan dengan interval tetap, serta pemroses pesanan yang akan memproses pesan dari antrian dan menghasilkan konfirmasi yang dapat dilihat di browser.

Setelah membuat aplikasi, kami akan menunjukkan cara menerapkan konfigurasi sistem pesan di dalamnya dan menggunakan AMQ Online untuk menginisialisasi sumber daya yang kami butuhkan di sistem ini.

Aplikasi Quarkus


Aplikasi Quarkus kami berjalan pada OpenShift dan merupakan versi modifikasi dari amqp-quickstart . Contoh lengkap dari sisi klien dapat ditemukan di sini .

Pesan generator


Generator setiap 5 detik secara monoton mengirimkan pengenal pesanan yang tumbuh ke alamat "pesanan".

@ApplicationScoped
public class OrderGenerator {
 
    private int orderId = 1;
 
    @Outgoing("orders")
    public Flowable<Integer> generate() {
        return Flowable.interval(5, TimeUnit.SECONDS)
        .map(tick -> orderId++);
    }
}

Penangan pesanan


Prosesor pesanan lebih sederhana, itu hanya mengembalikan pengidentifikasi konfirmasi ke alamat "konfirmasi".

@ApplicationScoped
public class OrderProcessor {
    @Incoming("orders")
    @Outgoing("confirmations")
    public Integer process(Integer order) {
        //       <img draggable="false" class="emoji" alt=":-)" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f642.svg">
        return order * 2;
    }
}

Sumber Daya Konfirmasi


Sumber konfirmasi adalah titik akhir HTTP untuk daftar konfirmasi yang dihasilkan oleh aplikasi kami.

@Path("/confirmations")
public class ConfirmationResource {
 
    @Inject
    @Stream("confirmations") Publisher<Integer> orders;
 
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
 
 
    @GET
    @Path("/stream")
    @Produces(MediaType.SERVER_SENT_EVENTS)
    public Publisher<Integer> stream() {
        return orders;
    }
}

Kustomisasi


Untuk terhubung ke AMQ Online, aplikasi kami akan memerlukan beberapa data konfigurasi, yaitu: konfigurasi konektor Quarkus, informasi titik akhir AMQP, dan kredensial klien. Tentu saja, lebih baik menyimpan semua data konfigurasi di satu tempat, tetapi kami akan memisahkannya secara khusus untuk menunjukkan opsi yang memungkinkan untuk menyiapkan aplikasi Quarkus.

Konektor


Konfigurasi konektor dapat disediakan pada tahap kompilasi menggunakan file properti aplikasi:

mp.messaging.outgoing.orders.connector=smallrye-amqp
mp.messaging.incoming.orders.connector=smallrye-amqp

Agar tidak menyulitkan ini, kami akan menggunakan antrian pesan hanya untuk alamat "pesanan". Dan alamat "konfirmasi" di aplikasi kita akan menggunakan antrian di memori.

Endpoint AMQP


Pada tahap kompilasi, nama host dan nomor port untuk titik akhir AMQP tidak diketahui, sehingga mereka perlu diimplementasikan. Titik akhir dapat diatur dalam configmap, yang dibuat oleh AMQ Online, jadi kami akan mendefinisikannya melalui variabel lingkungan di manifes aplikasi:

spec:
  template:
    spec:
      containers:
      - env:
        - name: AMQP_HOST
          valueFrom:
            configMapKeyRef:
              name: quarkus-config
              key: service.host
        - name: AMQP_PORT
          valueFrom:
            configMapKeyRef:
              name: quarkus-config
              key: service.port.amqp

Kredensial


Token akun layanan dapat digunakan untuk mengautentikasi aplikasi kami di OpenShift. Untuk melakukan ini, Anda harus terlebih dahulu membuat ConfigSource khusus yang akan membaca token otentikasi dari sistem file pod:

public class MessagingCredentialsConfigSource implements ConfigSource {
    private static final Set<String> propertyNames;
 
    static {
        propertyNames = new HashSet<>();
        propertyNames.add("amqp-username");
        propertyNames.add("amqp-password");
    }
 
    @Override
    public Set<String> getPropertyNames() {
        return propertyNames;
    }
 
    @Override
    public Map<String, String> getProperties() {
        try {
            Map<String, String> properties = new HashMap<>();
            properties.put("amqp-username", "@@serviceaccount@@");
            properties.put("amqp-password", readTokenFromFile());
            return properties;
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
 
    @Override
    public String getValue(String key) {
        if ("amqp-username".equals(key)) {
            return "@@serviceaccount@@";
        }
        if ("amqp-password".equals(key)) {
            try {
                return readTokenFromFile();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }
        return null;
    }
 
    @Override
    public String getName() {
        return "messaging-credentials-config";
    }
 
    private static String readTokenFromFile() throws IOException {
        return new String(Files.readAllBytes(Paths.get("/var/run/secrets/kubernetes.io/serviceaccount/token")), StandardCharsets.UTF_8);
    }
}

Perakitan dan penyebaran aplikasi


Karena aplikasi harus dikompilasi menjadi file yang dapat dieksekusi, mesin virtual GraalVM diperlukan. Untuk informasi lebih lanjut tentang cara mengatur lingkungan untuk ini, lihat instruksi terkait di Panduan Quarkus .

Kemudian, mengikuti instruksi di sana, Anda perlu mengunduh sumbernya, membangun dan menggunakan aplikasi kami:

git clone https://github.com/EnMasseProject/enmasse-example-clients
cd enmasse-example-clients/quarkus-example-client
oc new-project myapp
mvn -Pnative -Dfabric8.mode=openshift -Dfabric8.build.strategy=docker package fabric8:build fabric8:resource fabric8:apply

Setelah perintah ini, aplikasi akan digunakan, tetapi tidak akan mulai sampai kami mengkonfigurasi sumber pesan yang diperlukan di AMQ Online.

Pengaturan pesan


Sekarang tinggal mengatur sumber daya yang dibutuhkan aplikasi kita dalam sistem pengiriman pesan. Untuk melakukan ini, buat: 1) ruang alamat untuk menginisialisasi titik akhir sistem pesan; 2) alamat untuk mengkonfigurasi alamat yang kami gunakan dalam aplikasi; 3) pengguna sistem pesan untuk mengatur kredensial klien.

Ruang alamat


Objek AddressSpace di AMQ Online adalah sekelompok alamat yang berbagi titik akhir koneksi, serta kebijakan otentikasi dan otorisasi. Saat membuat ruang alamat, Anda dapat menentukan bagaimana titik akhir dari sistem pengiriman pesan akan disediakan:

apiVersion: enmasse.io/v1beta1
kind: AddressSpace
metadata:
  name: quarkus-example
spec:
  type: brokered
  plan: brokered-single-broker
  endpoints:
  - name: messaging
    service: messaging
    exports:
    - name: quarkus-config
      kind: configmap

Alamat


Alamat digunakan untuk mengirim dan menerima pesan. Setiap alamat memiliki tipe yang mendefinisikan semantiknya, serta rencana yang menetapkan jumlah sumber daya yang dipesan. Alamatnya dapat ditentukan, misalnya, seperti ini:

apiVersion: enmasse.io/v1beta1
kind: Address
metadata:
  name: quarkus-example.orders
spec:
  address: orders
  type: queue
  plan: brokered-queue

Pengguna pesan


Untuk mengirim dan menerima pesan ke alamat yang hanya dapat dilakukan oleh aplikasi tepercaya, Anda harus membuat pengguna di sistem pengiriman pesan. Untuk aplikasi yang berjalan di cluster, klien dapat diautentikasi menggunakan akun layanan OpenShift. Pengguna "akun layanan" dapat didefinisikan, misalnya, sebagai berikut:

apiVersion: user.enmasse.io/v1beta1
kind: MessagingUser
metadata:
  name: quarkus-example.app
spec:
  username: system:serviceaccount:myapp:default
  authentication:
    type: serviceaccount
  authorization:
  - operations: ["send", "recv"]
    addresses: ["orders"]

Izin untuk menyesuaikan aplikasi


Agar AMQ Online membuat configmap yang kami gunakan untuk mengimplementasikan informasi titik akhir AMQP, Anda harus menentukan peran dan pengikatan peran (Peranan dan Peranan Peran):

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: quarkus-config
spec:
  rules:
  - apiGroups: [ "" ]
    resources: [ "configmaps" ]
    verbs: [ "create" ]
  - apiGroups: [ "" ]
    resources: [ "configmaps" ]
    resourceNames: [ "quarkus-config" ]
    verbs: [ "get", "update", "patch" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: quarkus-config
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: quarkus-config
subjects:
- kind: ServiceAccount
  name: address-space-controller
  namespace: amq-online-infra

Cara menerapkan konfigurasi


Anda dapat menerapkan konfigurasi perpesanan seperti ini:

cd enmasse-example-clients/quarkus-example-client
oc project myapp
oc apply -f src/main/resources/k8s/addressspace
oc apply -f src/main/resources/k8s/address

Verifikasi aplikasi


Untuk memastikan aplikasi telah dimulai, pertama-tama, kami akan memeriksa apakah alamat yang sesuai dibuat dan aktif:

until [[ `oc get address quarkus-example.prices -o jsonpath='{.status.phase}'` == "Active" ]]; do echo "Not yet ready"; sleep 5; done

Kemudian periksa URL rute aplikasi (cukup buka alamat ini di browser):

echo "http://$(oc get route quarkus-example-client -o jsonpath='{.spec.host}')/prices.html"

Seharusnya terlihat di browser bahwa tiket diperbarui secara berkala ketika pesan dikirim dan diterima oleh AMQ Online.

Untuk meringkas


Jadi, kami menulis aplikasi Quarkus yang menggunakan AMQP untuk pengiriman pesan, mengatur aplikasi ini untuk bekerja pada platform Red Hat OpenShift, dan juga mengimplementasikan konfigurasinya berdasarkan konfigurasi AMQ Online. Kemudian kami membuat manifes yang diperlukan untuk menginisialisasi sistem pengiriman pesan untuk aplikasi kami.

Ini menyimpulkan seri Quarkus, tetapi ada banyak hal baru dan menarik di depan, tetap bersama kami!

All Articles