Wiadomości natywne w chmurze na platformie Red Hat OpenShift przy użyciu Quarkus i AMQ Online

Cześć wszystkim! Oto jest – nasz ostatni post z serii Quarkus! (Przy okazji obejrzyj nasz webinar „To jest Quarkus – natywny framework Java Kubernetes”. Pokażemy Ci jak zacząć od zera lub przenieść gotowe rozwiązania)

Wiadomości natywne w chmurze na platformie Red Hat OpenShift przy użyciu Quarkus i AMQ Online

В poprzedni W tym poście przyjrzeliśmy się odpowiednim narzędziom, które można wykorzystać do ilościowego określenia ulepszeń uzyskanych w wyniku modernizacji aplikacji Java.

Od wersji 0.17.0, kwarkus obsługuje użycie protokołu Advanced Message Queuing Protocol (AMQP), który jest otwartym standardem przesyłania wiadomości biznesowych pomiędzy aplikacjami lub organizacjami.

Red Hat AMQ w Internecie to usługa zbudowana w oparciu o projekt open source EnMasse oraz wdrożenie mechanizmu przesyłania wiadomości opartego na platformie Red Hat OpenShift. Więcej szczegółów na temat działania można znaleźć w artykule tutaj (PL). Dzisiaj pokażemy Ci, jak połączyć AMQ Online i Quarkus, aby zbudować nowoczesny system przesyłania wiadomości oparty na OpenShift, wykorzystujący dwie nowe technologie przesyłania wiadomości.

Zakłada się, że wdrożyłeś już AMQ Online na platformie OpenShift (jeśli nie, zobacz instrukcja instalacji).

Na początek stworzymy aplikację Quarkus, która będzie prostym systemem obsługi zamówień wykorzystującym komunikację reaktywną. Ta aplikacja będzie zawierać generator zamówień, który będzie wysyłał zamówienia do kolejki wiadomości w ustalonych odstępach czasu, a także procesor zamówień, który będzie przetwarzał wiadomości z kolejki i generował potwierdzenia widoczne w przeglądarce.

Po utworzeniu aplikacji pokażemy, jak osadzić konfigurację systemu przesyłania wiadomości w aplikacji i użyć AMQ Online do udostępnienia potrzebnych zasobów w systemie.

Aplikacja Quarkus

Nasza aplikacja Quarkus działa na OpenShift i jest zmodyfikowaną wersją programu amqp-szybki start. Można znaleźć kompletny przykład strony klienta tutaj.

Generator zamówień

Generator po prostu monotonicznie wysyła rosnące identyfikatory zamówień na adres „zamówienia” co 5 sekund.

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

Procesor zamówienia

Obsługa zamówień jest jeszcze prostsza, po prostu zwraca identyfikator potwierdzenia na adres „potwierdzenia”.

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

Zasoby potwierdzenia

Zasób potwierdzenia to punkt końcowy HTTP służący do wyświetlania potwierdzeń wygenerowanych przez naszą aplikację.

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

regulacja

Aby połączyć się z AMQ Online, nasza aplikacja będzie potrzebować pewnych danych konfiguracyjnych, a mianowicie: konfiguracji złącza Quarkus, informacji o punkcie końcowym AMQP i poświadczeń klienta. Lepiej oczywiście wszystkie dane konfiguracyjne przechowywać w jednym miejscu, jednak celowo je rozdzielimy, aby pokazać możliwe opcje konfiguracji aplikacji Quarkus.

Złącza

Konfigurację konektora można zapewnić w czasie kompilacji przy użyciu pliku właściwości aplikacji:

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

Aby wszystko było proste, będziemy używać kolejki komunikatów tylko dla adresu „zamówienia”. Natomiast adres „potwierdzeń” w naszej aplikacji będzie korzystał z kolejki w pamięci.

Punkt końcowy AMQP

W czasie kompilacji nazwa hosta i numer portu punktu końcowego AMQP są nieznane, dlatego należy je wstrzyknąć. Punkt końcowy można ustawić w mapie konfiguracyjnej tworzonej przez AMQ Online, dlatego zdefiniujemy je poprzez zmienne środowiskowe w manifeście aplikacji:

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

Referencje

Token konta usługi można wykorzystać do uwierzytelnienia naszej aplikacji w OpenShift. Aby to zrobić, musisz najpierw utworzyć niestandardowe źródło ConfigSource, które odczyta token uwierzytelniający z systemu plików poda:

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

Zbuduj i wdróż aplikację

Ponieważ aplikacja musi zostać skompilowana do pliku wykonywalnego, wymagana jest maszyna wirtualna GraalVM. Aby uzyskać szczegółowe informacje na temat konfigurowania środowiska w tym celu, zobacz odpowiednie instrukcje w Przewodnik Quarkusa.

Następnie, postępując zgodnie z podanymi tam instrukcjami, należy pobrać źródła, zbudować i wdrożyć naszą aplikację:

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

Po wykonaniu tych poleceń aplikacja zostanie wdrożona, ale nie zostanie uruchomiona, dopóki nie skonfigurujemy potrzebnych zasobów komunikacyjnych w AMQ Online.

Konfiguracja systemu przesyłania wiadomości

Teraz pozostaje już tylko ustawić w systemie przesyłania wiadomości zasoby, których potrzebuje nasza aplikacja. W tym celu należy utworzyć: 1) przestrzeń adresową w celu zainicjowania punktu końcowego systemu przesyłania wiadomości; 2) adres umożliwiający konfigurację adresów, których używamy w aplikacji; 3) Wysyłanie wiadomości do użytkownika w celu ustawienia poświadczeń klienta.

Przestrzeń adresowa

Obiekt AddressSpace w AMQ Online to grupa adresów, które współdzielą punkty końcowe połączenia oraz zasady uwierzytelniania i autoryzacji. Tworząc przestrzeń adresową, możesz określić sposób udostępniania punktów końcowych przesyłania wiadomości:

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

Adres

Adresy służą do wysyłania i odbierania wiadomości. Każdy adres ma typ, który określa jego semantykę, a także plan, który określa liczbę zasobów do zarezerwowania. Adres można określić na przykład w następujący sposób:

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

Użytkownik wiadomości

Aby mieć pewność, że tylko zaufane aplikacje będą mogły wysyłać i odbierać wiadomości na Twoje adresy, musisz utworzyć użytkownika w systemie przesyłania wiadomości. W przypadku aplikacji działających w klastrze klienci mogą być uwierzytelniani przy użyciu konta usługi OpenShift. Użytkownika „konto serwisowe” można zdefiniować na przykład w następujący sposób:

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

Uprawnienia do konfiguracji aplikacji

Aby usługa AMQ Online mogła utworzyć mapę konfiguracyjną, której użyliśmy do osadzenia informacji o punkcie końcowym AMQP, należy ustawić Role i 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

Jak zastosować konfiguracje

Możesz zastosować konfigurację systemu przesyłania wiadomości w następujący sposób:

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

Weryfikacja aplikacji

Aby mieć pewność, że aplikacja została uruchomiona, sprawdźmy przede wszystkim, czy odpowiednie adresy zostały utworzone i są aktywne:

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

Następnie sprawdźmy adres URL trasy aplikacji (wystarczy otworzyć ten adres w przeglądarce):

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

Przeglądarka powinna pokazywać, że zgłoszenia są okresowo aktualizowane w miarę wysyłania i odbierania wiadomości przez AMQ Online.

Podsumowując

Napisaliśmy więc aplikację Quarkus, która wykorzystuje AMQP do przesyłania wiadomości, skonfigurowaliśmy aplikację do działania na platformie Red Hat OpenShift i zaimplementowaliśmy jej konfigurację w oparciu o konfigurację AMQ Online. Następnie utworzyliśmy manifesty potrzebne do zainicjowania systemu przesyłania wiadomości dla naszej aplikacji.

Na tym kończymy serię o Quarkusie, ale przed nami jeszcze wiele nowych i interesujących rzeczy, bądźcie czujni!

Źródło: www.habr.com

Dodaj komentarz