ΠžΠ±Π»Π°Ρ‡Π½ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±ΠΌΠ΅Π½ сообщСниями Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ΅ Red Hat OpenShift с использованиСм Quarkus ΠΈ AMQ Online

ВсСм ΠΏΡ€ΠΈΠ²Π΅Ρ‚! Π’ΠΎΡ‚ ΠΈ ΠΎΠ½ – наш Π·Π°ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ пост ΠΈΠ· сСрии ΠΏΡ€ΠΎ Quarkus! (ΠšΡΡ‚Π°Ρ‚ΠΈ, смотритС наш Π²Π΅Π±ΠΈΠ½Π°Ρ€ Β«Π­Ρ‚ΠΎ Quarkus – Kubernetes native Java Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΒ». ПокаТСм, ΠΊΠ°ΠΊ Π½Π°Ρ‡Π°Ρ‚ΡŒ «с нуля» ΠΈΠ»ΠΈ пСрСнСсти Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ)

ΠžΠ±Π»Π°Ρ‡Π½ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±ΠΌΠ΅Π½ сообщСниями Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ΅ Red Hat OpenShift с использованиСм Quarkus ΠΈ AMQ Online

Π’ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ постС ΠΌΡ‹ рассмотрСли ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ инструмСнты, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΌΠΎΠΆΠ½ΠΎ количСствСнно ΠΎΡ†Π΅Π½ΠΈΡ‚ΡŒ ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΌΠΎΠ΄Π΅Ρ€Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ Java-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ.

Начиная с вСрсии 0.17.0, Quarkus ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ использованиС Advanced Message Queuing Protocol (AMQP), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ являСтся ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ стандартом ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ бизнСс-сообщСний ΠΌΠ΅ΠΆΠ΄Ρƒ прилоТСниями ΠΈΠ»ΠΈ организациями.

Red Hat AMQ Online – это сСрвис, построСнный Π½Π° основС ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° EnMasse ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰ΠΈΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ ΠΎΠ±ΠΌΠ΅Π½Π° сообщСний Π½Π° Π±Π°Π·Π΅ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ Red Hat OpenShift. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΠΎΠ½ устроСн, см. здСсь (EN). БСгодня ΠΌΡ‹ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ, ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ AMQ Online ΠΈ Quarkus, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΡΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ систСму ΠΎΠ±ΠΌΠ΅Π½Π° сообщСниями Π½Π° Π±Π°Π·Π΅ OpenShift с использованиСм Π΄Π²ΡƒΡ… Π½ΠΎΠ²Ρ‹Ρ… Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΉ, связанных с ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ сообщСний.

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΡƒΠΆΠ΅ Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΠ»ΠΈ AMQ Online Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ΅ OpenShift (Ссли Π½Π΅Ρ‚, Ρ‚ΠΎ см. руководство ΠΏΠΎ установкС).

Для Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ создадим прилоТСния Quarkus, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ собой ΠΏΡ€ΠΎΡΡ‚ΡƒΡŽ систСму ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π·Π°ΠΊΠ°Π·ΠΎΠ² с использованиСм Ρ€Π΅Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΎΠ±ΠΌΠ΅Π½Π° сообщСниями. Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ Π² сСбя Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π·Π°ΠΊΠ°Π·ΠΎΠ², ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ Π·Π°ΠΊΠ°Π·Ρ‹ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ сообщСний с фиксированным ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»ΠΎΠΌ, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π·Π°ΠΊΠ°Π·ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ сообщСния ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΈ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ подтвСрТдСния, доступныС для просмотра Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅.

ПослС создания прилоТСния ΠΌΡ‹ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ, ΠΊΠ°ΠΊ Π²Π½Π΅Π΄Ρ€ΡΡ‚ΡŒ Π² Π½Π΅Π³ΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ систСмы ΠΎΠ±ΠΌΠ΅Π½Π° сообщСниями ΠΈ задСйствуСм AMQ Online, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° этой систСмС Π½ΡƒΠΆΠ½Ρ‹Π΅ Π½Π°ΠΌ рСсурсы.

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

НашС Quarkus-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ выполняСтся Π½Π° OpenShift ΠΈ прСдставляСт собой ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ amqp-quickstart. ΠŸΠΎΠ»Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ клиСнтской части ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ здСсь.

Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π·Π°ΠΊΠ°Π·ΠΎΠ²

Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 5 сСкунд просто ΠΌΠΎΠ½ΠΎΡ‚ΠΎΠ½Π½ΠΎ отправляСт растущиС ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ Π·Π°ΠΊΠ°Π·ΠΎΠ² Π½Π° адрСс Β«ordersΒ».

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

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π·Π°ΠΊΠ°Π·ΠΎΠ²

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π·Π°ΠΊΠ°Π·ΠΎΠ² Π΅Ρ‰Π΅ ΠΏΡ€ΠΎΡ‰Π΅, ΠΎΠ½ всСго лишь Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ подтвСрТдСния Π½Π° адрСс Β«confirmationsΒ».

@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

Π§Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΡƒΡΠ»ΠΎΠΆΠ½ΡΡ‚ΡŒ, ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ сообщСний Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для адрСса Β«ordersΒ». А адрСс Β«confirmationsΒ» Π² нашСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Π² памяти.

ΠšΠΎΠ½Π΅Ρ‡Π½Π°Ρ Ρ‚ΠΎΡ‡ΠΊΠ° AMQP

На этапС компиляции имя хоста ΠΈ Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΡ€Ρ‚Π° для ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠΈ AMQP нСизвСстны, поэтому ΠΈΡ… Π½ΡƒΠΆΠ½ΠΎ Π²Π½Π΅Π΄Ρ€ΠΈΡ‚ΡŒ. ΠšΠΎΠ½Π΅Ρ‡Π½ΡƒΡŽ Ρ‚ΠΎΡ‡ΠΊΡƒ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°Ρ‚ΡŒ Π² configmap, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ создаСтся 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 Guide.

Π—Π°Ρ‚Π΅ΠΌ, слСдуя ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΌ Ρ‚Π°ΠΌ инструкциям, Π½Π°Π΄ΠΎ ΡΠΊΠ°Ρ‡Π°Ρ‚ΡŒ исходник, провСсти сборку ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠ΅ нашСго прилоТСния:

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, Π½ΠΎ Π²ΠΏΠ΅Ρ€Π΅Π΄ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΈ интСрСсного, ΠΎΡΡ‚Π°Π²Π°ΠΉΡ‚Π΅ΡΡŒ с Π½Π°ΠΌΠΈ!

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

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ