Cloud-native Messagerie op der Red Hat OpenShift Plattform mat Quarkus an AMQ Online

Moien alleguer! Hei ass et - eise leschte Post an der Quarkus Serie! (Kuckt iwwregens eise Webinar "Dëst ass Quarkus - Kubernetes gebierteg Java Kader". Mir weisen Iech wéi Dir vun Null unzefänken oder fäerdeg Léisungen transferéiert)

Cloud-native Messagerie op der Red Hat OpenShift Plattform mat Quarkus an AMQ Online

В virdrun An dësem Post hu mir déi relevant Tools gekuckt, déi kënne benotzt ginn fir d'Verbesserungen ze quantifizéieren, déi als Resultat vun der Moderniséierung vun Java Uwendungen kritt goufen.

Zënter Versioun 0.17.0, Quark ënnerstëtzt d'Benotzung vum Advanced Message Queuing Protocol (AMQP), wat en oppene Standard ass fir Geschäftsmessagen tëscht Uwendungen oder Organisatiounen ze transferéieren.

Red Hat AMQ Online ass e Service gebaut op Basis vun engem Open Source Projet EnMasse an Ëmsetzung vun engem Plattform-baséiert Messagerie Mechanismus Red Hat OpenShift. Fir méi Detailer iwwer wéi et funktionnéiert, kuckt hier (EN). Haut wäerte mir Iech weisen wéi Dir AMQ Online a Quarkus kombinéiere kënnt fir e modernen OpenShift-baséiert Messagerie System mat zwee neie Messagerie Technologien ze bauen.

Et gëtt ugeholl datt Dir schonn AMQ Online op der OpenShift Plattform ofgesat hutt (wann net, da kuckt Installatioun Guide).

Fir unzefänken erstellen mir eng Quarkus Applikatioun déi en einfachen Uerdnungsveraarbechtungssystem gëtt mat reaktive Messagerie. Dës Applikatioun enthält en Uerdnungsgenerator deen Bestellungen an eng Messageschlaang mat engem fixen Intervall schéckt, souwéi en Uerdnungsprozessor deen Messagen aus der Schlaang veraarbecht an Bestätegungen generéiert, déi am Browser sichtbar sinn.

Wann mir d'Applikatioun erstallt hunn, wäerte mir Iech weisen wéi Dir d'Messaging System Konfiguratioun an d'Applikatioun embett an AMQ Online benotzt fir d'Ressourcen ze versuergen déi mir um System brauchen.

Quark App

Eis Quarkus Applikatioun leeft op OpenShift an ass eng modifizéiert Versioun vum Programm amqp-Quickstart. E komplett Beispill vun der Client Säit kann fonnt ginn hei.

Uerdnung Generator

De Generator schéckt einfach monoton wuessend Bestellung IDen op d'"Bestellung" Adress all 5 Sekonnen.

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

Uerdnung Prozessor

D'Bestellung Handler ass nach méi einfach, et gëtt just eng Confirmatiouns ID op d'"Confirmatiouns" Adress zréck.

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

Confirmatiouns Ressourcen

D'Confirmatiounsressource ass en HTTP-Endpunkt fir d'Bestätegungen opzeféieren, déi vun eiser Applikatioun generéiert ginn.

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

Upassung

Fir mat AMQ Online ze verbannen, brauch eis Applikatioun e puer Konfiguratiounsdaten, nämlech: Quarkus Connector Konfiguratioun, AMQP Endpunktinformatioun a Client Umeldungsinformatiounen. Et ass natierlech besser all d'Konfiguratiounsdaten op enger Plaz ze halen, awer mir wäerte se bewosst trennen fir déi méiglech Optiounen ze weisen fir d'Quarkus Applikatioun ze konfiguréieren.

Connectoren

Connector Konfiguratioun kann zur Kompiléierungszäit zur Verfügung gestallt ginn mat enger Applikatiounseigenschaftsdatei:

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

Fir d'Saache einfach ze halen, benotze mir nëmmen eng Messageschlaang fir d'"Bestellung" Adress. An d'"Confirmatiouns" Adress an eiser Applikatioun wäert eng Schlaang an der Erënnerung benotzen.

AMQP Endpunkt

Beim Kompiléierungszäit sinn den Hostnumm an d'Portnummer fir den AMQP Endpunkt onbekannt, also musse se injizéiert ginn. Den Endpunkt kann an der Configmap gesat ginn, déi vun AMQ Online erstallt gëtt, sou datt mir se duerch Ëmfeldvariablen am Applikatiounsmanifest definéieren:

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

Umeldungsinformatioune

De Servicekonto Token kann benotzt ginn fir eis Applikatioun op OpenShift ze authentifizéieren. Fir dëst ze maachen, musst Dir als éischt e personaliséierte ConfigSource erstellen, deen d'Authentifikatiounstoken aus dem Dateiesystem vum Pod liest:

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

Bauen an deploy d'Applikatioun

Well d'Applikatioun muss an eng ausführbar Datei kompiléiert ginn, ass eng GraalVM virtuell Maschinn erfuerderlech. Fir Detailer iwwer wéi een en Ëmfeld fir dëst opbaut, kuckt déi entspriechend Instruktiounen an Quarkus Guide.

Dann, no den Instruktiounen déi do ginn, musst Dir d'Quell eroflueden, bauen an eis Applikatioun ofsetzen:

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

No dëse Kommandoen gëtt d'Applikatioun ofgesat, awer fänkt net un, bis mir d'Messageressourcen konfiguréieren, déi mir am AMQ Online brauchen.

Astellung vum Messagerie System

Elo bleift et just d'Ressourcen ze setzen déi eis Applikatioun am Messagesystem brauch. Fir dëst ze maachen, musst Dir erstellen: 1) en Adressraum fir de Messagesystem Endpunkt ze initialiséieren; 2) Adress fir d'Adressen ze konfiguréieren déi mir an der Applikatioun benotzen; 3) Messagerie Benotzer fir Client Umeldungsinformatiounen ze setzen.

Adress Plaz

En AddressSpace Objet am AMQ Online ass eng Grupp vun Adressen déi Verbindungsendpunkten an Authentifikatiouns- an Autorisatiounspolitik deelen. Wann Dir en Adressraum erstellt, kënnt Dir spezifizéieren wéi d'Messaging Endpunkter ausgesat ginn:

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

Adresse gi benotzt fir Messagen ze schécken an ze kréien. All Adress huet eng Aart, déi seng Semantik bestëmmt, wéi och e Plang, deen d'Zuel vun de Ressourcen spezifizéiert, déi reservéiert ginn. D'Adress kann zum Beispill esou festgeluecht ginn:

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

Messagerie Benotzer

Fir sécherzestellen datt nëmmen vertrauenswürdege Applikatioune Messagen op Är Adresse schécken a kréien, musst Dir e Benotzer am Messageriesystem erstellen. Fir Uwendungen déi op engem Cluster lafen, kënnen d'Clientë mat engem OpenShift Service Kont authentifizéiert ginn. De Benotzer "Serviceaccount" kann zum Beispill esou definéiert ginn:

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

Permissiounen fir d'Applikatioun ze konfiguréieren

Fir datt AMQ Online d'Konfiguratiounskaart erstellt, déi mir benotzt hunn fir d'AMQP Endpunktinformatioun z'integréieren, muss d'Role an d'RoleBinding gesat ginn:

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

Wéi Konfiguratiounen ze gëllen

Dir kënnt d'Messagesystemkonfiguratioun esou applizéieren:

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

Applikatioun Verifikatioun

Fir sécherzestellen datt d'Applikatioun ugefaang huet, loosst eis als éischt kucken ob déi entspriechend Adressen erstallt sinn an aktiv sinn:

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

Da loosst eis d'URL vun der Applikatiounsroute iwwerpréiwen (just dës Adress am Browser opmaachen):

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

De Browser soll weisen datt d'Tickete periodesch aktualiséiert ginn wéi Messagen vun AMQ Online geschéckt a kritt ginn.

Ze summéieren

Also hu mir eng Quarkus Applikatioun geschriwwen déi AMQP fir Messagerie benotzt, d'Applikatioun konfiguréiert fir op der Red Hat OpenShift Plattform ze lafen, an hir Konfiguratioun op Basis vun der AMQ Online Konfiguratioun implementéiert. Mir hunn dunn d'Manifester erstallt fir de Messageriesystem fir eis Applikatioun z'initialiséieren.

Dëst schléisst d'Serie iwwer Quarkus of, awer et gëtt vill nei an interessant Saache viru, bleift drun!

Source: will.com

Setzt e Commentaire