Messaggistica basata su cloud sulla piattaforma Red Hat OpenShift utilizzando Quarkus e AMQ Online

Ciao a tutti! Eccolo qui: il nostro post finale della serie Quarkus! (A proposito, guarda il nostro webinar “Questo è il framework Java nativo di Quarkus – Kubernetes”. Ti mostreremo come iniziare da zero o trasferire soluzioni già pronte)

Messaggistica basata su cloud sulla piattaforma Red Hat OpenShift utilizzando Quarkus e AMQ Online

В precedente In questo post abbiamo esaminato gli strumenti rilevanti che possono essere utilizzati per quantificare i miglioramenti ottenuti come risultato della modernizzazione delle applicazioni Java.

Dalla versione 0.17.0, Quarkù supporta l'uso del protocollo Advanced Message Queuing (AMQP), che è uno standard aperto per il trasferimento di messaggi aziendali tra applicazioni o organizzazioni.

Red Hat AMQ in linea è un servizio costruito sulla base di un progetto open source enmasse e l'implementazione di un meccanismo di messaggistica basato su piattaforma Red Hat OpenShift. Per maggiori dettagli su come funziona, vedere qui (EN). Oggi ti mostreremo come combinare AMQ Online e Quarkus per creare un moderno sistema di messaggistica basato su OpenShift utilizzando due nuove tecnologie di messaggistica.

Si presuppone che tu abbia già distribuito AMQ Online sulla piattaforma OpenShift (in caso contrario, consulta guida d'installazione).

Per iniziare, creeremo un'applicazione Quarkus che sarà un semplice sistema di elaborazione degli ordini utilizzando la messaggistica reattiva. Questa applicazione includerà un generatore di ordini che invia ordini a una coda di messaggi a un intervallo fisso, nonché un processore di ordini che elaborerà i messaggi dalla coda e genererà conferme visualizzabili nel browser.

Una volta creata l'applicazione, ti mostreremo come incorporare la configurazione del sistema di messaggistica nell'applicazione e utilizzare AMQ Online per fornire le risorse di cui abbiamo bisogno nel sistema.

Applicazione Quarkus

La nostra applicazione Quarkus funziona su OpenShift ed è una versione modificata del programma amqp-avvio rapido. È possibile trovare un esempio completo del lato client qui.

Generatore di ordini

Il generatore invia semplicemente in modo monotono ID ordine crescenti all'indirizzo "ordini" ogni 5 secondi.

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

Elaboratore degli ordini

Il gestore dell'ordine è ancora più semplice, restituisce semplicemente un ID di conferma all'indirizzo "conferme".

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

Risorse per la conferma

La risorsa di conferma è un endpoint HTTP per elencare le conferme generate dalla nostra applicazione.

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

registrazione

Per connettersi ad AMQ Online, la nostra applicazione avrà bisogno di alcuni dati di configurazione, vale a dire: configurazione del connettore Quarkus, informazioni sull'endpoint AMQP e credenziali del client. Naturalmente è meglio conservare tutti i dati di configurazione in un unico posto, ma li separeremo deliberatamente per mostrare le possibili opzioni per configurare l'applicazione Quarkus.

Connettori

La configurazione del connettore può essere fornita in fase di compilazione utilizzando un file delle proprietà dell'applicazione:

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

Per semplificare le cose, utilizzeremo una coda di messaggi solo per l'indirizzo "ordini". E l'indirizzo "conferme" nella nostra applicazione utilizzerà una coda in memoria.

Endpoint AMQP

In fase di compilazione, il nome host e il numero di porta per l'endpoint AMQP sono sconosciuti, quindi devono essere inseriti. L'endpoint può essere impostato nella mappa di configurazione creata da AMQ Online, quindi li definiremo tramite variabili di ambiente nel manifest dell'applicazione:

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

Credenziali

Il token dell'account di servizio può essere utilizzato per autenticare la nostra applicazione su OpenShift. Per fare ciò, devi prima creare un ConfigSource personalizzato che leggerà il token di autenticazione dal file system del 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);
    }
}

Costruisci e distribuisci l'applicazione

Poiché l'applicazione deve essere compilata in un file eseguibile, è necessaria una macchina virtuale GraalVM. Per i dettagli su come configurare un ambiente per questo, vedere le istruzioni corrispondenti in Guida Quarkus.

Quindi, seguendo le istruzioni fornite lì, è necessario scaricare il sorgente, creare e distribuire la nostra applicazione:

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

Dopo questi comandi, l'applicazione verrà distribuita, ma non verrà avviata finché non verranno configurate le risorse di messaggistica di cui abbiamo bisogno in AMQ Online.

Configurazione del sistema di messaggistica

Ora non resta che impostare le risorse di cui ha bisogno la nostra applicazione nel sistema di messaggistica. Per fare ciò è necessario creare: 1) uno spazio indirizzi per inizializzare l'endpoint del sistema di messaggistica; 2) indirizzo per configurare gli indirizzi che utilizziamo nell'applicazione; 3) Messaggistica all'utente per impostare le credenziali del client.

Spazio degli indirizzi

Un oggetto AddressSpace in AMQ Online è un gruppo di indirizzi che condividono endpoint di connessione e policy di autenticazione e autorizzazione. Quando crei uno spazio indirizzo, puoi specificare come verranno esposti gli endpoint di messaggistica:

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

Адреса

Gli indirizzi vengono utilizzati per inviare e ricevere messaggi. Ogni indirizzo ha un tipo, che ne determina la semantica, nonché un piano, che specifica il numero di risorse da riservare. L'indirizzo può essere determinato, ad esempio, in questo modo:

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

Utente di messaggistica

Per garantire che solo le applicazioni attendibili possano inviare e ricevere messaggi ai tuoi indirizzi, devi creare un utente nel sistema di messaggistica. Per le applicazioni in esecuzione su un cluster, i client possono essere autenticati utilizzando un account di servizio OpenShift. L'utente "serviceaccount" può essere definito, ad esempio, in questo modo:

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

Autorizzazioni per configurare l'applicazione

Affinché AMQ Online possa creare la mappa di configurazione utilizzata per incorporare le informazioni sull'endpoint AMQP, è necessario impostare Role e 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

Come applicare le configurazioni

È possibile applicare la configurazione del sistema di messaggistica in questo modo:

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

Verifica della domanda

Per essere sicuri che l'applicazione sia stata avviata, controlliamo innanzitutto se gli indirizzi corrispondenti sono stati creati e sono attivi:

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

Quindi controlliamo l'URL del percorso dell'applicazione (basta aprire questo indirizzo nel browser):

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

Il browser dovrebbe mostrare che i ticket vengono aggiornati periodicamente man mano che i messaggi vengono inviati e ricevuti da AMQ Online.

Riassumendo

Abbiamo quindi scritto un'applicazione Quarkus che utilizza AMQP per la messaggistica, configurato l'applicazione per l'esecuzione sulla piattaforma Red Hat OpenShift e implementata la sua configurazione in base alla configurazione AMQ Online. Abbiamo quindi creato i manifest necessari per inizializzare il sistema di messaggistica per la nostra applicazione.

Questo conclude la serie su Quarkus, ma ci sono molte cose nuove e interessanti in vista, rimanete sintonizzati!

Fonte: habr.com

Aggiungi un commento