Schimb de mesaje orientat pe cloud pe platforma Red Hat OpenShift utilizând Quarkus și AMQ Online

Salut tuturor! Iată-l – ultima noastră postare din seria despre Quarkus! (Apropo, urmăriți webinarul nostru „Acesta este Quarkus – un framework Java nativ pentru Kubernetes”. Vă vom arăta cum să începeți „de la zero” sau să migrați soluții deja existente)

Schimb de mesaje orientat pe cloud pe platforma Red Hat OpenShift utilizând Quarkus și AMQ Online

În anterior în această postare am analizat instrumentele corespunzătoare, cu ajutorul cărora putem evalua cantitativ îmbunătățirile obținute în urma modernizării aplicațiilor Java.

Începând cu versiunea 0.17.0, Quarkus acceptă utilizarea Advanced Message Queuing Protocol (AMQP), care este un standard deschis pentru transmiterea mesajelor de afaceri între aplicații sau organizații.

Red Hat AMQ Online este un serviciu bazat pe un proiect deschis EnMasse și implementează un mecanism de schimb de mesaje pe platforma Red Hat OpenShift. Aflati mai multe despre cum este structurat acesta, vezi aici (EN).. Astăzi, vă vom arăta cum să combinăm AMQ Online și Quarkus pentru a construi un sistem modern de schimb de mesaje pe OpenShift, folosind două tehnologii noi legate de manipularea mesajelor.

Se consideră că ați desfășurat deja AMQ Online pe platforma OpenShift (dacă nu, consultați ghidul de instalare).

Pentru început, vom crea aplicația Quarkus, care va reprezenta un sistem simplu de procesare a comenzilor folosind schimbul de mesaje reactive. Această aplicație va include un generator de comenzi care trimite comenzile în coada de mesaje la un interval fix, precum și un procesor de comenzi care va manipula mesajele din coadă și va genera confirmări disponibile pentru vizualizare în browser.

După crearea aplicației, vă vom arăta cum să implementați configurația sistemului de schimb de mesaje și vom folosi AMQ Online pentru a iniția resursele necesare în acest sistem.

Aplicația Quarkus

Aplicația noastră Quarkus rulează pe OpenShift și este o versiune modificată a programului amqp-quickstart. Un exemplu complet al părții client poate fi găsit aici.

Generatorul de comenzi

Generatorul trimite monoton, la fiecare 5 secunde, identificatori crescători ai comenzilor la adresa „orders”.

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

Procesorul de comenzi

Procesorul de comenzi este și mai simplu, întorcând doar identificatorul de confirmare la adresa „confirmations”.

@ApplicationScoped
public class OrderProcessor {
    @Incoming("orders")
    @Outgoing("confirmations")
    public Integer process(Integer order) {
        // Identificatorul confirmării este dublul identificatorului comenzii <img draggable="false" class="emoji" alt=":-)" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f642.svg">
        return order * 2;
    }
}

Resursele de confirmare

Resursa de confirmare este un punct final HTTP pentru lista confirmațiilor generate de aplicația noastră.

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

Configurare

Pentru a ne conecta la AMQ Online, aplicația noastră va avea nevoie de câteva date de configurare, și anume: configurația conectorului Quarkus, informații despre punctul final AMQP și acreditivele clientului. Ideal, toate datele de configurare ar trebui să fie centralizate, dar le vom împărți pentru a arăta posibile opțiuni de configurare pentru aplicația Quarkus.

Conectori

Configurația conectorului poate fi furnizată în timpul compilării prin intermediul unui fișier de proprietăți al aplicației:

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

Pentru a simplifica, vom folosi o coadă de mesaje doar pentru adresa „orders”. Adresa „confirmations” din aplicația noastră va utiliza o coadă în memorie.

Punctul final AMQP

În timpul compilării, numele gazdelor și numărul portului pentru punctul final AMQP nu sunt cunoscute, așa că trebuie să le injectăm. Punctul final poate fi definit în configmap-ul creat de AMQ Online, așa că vom stabili aceste variabile prin variabile de mediu în manifestul aplicației:

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

Datele de autentificare

Tokenul contului de serviciu poate fi utilizat pentru a autentifica aplicația noastră în OpenShift. Pentru aceasta, trebuie mai întâi să creăm un ConfigSource personalizat, care va citi tokenul de autentificare din sistemul de fișiere al pod-ului:

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

Compilarea și desfășurarea aplicației

Deoarece aplicația trebuie compilată într-un fișier executabil, va fi nevoie de o mașină virtuală GraalVM. Mai multe informații despre cum să configurați acest mediu găsiți în instrucțiunile corespunzătoare din Ghidul Quarkus.

Apoi, urmând instrucțiunile de acolo, va trebui să descărcați sursa, să efectuați compilarea și să desfășurați aplicația noastră:

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

După aceste comenzi, aplicația va fi desfășurată, dar nu se va lansa până nu vom configura resursele necesare pentru mesagerie în AMQ Online.

Configurarea sistemului de mesagerie

Acum trebuie să definim în sistemul de mesagerie resursele de care are nevoie aplicația noastră. Pentru aceasta trebuie să creăm: 1) un spațiu de adresare, pentru a inițializa punctul final al sistemului de mesagerie; 2) o adresă, pentru a configura adresele utilizate în aplicație; 3) un utilizator al sistemului de mesagerie, pentru a stabili acreditivele clientului.

Spațiul de adresare

Obiectul AddressSpace din AMQ Online este un grup de adrese care utilizează împreună punctele finale de conectare, precum și politicile de autentificare și autorizare. Când creați un spațiu de adresare, puteți specifica modul în care vor fi furnizate punctele finale ale sistemului de mesagerie:

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

Adrese

Adresele sunt folosite pentru a trimite și a primi mesaje. Fiecare adresă are un tip care îi definește semantica, precum și un plan care stabilește cantitatea de resurse rezervate. O adresă poate fi definită, de exemplu, astfel:

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

Utilizator al sistemului de mesagerie

Pentru a permite aplicatiilor de încredere să trimită și să primească mesaje pe adresele dvs., trebuie să creați un utilizator în sistemul de mesagerie. Pentru aplicațiile care rulează pe cluster, clienții pot fi autentificați folosind un cont de serviciu OpenShift. Utilizatorul „serviceaccount” poate fi definit, de exemplu, astfel:

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

Permisiuni pentru configurarea aplicației

Pentru ca AMQ Online să poată crea configmap-ul pe care l-am folosit pentru a inieța informațiile despre punctul final AMQP, trebuie să definim un rol și o legătură de rol (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

Cum să aplicați configurațiile

Configurarea sistemului de mesagerie poate fi aplicată astfel:

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

Verificarea aplicației

Pentru a ne asigura că aplicația s-a lansat, în primul rând verificăm dacă adresele corespunzătoare au fost create și sunt active:

until [[ `oc get address quarkus-example.prices -o jsonpath='{.status.phase}'` == "Active" ]]; do echo "Nu este încă gata"; sleep 5; done

Apoi, verificăm URL-ul rutei aplicației (pur și simplu vom deschide această adresă în browser):

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

În browser ar trebui să puteți observa că ticetele se actualizează periodic pe măsură ce mesajele sunt trimise și primite de AMQ Online.

Încheiem

Astfel, am scris o aplicație Quarkus care folosește AMQP pentru schimbul de mesaje, am configurat această aplicație pentru a rula pe platforma Red Hat OpenShift și am implementat configurația sa pe baza configurației AMQ Online. Apoi, am creat manifestele necesare pentru a iniția sistemul de schimb de mesaje pentru aplicația noastră.

Aici încheiem seria despre Quarkus, dar ne așteaptă multe noutăți interesante, rămâneți cu noi!

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster