Π‘ΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ Π² ΠΎΠ±Π»Π°ΠΊΠ° Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Red Hat OpenShift с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° Quarkus ΠΈ AMQ Online

Π—Π΄Ρ€Π°Π²Π΅ΠΉΡ‚Π΅ всички! Π•Ρ‚ΠΎ Π³ΠΎ ΠΈ послСдният Π½ΠΈ пост ΠΎΡ‚ ΠΏΠΎΡ€Π΅Π΄ΠΈΡ†Π°Ρ‚Π° Quarkus! (ΠœΠ΅ΠΆΠ΄Ρƒ Π΄Ρ€ΡƒΠ³ΠΎΡ‚ΠΎ, Π³Π»Π΅Π΄Π°ΠΉΡ‚Π΅ нашия ΡƒΠ΅Π±ΠΈΠ½Π°Ρ€ β€žΠ’ΠΎΠ²Π° Π΅ Quarkus – Ρ€ΠΎΠ΄Π½Π°Ρ‚Π° Java Ρ€Π°ΠΌΠΊΠ° Π½Π° Kubernetesβ€œ. Π©Π΅ Π²ΠΈ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΠΊΠ°ΠΊ Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅Ρ‚Π΅ ΠΎΡ‚ Π½ΡƒΠ»Π°Ρ‚Π° ΠΈΠ»ΠΈ Π΄Π° ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΠΈΡ‚Π΅ Π³ΠΎΡ‚ΠΎΠ²ΠΈ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ)

Π‘ΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ Π² ΠΎΠ±Π»Π°ΠΊΠ° Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Red Hat OpenShift с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° Quarkus ΠΈ AMQ Online

Π’ ΠΏΡ€Π΅Π΄ΠΈΡˆΠ΅Π½ Π’ Ρ‚Π°Π·ΠΈ публикация Ρ€Π°Π·Π³Π»Π΅Π΄Π°Ρ…ΠΌΠ΅ ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΈΡ‚Π΅ инструмСнти, ΠΊΠΎΠΈΡ‚ΠΎ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Π·Π° количСствСно опрСдСлянС Π½Π° подобрСнията, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈ Π² Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ Π½Π° ΠΌΠΎΠ΄Π΅Ρ€Π½ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° Java прилоТСния.

ΠžΡ‚ вСрсия 0.17.0, ΠšΠ²Π°Ρ€ΠΊΡƒΡ ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Advanced Message Queuing Protocol (AMQP), ΠΊΠΎΠΉΡ‚ΠΎ Π΅ ΠΎΡ‚Π²ΠΎΡ€Π΅Π½ стандарт Π·Π° ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° бизнСс ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρƒ прилоТСния ΠΈΠ»ΠΈ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ.

Red Hat AMQ ΠΎΠ½Π»Π°ΠΉΠ½ Π΅ услуга, ΠΈΠ·Π³Ρ€Π°Π΄Π΅Π½Π° Π½Π° Π±Π°Π·Π°Ρ‚Π° Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ с ΠΎΡ‚Π²ΠΎΡ€Π΅Π½ ΠΊΠΎΠ΄ EnMasse ΠΈ внСдряванС Π½Π° Π±Π°Π·ΠΈΡ€Π°Π½ Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ° ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ Red Hat OpenShift. Π—Π° ΠΏΠΎΠ²Π΅Ρ‡Π΅ подробности ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚ΠΈ Π²ΠΈΠΆΡ‚Π΅ Ρ‚ΡƒΠΊ (EN). ДнСс Ρ‰Π΅ Π²ΠΈ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΠΊΠ°ΠΊ Π΄Π° ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€Π°Ρ‚Π΅ AMQ Online ΠΈ Quarkus, Π·Π° Π΄Π° ΠΈΠ·Π³Ρ€Π°Π΄ΠΈΡ‚Π΅ ΠΌΠΎΠ΄Π΅Ρ€Π½Π° систСма Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ, Π±Π°Π·ΠΈΡ€Π°Π½Π° Π½Π° OpenShift, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ Π΄Π²Π΅ Π½ΠΎΠ²ΠΈ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ.

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π° сС, Ρ‡Π΅ Π²Π΅Ρ‡Π΅ стС Ρ€Π°Π·ΠΏΠΎΠ»ΠΎΠΆΠΈΠ»ΠΈ AMQ Online Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° OpenShift (Π°ΠΊΠΎ Π½Π΅, Π²ΠΈΠΆΡ‚Π΅ Ρ€ΡŠΠΊΠΎΠ²ΠΎΠ΄ΡΡ‚Π²ΠΎ Π·Π° инсталиранС).

ΠšΠ°Ρ‚ΠΎ Π½Π°Ρ‡Π°Π»ΠΎ Ρ‰Π΅ създадСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Quarkus, ΠΊΠΎΠ΅Ρ‚ΠΎ Ρ‰Π΅ бъдС проста систСма Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΏΠΎΡ€ΡŠΡ‡ΠΊΠΈ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰Π° Ρ€Π΅Π°ΠΊΡ‚ΠΈΠ²Π½ΠΈ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ. Π’ΠΎΠ²Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ‰Π΅ Π²ΠΊΠ»ΡŽΡ‡Π²Π° Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π½Π° ΠΏΠΎΡ€ΡŠΡ‡ΠΊΠΈ, ΠΊΠΎΠΉΡ‚ΠΎ ΠΈΠ·ΠΏΡ€Π°Ρ‰Π° ΠΏΠΎΡ€ΡŠΡ‡ΠΊΠΈ към опашка ΠΎΡ‚ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ Π½Π° фиксиран ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π», ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ процСсор Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΏΠΎΡ€ΡŠΡ‡ΠΊΠΈ, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π²Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ ΠΎΡ‚ ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π° ΠΈ Ρ‰Π΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° ΠΏΠΎΡ‚Π²ΡŠΡ€ΠΆΠ΄Π΅Π½ΠΈΡ, Π²ΠΈΠ΄ΠΈΠΌΠΈ Π² Π±Ρ€Π°ΡƒΠ·ΡŠΡ€Π°.

Π‘Π»Π΅Π΄ ΠΊΠ°Ρ‚ΠΎ създадСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ, Ρ‰Π΅ Π²ΠΈ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΠΊΠ°ΠΊ Π΄Π° Π²Π³Ρ€Π°Π΄ΠΈΡ‚Π΅ конфигурацията Π½Π° систСмата Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΈ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ AMQ Online, Π·Π° Π΄Π° прСдоставим рСсурситС, ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ сС Π½ΡƒΠΆΠ΄Π°Π΅ΠΌ Π² систСмата.

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Quarkus

ΠΠ°ΡˆΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Quarkus Ρ€Π°Π±ΠΎΡ‚ΠΈ Π½Π° OpenShift ΠΈ Π΅ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€Π°Π½Π° вСрсия Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° amqp-Π±ΡŠΡ€Π· старт. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ пълСн ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΎΡ‚ страна Π½Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Ρ‚ΡƒΠΊ.

Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π½Π° ΠΏΠΎΡ€ΡŠΡ‡ΠΊΠΈ

Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ΡŠΡ‚ просто ΠΌΠΎΠ½ΠΎΡ‚ΠΎΠ½Π½ΠΎ ΠΈΠ·ΠΏΡ€Π°Ρ‰Π° нарастващи ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΈ Π½Π° ΠΏΠΎΡ€ΡŠΡ‡ΠΊΠΈ Π΄ΠΎ адрСса Π½Π° β€žΠΏΠΎΡ€ΡŠΡ‡ΠΊΠΈβ€œ Π½Π° всСки 5 сСкунди.

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

ΠŸΡ€ΠΎΡ†Π΅ΡΠΎΡ€ Π½Π° ΠΏΠΎΡ€ΡŠΡ‡ΠΊΠΈ

ΠœΠ°Π½ΠΈΠΏΡƒΠ»Π°Ρ‚ΠΎΡ€ΡŠΡ‚ Π½Π° ΠΏΠΎΡ€ΡŠΡ‡ΠΊΠΈΡ‚Π΅ Π΅ ΠΎΡ‰Π΅ ΠΏΠΎ-прост, Ρ‚ΠΎΠΉ просто Π²Ρ€ΡŠΡ‰Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π·Π° ΠΏΠΎΡ‚Π²ΡŠΡ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ Π½Π° адрСса Π·Π° β€žΠΏΠΎΡ‚Π²ΡŠΡ€ΠΆΠ΄Π΅Π½ΠΈΡβ€œ.

@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;
    }
}

РСсурси Π·Π° ΠΏΠΎΡ‚Π²ΡŠΡ€ΠΆΠ΄Π΅Π½ΠΈΠ΅

Π Π΅ΡΡƒΡ€ΡΡŠΡ‚ Π·Π° ΠΏΠΎΡ‚Π²ΡŠΡ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ Π΅ HTTP ΠΊΡ€Π°ΠΉΠ½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π·Π° изброяванС Π½Π° ΠΏΠΎΡ‚Π²ΡŠΡ€ΠΆΠ΄Π΅Π½ΠΈΡΡ‚Π°, Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½ΠΈ ΠΎΡ‚ Π½Π°ΡˆΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.

@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;
    }
}

Ρ€Π΅Π³ΡƒΠ»ΠΈΡ€Π°Π½Π΅

Π—Π° Π΄Π° сС ΡΠ²ΡŠΡ€ΠΆΠ΅ с AMQ Online, Π½Π°ΡˆΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ‰Π΅ сС Π½ΡƒΠΆΠ΄Π°Π΅ ΠΎΡ‚ някои ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΈ Π΄Π°Π½Π½ΠΈ, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ: конфигурация Π½Π° ΠΊΠΎΠ½Π΅ΠΊΡ‚ΠΎΡ€ Quarkus, информация Π·Π° ΠΊΡ€Π°ΠΉΠ½Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° AMQP ΠΈ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΎΠ½Π½ΠΈ Π΄Π°Π½Π½ΠΈ Π½Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Π Π°Π·Π±ΠΈΡ€Π° сС, ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅ Π΅ всички ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΈ Π΄Π°Π½Π½ΠΈ Π΄Π° сС ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Ρ‚ Π½Π° Π΅Π΄Π½ΠΎ място, Π½ΠΎ Π½ΠΈΠ΅ ΡƒΠΌΠΈΡˆΠ»Π΅Π½ΠΎ Ρ‰Π΅ Π³ΠΈ Ρ€Π°Π·Π΄Π΅Π»ΠΈΠΌ, Π·Π° Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΈΡ‚Π΅ ΠΎΠΏΡ†ΠΈΠΈ Π·Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Quarkus.

Π‘ΡŠΠ΅Π΄ΠΈΠ½ΠΈΡ‚Π΅Π»ΠΈ

ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡΡ‚Π° Π½Π° ΠΊΠΎΠ½Π΅ΠΊΡ‚ΠΎΡ€Π° ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС прСдоставСна ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Π½Π΅ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° Ρ„Π°ΠΉΠ» със свойства Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ:

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

Π—Π° Π΄Π° опростим Π½Π΅Ρ‰Π°Ρ‚Π°, Ρ‰Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ опашка ΠΎΡ‚ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ само Π·Π° адрСса Π½Π° β€žΠΏΠΎΡ€ΡŠΡ‡ΠΊΠΈβ€œ. А Π°Π΄Ρ€Π΅ΡΡŠΡ‚ Π·Π° β€žΠΏΠΎΡ‚Π²ΡŠΡ€ΠΆΠ΄Π΅Π½ΠΈΡβ€œ Π² Π½Π°ΡˆΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ‰Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° опашка Π² ΠΏΠ°ΠΌΠ΅Ρ‚Ρ‚Π°.

ΠšΡ€Π°ΠΉΠ½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° AMQP

По Π²Ρ€Π΅ΠΌΠ΅ Π½Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Π½Π΅ ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° хоста ΠΈ Π½ΠΎΠΌΠ΅Ρ€ΡŠΡ‚ Π½Π° ΠΏΠΎΡ€Ρ‚Π° Π·Π° ΠΊΡ€Π°ΠΉΠ½Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° AMQP са нСизвСстни, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ трябва Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ ΠΈΠ½ΠΆΠ΅ΠΊΡ‚ΠΈΡ€Π°Π½ΠΈ. ΠšΡ€Π°ΠΉΠ½Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС Π·Π°Π΄Π°Π΄Π΅Π½Π° Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚Π°, която Π΅ създадСна ΠΎΡ‚ AMQ Online, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Ρ‰Π΅ Π³ΠΈ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°ΠΌΠ΅ Ρ‡Ρ€Π΅Π· ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π½Π° срСдата Π² манифСста Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ:

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

АкрСдитивни писма

Π’ΠΎΠΊΠ΅Π½ΡŠΡ‚ Π½Π° Π°ΠΊΠ°ΡƒΠ½Ρ‚Π° Π½Π° услугата ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° удостовСряванС Π½Π° Π½Π°ΡˆΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² OpenShift. Π—Π° Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ Ρ‚ΠΎΠ²Π°, ΠΏΡŠΡ€Π²ΠΎ трябва Π΄Π° ΡΡŠΠ·Π΄Π°Π΄Π΅Ρ‚Π΅ пСрсонализиран ConfigSource, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅ Ρ‚ΠΎΠΊΠ΅Π½Π° Π·Π° удостовСряванС ΠΎΡ‚ Ρ„Π°ΠΉΠ»ΠΎΠ²Π°Ρ‚Π° систСма Π½Π° 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);
    }
}

Π˜Π·Π³Ρ€Π°Π΄Π΅Ρ‚Π΅ ΠΈ Ρ€Π°Π·ΠΏΠΎΠ»ΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ

Въй ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ трябва Π΄Π° бъдС ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Π½ΠΎ Π² изпълним Ρ„Π°ΠΉΠ», Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠ° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π° машина GraalVM. Π—Π° подробности ΠΊΠ°ΠΊ Π΄Π° настроитС срСда Π·Π° Ρ‚ΠΎΠ²Π° Π²ΠΈΠΆΡ‚Π΅ ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΈΡ‚Π΅ инструкции Π² Π ΡŠΠΊΠΎΠ²ΠΎΠ΄ΡΡ‚Π²ΠΎ Π·Π° Quarkus.

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π°, слСдвайки инструкциитС, Π΄Π°Π΄Π΅Π½ΠΈ Ρ‚Π°ΠΌ, трябва Π΄Π° ΠΈΠ·Ρ‚Π΅Π³Π»ΠΈΡ‚Π΅ изходния ΠΊΠΎΠ΄, Π΄Π° ΠΈΠ·Π³Ρ€Π°Π΄ΠΈΡ‚Π΅ ΠΈ Π²Π½Π΅Π΄Ρ€ΠΈΡ‚Π΅ Π½Π°ΡˆΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅:

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

Π‘Π»Π΅Π΄ Ρ‚Π΅Π·ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Ρ‰Π΅ бъдС Ρ€Π°Π·Π³ΡŠΡ€Π½Π°Ρ‚ΠΎ, Π½ΠΎ няма Π΄Π° стартира, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ Π½Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°ΠΌΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈΡ‚Π΅ Π½ΠΈ рСсурси Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ Π² AMQ Online.

Настройка Π½Π° систСмата Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ

Π‘Π΅Π³Π° остава само Π΄Π° Π·Π°Π΄Π°Π΄Π΅ΠΌ рСсурситС, ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ Π½Π°ΡˆΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ сС Π½ΡƒΠΆΠ΄Π°Π΅ Π² систСмата Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ. Π—Π° Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ Ρ‚ΠΎΠ²Π°, трябва Π΄Π° ΡΡŠΠ·Π΄Π°Π΄Π΅Ρ‚Π΅: 1) адрСсно пространство Π·Π° ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΊΡ€Π°ΠΉΠ½Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° систСмата Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ; 2) адрСс Π·Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½Π΅ Π½Π° адрСситС, ΠΊΠΎΠΈΡ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ; 3) ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π» Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ Π·Π° Π·Π°Π΄Π°Π²Π°Π½Π΅ Π½Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΎΠ½Π½ΠΈ Π΄Π°Π½Π½ΠΈ Π½Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°.

АдрСсно пространство

ΠžΠ±Π΅ΠΊΡ‚ AddressSpace Π² AMQ Online Π΅ Π³Ρ€ΡƒΠΏΠ° ΠΎΡ‚ адрСси, ΠΊΠΎΠΈΡ‚ΠΎ сподСлят ΠΊΡ€Π°ΠΉΠ½ΠΈ Ρ‚ΠΎΡ‡ΠΊΠΈ Π½Π° Π²Ρ€ΡŠΠ·ΠΊΠ° ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π° Π·Π° удостовСряванС ΠΈ оторизация. ΠšΠΎΠ³Π°Ρ‚ΠΎ ΡΡŠΠ·Π΄Π°Π²Π°Ρ‚Π΅ адрСсно пространство, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° посочитС ΠΊΠ°ΠΊ ΠΊΡ€Π°ΠΉΠ½ΠΈΡ‚Π΅ Ρ‚ΠΎΡ‡ΠΊΠΈ Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ ΠΈΠ·Π»ΠΎΠΆΠ΅Π½ΠΈ:

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

адрСс

АдрСситС сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Π·Π° ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Π½Π΅ Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ. ВсСки адрСс ΠΈΠΌΠ° Ρ‚ΠΈΠΏ, ΠΊΠΎΠΉΡ‚ΠΎ опрСдСля Π½Π΅Π³ΠΎΠ²Π°Ρ‚Π° сСмантика, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ ΠΏΠ»Π°Π½, ΠΊΠΎΠΉΡ‚ΠΎ опрСдСля броя Π½Π° рСсурситС, ΠΊΠΎΠΈΡ‚ΠΎ трябва Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€Π°Π½ΠΈ. ΠΠ΄Ρ€Π΅ΡΡŠΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈ Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚Π°ΠΊΠ°:

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

ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π» Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ

Π—Π° Π΄Π° стС сигурни, Ρ‡Π΅ само Π½Π°Π΄Π΅ΠΆΠ΄Π½ΠΈ прилоТСния ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Ρ‚ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Ρ‚ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ Π΄ΠΎ Π²Π°ΡˆΠΈΡ‚Π΅ адрСси, трябва Π΄Π° ΡΡŠΠ·Π΄Π°Π΄Π΅Ρ‚Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π» Π² систСмата Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ. Π—Π° прилоТСния, Ρ€Π°Π±ΠΎΡ‚Π΅Ρ‰ΠΈ Π² ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€, ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΈΡ‚Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ удостовСрСни с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° Π°ΠΊΠ°ΡƒΠ½Ρ‚ Π·Π° услуга OpenShift. ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡΠΊΠΈΡΡ‚ "serviceaccount" ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½ Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠΎ слСдния Π½Π°Ρ‡ΠΈΠ½:

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"]

Π Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π·Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ

Π—Π° Π΄Π° ΠΌΠΎΠΆΠ΅ AMQ Online Π΄Π° създадС configmap, ΠΊΠΎΠΉΡ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ…ΠΌΠ΅ Π·Π° Π²Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅ Π½Π° информацията Π·Π° ΠΊΡ€Π°ΠΉΠ½Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° AMQP, трябва Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ Π·Π°Π΄Π°Π΄Π΅Π½ΠΈ Role ΠΈ RoleBinding:

---
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

Как сС ΠΏΡ€ΠΈΠ»Π°Π³Π°Ρ‚ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ

ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠΈΡ‚Π΅ конфигурацията Π½Π° систСмата Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ ΠΏΠΎ слСдния Π½Π°Ρ‡ΠΈΠ½:

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

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ

Π—Π° Π΄Π° сС ΡƒΠ²Π΅Ρ€ΠΈΡ‚Π΅, Ρ‡Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π΅ стартирано, Π½Π΅ΠΊΠ° ΠΏΡŠΡ€Π²ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ Π΄Π°Π»ΠΈ ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΈΡ‚Π΅ адрСси са създадСни ΠΈ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΈ:

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

Π’ΠΎΠ³Π°Π²Π° Π½Π΅ΠΊΠ° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ URL адрСса Π½Π° ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ (просто ΠΎΡ‚Π²ΠΎΡ€Π΅Ρ‚Π΅ Ρ‚ΠΎΠ·ΠΈ адрСс Π² Π±Ρ€Π°ΡƒΠ·ΡŠΡ€Π°):

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

Π‘Ρ€Π°ΡƒΠ·ΡŠΡ€ΡŠΡ‚ трябва Π΄Π° ΠΏΠΎΠΊΠ°Π·Π²Π°, Ρ‡Π΅ Π±ΠΈΠ»Π΅Ρ‚ΠΈΡ‚Π΅ сС Π°ΠΊΡ‚ΡƒΠ°Π»ΠΈΠ·ΠΈΡ€Π°Ρ‚ ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ΠΈΡ‡Π½ΠΎ, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡΡ‚Π° сС ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Ρ‚ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Ρ‚ ΠΎΡ‚ AMQ Online.

Π Π΅Π·ΡŽΠΌΠΈΡ€Π°Π½Π΅

Π’Π°ΠΊΠ° Ρ‡Π΅ написахмС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Quarkus, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° AMQP Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ, ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Ρ…ΠΌΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Red Hat OpenShift ΠΈ Π²Π½Π΅Π΄Ρ€ΠΈΡ…ΠΌΠ΅ конфигурацията ΠΌΡƒ въз основа Π½Π° AMQ Online конфигурацията. Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° ΡΡŠΠ·Π΄Π°Π΄ΠΎΡ…ΠΌΠ΅ манифСститС, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈ Π·Π° ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° систСмата Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ Π·Π° Π½Π°ΡˆΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.

Π‘ Ρ‚ΠΎΠ²Π° ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡Π²Π°ΠΌΠ΅ ΠΏΠΎΡ€Π΅Π΄ΠΈΡ†Π°Ρ‚Π° Π·Π° Quarkus, Π½ΠΎ прСдстоят ΠΌΠ½ΠΎΠ³ΠΎ Π½ΠΎΠ²ΠΈ ΠΈ интСрСсни Π½Π΅Ρ‰Π°, ΠΎΡ‡Π°ΠΊΠ²Π°ΠΉΡ‚Π΅!

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: www.habr.com

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€