Π Π°Π·ΠΌΠ΅Π½Π° Π½Π° ΠΏΠΎΡ€Π°ΠΊΠΈ Π²ΠΎ ΠΎΠ±Π»Π°ΠΊ Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Red Hat OpenShift со помош Π½Π° Quarkus ΠΈ AMQ Online

Π—Π΄Ρ€Π°Π²ΠΎ Π½Π° ситС! Π•Π²Π΅ Π³ΠΎ - Π½Π°ΡˆΠ°Ρ‚Π° послСдна објава Π²ΠΎ ΡΠ΅Ρ€ΠΈΡ˜Π°Ρ‚Π° ΠšΠ²Π°Ρ€ΠΊΡƒΡ! (ΠŸΠ°Ρ‚Π΅ΠΌ, Π³Π»Π΅Π΄Π°Ρ˜Ρ‚Π΅ Π³ΠΎ Π½Π°ΡˆΠΈΠΎΡ‚ Π²Π΅Π±ΠΈΠ½Π°Ρ€ β€žΠžΠ²Π° Π΅ Quarkus – Kubernetes Ρ€ΠΎΠ΄Π½Π° Java Ρ€Π°ΠΌΠΊΠ°β€œ. ЌС Π²ΠΈ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅Ρ‚Π΅ ΠΎΠ΄ Π½ΡƒΠ»Π° ΠΈΠ»ΠΈ Π΄Π° ΠΏΡ€Π΅Ρ„Ρ€Π»ΠΈΡ‚Π΅ Π³ΠΎΡ‚ΠΎΠ²ΠΈ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ˜Π°)

Π Π°Π·ΠΌΠ΅Π½Π° Π½Π° ΠΏΠΎΡ€Π°ΠΊΠΈ Π²ΠΎ ΠΎΠ±Π»Π°ΠΊ Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Red Hat OpenShift со помош Π½Π° Quarkus ΠΈ AMQ Online

Π’ ΠΏΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π½ΠΎ Π’ΠΎ овој пост, Π³ΠΈ Ρ€Π°Π·Π³Π»Π΅Π΄Π°Π²ΠΌΠ΅ Ρ€Π΅Π»Π΅Π²Π°Π½Ρ‚Π½ΠΈΡ‚Π΅ Π°Π»Π°Ρ‚ΠΊΠΈ ΠΊΠΎΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° сС користат Π·Π° ΠΊΠ²Π°Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€Π°ΡšΠ΅ Π½Π° ΠΏΠΎΠ΄ΠΎΠ±Ρ€ΡƒΠ²Π°ΡšΠ°Ρ‚Π° Π΄ΠΎΠ±ΠΈΠ΅Π½ΠΈ ΠΊΠ°ΠΊΠΎ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ Π½Π° ΠΌΠΎΠ΄Π΅Ρ€Π½ΠΈΠ·ΠΈΡ€Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° Java Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈΡ‚Π΅.

Од Π²Π΅Ρ€Π·ΠΈΡ˜Π°Ρ‚Π° 0.17.0, ΠšΠ²Π°Ρ€ΠΊΡƒΡ ΠΏΠΎΠ΄Π΄Ρ€ΠΆΡƒΠ²Π° ΡƒΠΏΠΎΡ‚Ρ€Π΅Π±Π° Π½Π° Π½Π°ΠΏΡ€Π΅Π΄Π΅Π½ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π·Π° Ρ€Π΅Π΄ΠΈΡ†Π° ΠΏΠΎΡ€Π°ΠΊΠΈ (AMQP), кој Π΅ ΠΎΡ‚Π²ΠΎΡ€Π΅Π½ стандард Π·Π° прСнос Π½Π° Π΄Π΅Π»ΠΎΠ²Π½ΠΈ ΠΏΠΎΡ€Π°ΠΊΠΈ ΠΏΠΎΠΌΠ΅Ρ“Ρƒ Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ.

Red Hat AMQ Online Π΅ услуга ΠΈΠ·Π³Ρ€Π°Π΄Π΅Π½Π° Π²Ρ€Π· основа Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ со ΠΎΡ‚Π²ΠΎΡ€Π΅Π½ ΠΊΠΎΠ΄ EnMasse ΠΈ ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€Π°ΡšΠ΅ Π½Π° ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·Π°ΠΌ Π·Π° ΠΏΠΎΡ€Π°ΠΊΠΈ Π±Π°Π·ΠΈΡ€Π°Π½ Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ° Red Hat OpenShift. Π—Π° повСќС Π΄Π΅Ρ‚Π°Π»ΠΈ Π·Π° Ρ‚ΠΎΠ° ΠΊΠ°ΠΊΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€Π°, Π²ΠΈΠ΄Π΅Ρ‚Π΅ Ρ‚ΡƒΠΊΠ° (EN). ДСнСс ќС Π²ΠΈ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° Π³ΠΈ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€Π°Ρ‚Π΅ AMQ Online ΠΈ Quarkus Π·Π° Π΄Π° ΠΈΠ·Π³Ρ€Π°Π΄ΠΈΡ‚Π΅ ΠΌΠΎΠ΄Π΅Ρ€Π΅Π½ систСм Π·Π° ΠΏΠΎΡ€Π°ΠΊΠΈ Π±Π°Π·ΠΈΡ€Π°Π½ Π½Π° OpenShift ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ Π΄Π²Π΅ Π½ΠΎΠ²ΠΈ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ Π·Π° ΠΏΠΎΡ€Π°ΠΊΠΈ.

Π‘Π΅ прСтпоставува Π΄Π΅ΠΊΠ° вСќС стС Π³ΠΎ распорСдилС AMQ Online Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° OpenShift (Π°ΠΊΠΎ Π½Π΅, Ρ‚ΠΎΠ³Π°Ρˆ Π²ΠΈΠ΄Π΅Ρ‚Π΅ Π²ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΈΠ½ΡΡ‚Π°Π»Π°Ρ†ΠΈΡ˜Π°).

Π—Π° ΠΏΠΎΡ‡Π΅Ρ‚ΠΎΠΊ, ќС создадСмС Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° Quarkus која ќС Π±ΠΈΠ΄Π΅ СдноставСн систСм Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° Π½Π°Ρ€Π°Ρ‡ΠΊΠΈ со помош Π½Π° Ρ€Π΅Π°ΠΊΡ‚ΠΈΠ²Π½ΠΈ ΠΏΠΎΡ€Π°ΠΊΠΈ. Оваа Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° ќС Π²ΠΊΠ»ΡƒΡ‡ΡƒΠ²Π° Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π½Π° Π½Π°Ρ€Π°Ρ‡ΠΊΠΈ кој ΠΈΡΠΏΡ€Π°ΡœΠ° Π½Π°Ρ€Π°Ρ‡ΠΊΠΈ Π΄ΠΎ Ρ€Π΅Π΄ΠΎΡ‚ Π·Π° ΠΏΠΎΡ€Π°ΠΊΠΈ Π²ΠΎ фиксСн ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π», ΠΊΠ°ΠΊΠΎ ΠΈ процСсор Π·Π° Π½Π°Ρ€Π°Ρ‡ΠΊΠΈ кој ќС Π³ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΡƒΠ²Π° ΠΏΠΎΡ€Π°ΠΊΠΈΡ‚Π΅ ΠΎΠ΄ Ρ€Π΅Π΄ΠΎΡ‚ ΠΈ ќС Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° ΠΏΠΎΡ‚Π²Ρ€Π΄ΠΈ ΡˆΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π²ΠΈΠ΄Π°Ρ‚ Π²ΠΎ прСлистувачот.

ΠžΡ‚ΠΊΠ°ΠΊΠΎ ќС ја создадСмС Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π°Ρ‚Π°, ќС Π²ΠΈ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° ја Π²Π³Ρ€Π°Π΄ΠΈΡ‚Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ˜Π°Ρ‚Π° Π½Π° систСмот Π·Π° ΠΏΠΎΡ€Π°ΠΊΠΈ Π²ΠΎ Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π°Ρ‚Π° ΠΈ Π΄Π° Π³ΠΎ користитС AMQ Online Π·Π° Π΄Π° Π³ΠΈ ΠΎΠ±Π΅Π·Π±Π΅Π΄ΠΈΠΌΠ΅ рСсурситС ΡˆΡ‚ΠΎ Π½ΠΈ сС ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΈ Π½Π° систСмот.

ΠΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° ΠšΠ²Π°Ρ€ΠΊΡƒΡ

ΠΠ°ΡˆΠ°Ρ‚Π° Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° Quarkus Ρ€Π°Π±ΠΎΡ‚ΠΈ Π½Π° OpenShift ΠΈ Π΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Ρ‚Π° Π²Π΅Ρ€Π·ΠΈΡ˜Π° Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° amqp-Π±Ρ€Π· ΠΏΠΎΡ‡Π΅Ρ‚ΠΎΠΊ. МоТС Π΄Π° сС најдС цСлосСн ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° клиСнтската страна Ρ‚ΡƒΠΊΠ°.

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

Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΡ‚ Сдноставно ΠΌΠΎΠ½ΠΎΡ‚ΠΎΠ½ΠΎ ΠΈΡΠΏΡ€Π°ΡœΠ° ID Π½Π° растСчки Π½Π°Ρ€Π°Ρ‡ΠΊΠΈ Π½Π° адрСсата β€žΠ½Π°Ρ€Π°Ρ‡ΠΊΠΈβ€œ Π½Π° сСкои 5 сСкунди.

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

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

Π£ΠΏΡ€Π°Π²ΡƒΠ²Π°Ρ‡ΠΎΡ‚ со Π½Π°Ρ€Π°Ρ‡ΠΊΠΈ Π΅ ΡƒΡˆΡ‚Π΅ поСдноставСн, Ρ‚ΠΎΡ˜ само Π²Ρ€Π°ΡœΠ° ID Π·Π° ΠΏΠΎΡ‚Π²Ρ€Π΄Π° Π½Π° адрСсата β€žΠΏΠΎΡ‚Π²Ρ€Π΄ΠΈβ€œ.

@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 кој ќС Π³ΠΎ Ρ‡ΠΈΡ‚Π° Ρ‚ΠΎΠΊΠ΅Π½ΠΎΡ‚ Π·Π° Π°Π²Ρ‚Π΅Π½Ρ‚ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° ΠΎΠ΄ Π΄Π°Ρ‚ΠΎΡ‚Π΅Ρ‡Π½ΠΈΠΎΡ‚ систСм Π½Π° ΠΏΠΎΠ΄Π»ΠΎΠ³Π°Ρ‚Π°:

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. Π—Π° Π΄Π΅Ρ‚Π°Π»ΠΈ Π·Π° Ρ‚ΠΎΠ° ΠΊΠ°ΠΊΠΎ Π΄Π° поставитС срСдина Π·Π° ΠΎΠ²Π°, Π²ΠΈΠ΄Π΅Ρ‚Π΅ Π³ΠΈ соодвСтнитС упатства Π²ΠΎ Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠšΠ²Π°Ρ€ΠΊΡƒΡ.

ΠŸΠΎΡ‚ΠΎΠ°, слСдСјќи Π³ΠΈ упатствата Π΄Π°Π΄Π΅Π½ΠΈ Ρ‚Π°ΠΌΡƒ, Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π³ΠΎ ΠΏΡ€Π΅Π·Π΅ΠΌΠ΅Ρ‚Π΅ ΠΈΠ·Π²ΠΎΡ€ΠΎΡ‚, Π΄Π° ја ΠΈΠ·Π³Ρ€Π°Π΄ΠΈΡ‚Π΅ ΠΈ распорСдитС Π½Π°ΡˆΠ°Ρ‚Π° Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π°:

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. ΠšΠΎΡ€ΠΈΡΠ½ΠΈΡ‡ΠΊΠ°Ρ‚Π° β€žΡΠ΅Ρ€Π²ΠΈΡΠ½Π° ΡΠΌΠ΅Ρ‚ΠΊΠ°β€œ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π²Π°ΠΊΠ°:

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 Π΄Π° ја ΠΊΡ€Π΅ΠΈΡ€Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π°Ρ‚Π° ΠΌΠ°ΠΏΠ° ΡˆΡ‚ΠΎ ја користСвмС Π·Π° Π΄Π° Π³ΠΈ Π²Π³Ρ€Π°Π΄ΠΈΠΌΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈΡ‚Π΅ Π·Π° ΠΊΡ€Π°Ρ˜Π½Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ° 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

Π”ΠΎΠ΄Π°Π΄Π΅Ρ‚Π΅ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€