Scambio di messaggi orientato al cloud sulla piattaforma Red Hat OpenShift utilizzando Quarkus e AMQ Online

Ciao a tutti! Ecco il nostro ultimo post della serie su Quarkus! (A proposito, guarda il nostro webinar «Quarkus è un framework Java nativo per Kubernetes». Mostreremo come iniziare «da zero» o migrare soluzioni esistenti)

Scambio di messaggi orientato al cloud sulla piattaforma Red Hat OpenShift utilizzando Quarkus e AMQ Online

In precedente In questo post abbiamo esaminato gli strumenti appropriati che consentono di valutare quantitativamente i miglioramenti ottenuti a seguito della modernizzazione delle applicazioni Java.

A partire dalla versione 0.17.0, Quarkus supporta l'uso del Advanced Message Queuing Protocol (AMQP), che è uno standard aperto per la trasmissione di messaggi aziendali tra applicazioni o organizzazioni.

Red Hat AMQ Online è un servizio basato su un progetto open source EnMasse che implementa un meccanismo di scambio di messaggi sulla piattaforma Red Hat OpenShift. Maggiori dettagli su come funziona possono essere trovati qui (EN). Oggi mostreremo come integrare AMQ Online e Quarkus per costruire un moderno sistema di messaggistica basato su OpenShift, utilizzando due nuove tecnologie legate all'elaborazione dei messaggi.

Si presume che tu abbia già distribuito AMQ Online sulla piattaforma OpenShift (se non lo hai fatto, consulta la guida all'installazione).

Iniziamo creando un'applicazione Quarkus che fungerà da semplice sistema di gestione degli ordini utilizzando la messaggistica reattiva. Questa applicazione includerà un generatore di ordini che invierà ordini in una coda di messaggi a intervalli fissi, oltre a un gestore di ordini che elaborerà i messaggi dalla coda e formerà le conferme disponibili per la visualizzazione nel browser.

Dopo aver creato l'applicazione, mostreremo come integrare la configurazione del sistema di messaggistica e utilizzeremo AMQ Online per inizializzare le risorse necessarie su questo sistema.

Applicazione Quarkus

La nostra applicazione Quarkus è in esecuzione su OpenShift e rappresenta una versione modificata del programma amqp-quickstart. È possibile trovare un esempio completo della parte client qui.

Generatore di ordini

Il generatore invia monotonicamente identificatori di ordini crescenti all'indirizzo "orders" ogni 5 secondi.

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

Gestore di ordini

Il gestore degli ordini è ancora più semplice, restituisce solo l'identificativo di conferma all'indirizzo "confirmations".

@ApplicationScoped
public class OrderProcessor {
    @Incoming("orders")
    @Outgoing("confirmations")
    public Integer process(Integer order) {
        // L'identificatore della conferma è uguale al doppio dell'identificatore dell'ordine <img draggable="false" class="emoji" alt=":-)" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f642.svg">
        return order * 2;
    }
}

Risorse di conferma

La risorsa di conferma è un endpoint HTTP per elencare le conferme generate dall'applicazione.

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

Impostazione

Per connettersi ad AMQ Online, la nostra applicazione avrà bisogno di alcune informazioni di configurazione, ovvero: la configurazione del connettore Quarkus, i dettagli dell'endpoint AMQP e le credenziali del client. È meglio tenere tutte le informazioni di configurazione in un solo posto, ma le divideremo appositamente per mostrare le diverse opzioni di configurazione dell'applicazione Quarkus.

Connettori

La configurazione del connettore può essere fornita al momento della compilazione tramite un file di proprietà dell'applicazione:

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

Per semplificare, utilizzeremo la coda dei messaggi solo per l'indirizzo «orders». L'indirizzo «confirmations» nel nostro applicativo utilizzerà una coda in memoria.

Endpoint AMQP

Durante la fase di compilazione, il nome host e il numero di porta per l'endpoint AMQP non sono noti, quindi devono essere iniettati. L'endpoint può essere specificato in un configmap creato da AMQ Online, quindi li definiremo tramite variabili di ambiente nel manifesto 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 del servizio può essere utilizzato per autenticare la nostra applicazione in OpenShift. Per fare ciò, è necessario prima creare un ConfigSource personalizzato che legga il token di autenticazione dal filesystem del pod:

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

Assemblaggio e distribuzione dell'applicazione

Poiché l'applicazione deve essere compilata in un file eseguibile, sarà necessaria una macchina virtuale GraalVM. Per ulteriori dettagli su come configurare l'ambiente, consultare le istruzioni corrispondenti in Guida a Quarkus.

Poi, seguendo le istruzioni fornite, dobbiamo scaricare il codice sorgente, effettuare la compilazione e eseguire il deployment della 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 sarà deployata, ma non partirà finché non configuriamo le risorse di messaggistica necessarie in AMQ Online.

Configurazione del sistema di messaggistica

Ora dobbiamo specificare nel sistema di messaggistica le risorse necessarie per la nostra applicazione. A questo scopo, è necessario creare: 1) uno spazio dei nomi per inizializzare il punto finale del sistema di messaggistica; 2) un indirizzo per configurare gli indirizzi che utilizziamo nell'applicazione; 3) un utente del sistema di messaggistica per impostare le credenziali del client.

Spazio degli indirizzi

L'oggetto AddressSpace in AMQ Online è un gruppo di indirizzi che condividono le stesse endpoint di connessione, così come le politiche di autenticazione e autorizzazione. Durante la creazione di uno spazio indirizzi, è possibile specificare come verranno fornite le endpoint del sistema 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

Gli indirizzi vengono utilizzati per spedire e ricevere messaggi. Ogni indirizzo ha un tipo che determina la sua semantica, oltre a un piano che specifica il numero di risorse riservate. Un indirizzo può essere definito, 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 del sistema di messaggistica

Per consentire solo alle applicazioni fidate di inviare e ricevere messaggi sui tuoi indirizzi, è necessario creare un utente nel sistema di messaggistica. Per le applicazioni che operano nel 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"]

Permessi per configurare l'applicazione

Affinché AMQ Online possa creare il configmap che abbiamo usato per integrare le informazioni sul punto finale AMQP, è necessario impostare un ruolo e un binding del ruolo (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

Puoi 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 dell'applicazione

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

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

Poi verificheremo l'URL del percorso dell'applicazione (apriamo semplicemente questo indirizzo nel browser):

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

Nel browser, dovrebbe essere visibile che i ticket si aggiornano periodicamente mentre i messaggi vengono inviati e ricevuti tramite AMQ Online.

Tiriamo le somme

Quindi, abbiamo scritto un'applicazione Quarkus che utilizza AMQP per la messaggistica, configurato questa applicazione per funzionare sulla piattaforma Red Hat OpenShift e implementato la sua configurazione basata su quella di AMQ Online. Successivamente, abbiamo creato i manifesti necessari per inizializzare il sistema di messaggistica per la nostra applicazione.

Così concludiamo la nostra serie su Quarkus, ma ci sono molte novità interessanti in arrivo, rimanete con noi!

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster