Mensajería nativa de la nube en la plataforma Red Hat OpenShift usando Quarkus y AMQ Online

¡Hola a todos! Aquí está: ¡nuestra publicación final de la serie Quarkus! (Por cierto, mira nuestro seminario web "Este es Quarkus: el marco Java nativo de Kubernetes". Le mostraremos cómo empezar desde cero o transferir soluciones ya preparadas)

Mensajería nativa de la nube en la plataforma Red Hat OpenShift usando Quarkus y AMQ Online

В anterior En esta publicación, analizamos las herramientas relevantes que se pueden utilizar para cuantificar las mejoras obtenidas como resultado de la modernización de las aplicaciones Java.

Desde la versión 0.17.0, cuarcus admite el uso del protocolo avanzado de cola de mensajes (AMQP), que es un estándar abierto para transferir mensajes comerciales entre aplicaciones u organizaciones.

Red Hat AMQ en línea es un servicio construido sobre la base de un proyecto de código abierto En masa e implementar un mecanismo de mensajería basado en plataforma Red Hat OpenShift. Para obtener más detalles sobre cómo funciona, consulte aquí (ES). Hoy le mostraremos cómo combinar AMQ Online y Quarkus para crear un sistema de mensajería moderno basado en OpenShift utilizando dos nuevas tecnologías de mensajería.

Se supone que ya ha implementado AMQ Online en la plataforma OpenShift (si no, consulte guía de instalación).

Para comenzar, crearemos una aplicación Quarkus que será un sistema de procesamiento de pedidos simple que utilizará mensajería reactiva. Esta aplicación incluirá un generador de pedidos que envía pedidos a una cola de mensajes en un intervalo fijo, así como un procesador de pedidos que procesará mensajes de la cola y generará confirmaciones visibles en el navegador.

Una vez que hayamos creado la aplicación, le mostraremos cómo integrar la configuración del sistema de mensajería en la aplicación y usar AMQ Online para aprovisionar los recursos que necesitamos en el sistema.

Aplicación Quarkus

Nuestra aplicación Quarkus se ejecuta en OpenShift y es una versión modificada del programa. amqp-inicio rápido. Puede encontrar un ejemplo completo del lado del cliente. aquí.

Generador de pedidos

El generador simplemente envía monótonamente ID de pedidos crecientes a la dirección de "pedidos" cada 5 segundos.

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

Procesador de pedidos

El gestor de pedidos es aún más sencillo: simplemente devuelve un ID de confirmación a la dirección de "confirmaciones".

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

Recursos de confirmación

El recurso de confirmación es un punto final HTTP para enumerar las confirmaciones generadas por nuestra aplicación.

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

Ajuste

Para conectarse a AMQ Online, nuestra aplicación necesitará algunos datos de configuración, a saber: configuración del conector Quarkus, información del punto final AMQP y credenciales del cliente. Por supuesto, es mejor mantener todos los datos de configuración en un solo lugar, pero los separaremos deliberadamente para mostrar las posibles opciones para configurar la aplicación Quarkus.

Conectores

La configuración del conector se puede proporcionar en tiempo de compilación mediante un archivo de propiedades de la aplicación:

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

Para simplificar las cosas, solo usaremos una cola de mensajes para la dirección de "pedidos". Y la dirección de "confirmaciones" en nuestra aplicación utilizará una cola en la memoria.

Punto final AMQP

En el momento de la compilación, se desconocen el nombre de host y el número de puerto del punto final AMQP, por lo que deben inyectarse. El punto final se puede configurar en el mapa de configuración creado por AMQ Online, por lo que los definiremos a través de variables de entorno en el manifiesto de la aplicación:

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

Cartas credenciales

El token de la cuenta de servicio se puede utilizar para autenticar nuestra aplicación en OpenShift. Para hacer esto, primero debe crear un ConfigSource personalizado que leerá el token de autenticación del sistema de archivos 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);
    }
}

Construya e implemente la aplicación

Dado que la aplicación debe compilarse en un archivo ejecutable, se requiere una máquina virtual GraalVM. Para obtener detalles sobre cómo configurar un entorno para esto, consulte las instrucciones correspondientes en Guía de cuarkus.

Luego, siguiendo las instrucciones que se proporcionan allí, debe descargar el código fuente, compilar e implementar nuestra aplicación:

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

Tras estos comandos la aplicación se desplegará, pero no se iniciará hasta que configuremos los recursos de mensajería que necesitamos en AMQ Online.

Configurar el sistema de mensajería

Ahora solo queda configurar los recursos que necesita nuestra aplicación en el sistema de mensajería. Para hacer esto, necesita crear: 1) un espacio de direcciones para inicializar el punto final del sistema de mensajería; 2) dirección para configurar las direcciones que utilizamos en la aplicación; 3) Usuario de mensajería para configurar las credenciales del cliente.

Espacio de dirección

Un objeto AddressSpace en AMQ Online es un grupo de direcciones que comparten puntos finales de conexión y políticas de autenticación y autorización. Cuando crea un espacio de direcciones, puede especificar cómo se expondrán los puntos finales de mensajería:

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

Адреса

Las direcciones se utilizan para enviar y recibir mensajes. Cada dirección tiene un tipo, que determina su semántica, así como un plan, que especifica la cantidad de recursos que se reservarán. La dirección se puede determinar, por ejemplo, así:

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

Usuario de mensajería

Para garantizar que solo las aplicaciones confiables puedan enviar y recibir mensajes a sus direcciones, debe crear un usuario en el sistema de mensajería. Para las aplicaciones que se ejecutan en un clúster, los clientes se pueden autenticar mediante una cuenta de servicio OpenShift. El usuario "cuenta de servicio" se puede definir, por ejemplo, así:

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

Permisos para configurar la aplicación.

Para que AMQ Online cree el mapa de configuración que usamos para incrustar la información del punto final AMQP, debemos configurar Role y 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

Cómo aplicar configuraciones

Puede aplicar la configuración del sistema de mensajería de esta manera:

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

Verificación de la aplicación

Para asegurarnos de que la aplicación se ha iniciado, en primer lugar comprobemos si las direcciones correspondientes han sido creadas y están activas:

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

Luego verifiquemos la URL de la ruta de la aplicación (simplemente abra esta dirección en el navegador):

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

El navegador debe mostrar que los tickets se actualizan periódicamente a medida que AMQ Online envía y recibe mensajes.

En resumen

Entonces, escribimos una aplicación Quarkus que usa AMQP para mensajería, configuramos la aplicación para que se ejecute en la plataforma Red Hat OpenShift e implementamos su configuración basada en la configuración de AMQ Online. Luego creamos los manifiestos necesarios para inicializar el sistema de mensajería de nuestra aplicación.

Esto concluye la serie sobre Quarkus, pero hay muchas cosas nuevas e interesantes por delante, ¡estad atentos!

Fuente: habr.com

Añadir un comentario