Cloud-georiƫnteerde berichtenuitwisseling op het Red Hat OpenShift-platform met Quarkus en AMQ Online

Hallo allemaal! Hier is hij dan – onze laatste post in de serie over Quarkus! (Overigens, kijk onze webinar ā€žDit is Quarkus – een Kubernetes-native Java-frameworkā€œ. We zullen laten zien hoe je kunt beginnen ā€žvanaf nulā€œ of bestaande oplossingen kunt migreren)

Cloud-georiƫnteerde berichtenuitwisseling op het Red Hat OpenShift-platform met Quarkus en AMQ Online

In In de vorige post hebben we de relevante tools bekeken waarmee je kwantitatief kunt beoordelen welke verbeteringen zijn behaald door Java-toepassingen te moderniseren.

Vanaf versie 0.17.0 Quarkus ondersteunt het gebruik van de Advanced Message Queuing Protocol (AMQP), een open standaard voor de overdracht van zakelijke berichten tussen toepassingen of organisaties.

Red Hat AMQ Online is een service die is gebouwd op basis van het open project EnMasse en implementeert een berichtenuitwisselingsmechanisme op basis van het Red Hat OpenShift. Meer over de werking ervan vind je hier (EN). Vandaag laten we zien hoe we AMQ Online en Quarkus kunnen combineren om een moderne berichtenuitwisselingssysteem op basis van OpenShift te bouwen met behulp van twee nieuwe technologieƫn die betrekking hebben op de verwerking van berichten.

Verondersteld wordt dat je AMQ Online al hebt geĆÆmplementeerd op het OpenShift-platform (als dat niet het geval is, zie dan de installatiehandleiding).

Laten we beginnen met het creƫren van een Quarkus-toepassing die een eenvoudig systeem voor orderverwerking zal voorstellen met behulp van reactieve berichtenuitwisseling. Deze toepassing zal een ordergenerator bevatten die bestellingen met vaste tussenpozen naar de berichtwachtrij verzendt, evenals een orderverwerker die berichten uit de wachtrij verwerkt en bevestigingen genereert die in de browser kunnen worden bekeken.

Na het creƫren van de toepassing laten we zien hoe we de configuratie van het berichtenuitwisselingssysteem erin kunnen integreren en AMQ Online gebruiken om de benodigde resources in dit systeem te initialiseren.

Quarkus-toepassing

Onze Quarkus-toepassing draait op OpenShift en is een gemodificeerde versie van het programma amqp-quickstart. Een volledig voorbeeld van de clientzijde is te vinden hier.

Ordergenerator

De generator verzendt elke 5 seconden eenvoudig monotone groeiende orderidentificaties naar het adres "orders".

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

Orderverwerker

De orderverwerking is nog eenvoudiger, het retourneert gewoon een bevestigings-id naar het adres "confirmations".

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

Bevestigingsbronnen

Een bevestigingsbron is een HTTP-eindpunt voor het opsommen van de bevestigingen die ons applicatie genereert.

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

Instellingen

Om verbinding te maken met AMQ Online heeft onze applicatie bepaalde configuratiegegevens nodig, namelijk: de configuratie van de Quarkus-connector, informatie over het AMQP-eindpunt en klantreferenties. Het is beter om deze configuratiegegevens op ƩƩn plek te houden, maar we zullen ze verkeerd scheiden om verschillende configuratiemogelijkheden van de Quarkus-applicatie te tonen.

Connectoren

De connectorconfiguratie kan tijdens de compilatie worden verstrekt via een properties-bestand van de applicatie:

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

Om het eenvoudig te houden, zullen we de berichtenqueue alleen gebruiken voor het adres "orders". Het adres "confirmations" in onze applicatie maakt gebruik van een in-memory queue.

AMQP-eindpunt

Tijdens de compilatie zijn de hostnaam en poortnummer voor het AMQP-eindpunt onbekend, dus deze moeten worden ingespoten. Het eindpunt kan worden ingesteld in de configmap die door AMQ Online wordt aangemaakt, dus we zullen ze definiƫren via omgevingsvariabelen in de manifest van de applicatie:

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

Referenties

De service-account-token kan worden gebruikt voor de authenticatie van onze applicatie in OpenShift. Eerst moet er een aangepaste ConfigSource worden aangemaakt die het authenticatietoken uit het bestandssysteem van de pod leest:

public class MessagingCredentialsConfigSource implements ConfigSource {
    private static final Set propertyNames;
 
    static {
        propertyNames = new HashSet();
        propertyNames.add("amqp-username");
        propertyNames.add("amqp-password");
    }
 
    @Override
    public Set getPropertyNames() {
        return propertyNames;
    }
 
    @Override
    public Map getProperties() {
        try {
            Map 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);
    }
}

Bouwen en implementeren van de applicatie

Aangezien de applicatie naar een uitvoerbaar bestand moet worden gecompileerd, is een GraalVM virtuele machine vereist. Voor meer informatie over hoe u de omgeving hiervoor kunt instellen, zie de bijbehorende instructies in Quarkus Gids.

Volg daarna de instructies daar om de broncode te downloaden, de build uit te voeren en onze applicatie te implementeren:

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

Na deze commando's is de applicatie geĆÆmplementeerd, maar deze wordt niet gestart totdat we de benodigde messaging resources in AMQ Online hebben ingesteld.

Configureren van het messaging systeem

Nu moeten we in het messaging systeem de resources instellen die onze applicatie nodig heeft. Hiervoor moet je het volgende creƫren: 1) een adresruimte om het eindpunt van het messaging systeem in te stellen; 2) een adres om de adressen in te stellen die we in de applicatie gebruiken; 3) een gebruiker van het messaging systeem om de klantgegevens in te stellen.

Adresruimte

Het AddressSpace object in AMQ Online is een groep adressen die gezamenlijk gebruik maken van verbindings-eindpunten en ook van authenticatie- en autorisatiebeleid. Bij het aanmaken van een adresruimte kun je opgeven hoe de eindpunten van het messaging systeem zullen worden aangeboden:

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

Adressen

Adressen worden gebruikt voor het verzenden en ontvangen van berichten. Elke adres heeft een type dat de semantiek definieert, evenals een plan dat het aantal gereserveerde bronnen vastlegt. Een adres kan bijvoorbeeld als volgt gedefinieerd worden:

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

Gebruiker van het berichten systeem

Om ervoor te zorgen dat alleen vertrouwde applicaties berichten kunnen verzenden en ontvangen op uw adressen, moet er een gebruiker in het berichten systeem worden aangemaakt. Voor applicaties die op een cluster draaien, kunnen clients worden geverifieerd met behulp van een service-account in OpenShift. Een gebruiker "serviceaccount" kan bijvoorbeeld als volgt gedefinieerd worden:

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

Machtigingen voor het configureren van de applicatie

Om AMQ Online in staat te stellen een configmap te maken die we hebben gebruikt om de informatie over het AMQP-eindpunt in te voeren, moeten rol en rolbinding (Role en RoleBinding) worden ingesteld:

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

Hoe configuraties toe te passen

De configuratie van het berichten systeem kan als volgt worden toegepast:

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

Verificatie van de applicatie

Om te controleren of de applicatie begon, laten we eerst nagaan of de bijbehorende adressen zijn aangemaakt en actief zijn:

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

Laten we vervolgens de URL van de applicatieroute controleren (gewoon dit adres in de browser openen):

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

In de browser moet zichtbaar zijn dat de tickets periodiek worden bijgewerkt terwijl berichten worden verzonden en ontvangen door AMQ Online.

Laten we de balans opmaken

We hebben een Quarkus-applicatie geschreven die AMQP gebruikt voor messaging, deze applicatie ingesteld om te draaien op het Red Hat OpenShift-platform, en de configuratie geĆÆmplementeerd op basis van de AMQ Online-configuratie. Vervolgens hebben we de noodzakelijke manifesten gemaakt voor de initialisatie van het messaging-systeem voor onze applicatie.

Hiermee sluiten we de serie over Quarkus af, maar er komt veel nieuws en interessants aan, blijf bij ons!

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers šŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster