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

Ciao a tutti! Eccolo qui – il nostro post finale della serie su Quarkus! (A proposito, guarda il nostro webinar «Questo è 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 nel post abbiamo esaminato gli strumenti appropriati con cui è possibile valutare quantitativamente i miglioramenti ottenuti a seguito della modernizzazione delle applicazioni Java.

A partire dalla versione 0.17.0, Quarkus supporta l'uso dell'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 e implementa un meccanismo di scambio di messaggi sulla piattaforma Red Hat OpenShift. Maggiori dettagli su come è strutturato possono essere trovati qui (EN). Oggi mostreremo come combinare 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 (in caso contrario, consulta la guida all'installazione).

Per prima cosa, creeremo un'applicazione Quarkus che rappresenterà un semplice sistema di gestione degli ordini utilizzando uno scambio di messaggi reattivo. Questa applicazione includerà un generatore di ordini che invia ordini a una coda di messaggi a intervallo fisso, oltre a un gestore di ordini che elaborerà i messaggi dalla coda e genererà conferme disponibili per la visualizzazione nel browser.

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

Applicazione Quarkus

La nostra applicazione Quarkus è eseguita su OpenShift ed è una versione modificata del programma amqp-quickstart. Un esempio completo della parte client può essere trovato qui.

Generatore di ordini

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

@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 di ordini è ancora più semplice, restituisce semplicemente l'identificatore della conferma all'indirizzo «confirmations».

@ApplicationScoped
public class OrderProcessor {
    @Incoming("orders")
    @Outgoing("confirmations")
    public Integer process(Integer order) {
        // L'identificatore di 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 l'elenco delle conferme generate dal funzionamento della nostra 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;
    }
}

Configurazione

Per connettersi ad AMQ Online, la nostra applicazione avrà bisogno di alcuni dati di configurazione, ovvero: la configurazione del connettore Quarkus, i dettagli dell'endpoint AMQP e le credenziali del cliente. È meglio mantenere tutte le informazioni di configurazione in un posto unico, ma per dimostrare le possibili varianti di configurazione dell'applicazione Quarkus, le separeremo.

Connettori

La configurazione del connettore può essere fornita in fase di compilazione utilizzando 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" nella nostra applicazione utilizzerà invece una coda in memoria.

Endpoint AMQP

In 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, che viene creato da AMQ Online, quindi li definiremo tramite variabili 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 dell'account di servizio può essere utilizzato per autenticare la nostra applicazione in OpenShift. Per fare ciò, è necessario prima creare una ConfigSource personalizzata, che leggerà il token di autenticazione dal file system 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);
    }
}

Compilazione e distribuzione dell'applicazione

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

Successivamente, seguendo le istruzioni fornite, è necessario scaricare il codice sorgente, effettuare la compilazione 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 sarà distribuita, ma non verrà avviata fino a quando non configuraremo le risorse di messaggistica necessarie in AMQ Online.

Configurazione del sistema di messaggistica

Ora è necessario definire nel sistema di messaggistica le risorse di cui ha bisogno la nostra applicazione. A tal fine, bisogna 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 fornire le credenziali del cliente.

Spazio degli indirizzi

L'oggetto AddressSpace in AMQ Online è un gruppo di indirizzi che condividono i punti finali di connessione e le politiche di autenticazione e autorizzazione. Quando si crea uno spazio degli indirizzi, è possibile definire come verranno forniti i punti finali 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

Indirizzo

Gli indirizzi vengono utilizzati per inviare e ricevere messaggi. Ogni indirizzo ha un tipo che ne definisce la semantica, oltre a un piano che stabilisce 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 inviare e ricevere messaggi sui tuoi indirizzi, solo le applicazioni fidate devono poterlo fare, quindi è necessario creare un utente nel sistema di messaggistica. Per le applicazioni che operano nel cluster, i client possono essere autenticati utilizzando un conto 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 la configurazione dell'applicazione

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

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

Per assicurarti che l'applicazione sia stata avviata, prima di tutto verifichiamo 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

Dopo verificheremo 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"

Nel browser dovrebbe essere visibile che i biglietti si aggiornano periodicamente mentre i messaggi vengono inviati e ricevuti da AMQ Online.

Riepiloghiamo

Abbiamo quindi scritto un'applicazione Quarkus che utilizza AMQP per lo scambio di messaggi, configurato quest'applicazione per funzionare sulla piattaforma Red Hat OpenShift e implementato la sua configurazione basata sulla configurazione di AMQ Online. Abbiamo quindi creato i manifesti necessari per inizializzare il sistema di scambio di messaggi per la nostra applicazione.

Con questo concludiamo la serie su Quarkus, ma ci sono molte novità interessanti in arrivo, restate 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