Red Hat OpenShift Mensajería basada en la nube con Quarkus y AMQ Online

¡Hola a todos! Aquí está, ¡nuestra publicación final de la serie Quarkus! (Por cierto, consulte nuestro seminario web “Este es Quarkus - Kubernetes marco nativa de Java . Vamos a mostrar cómo empezar desde cero o soluciones de transferencia ya hecho)



En un anterior post miramos las herramientas adecuadas con las que se puede cuantificar las mejoras realizadas como consecuencia de la modernización de Java aplicaciones.

A partir de la versión 0.17.0, Quarkus admite el uso del Protocolo avanzado de colas de mensajes ( AMQP ), que es un estándar abierto para transferir mensajes comerciales entre aplicaciones u organizaciones.

Red Hat AMQ Online es un servicio creado sobre la base del proyecto abierto EnMasse e implementa un mecanismo de mensajería basado en la plataforma Red Hat OpenShift . Obtenga más información sobre cómo funciona, consulte. Aquí (a EN) . Hoy mostramos cómo combinar AMQ Online y Quarkus para construir un sistema de mensajería moderno basado en OpenShift utilizando dos nuevas tecnologías relacionadas con el procesamiento de mensajes.

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

Para comenzar, crearemos la aplicación Quarkus, que será un sistema simple de procesamiento de pedidos utilizando mensajes reactivos. Esta aplicación incluirá un generador de pedidos que envía pedidos a la cola de mensajes con un intervalo fijo, así como un procesador de pedidos que procesará los mensajes de la cola y generará confirmaciones disponibles para ver en el navegador.

Después de crear la aplicación, le mostraremos cómo implementar la configuración del sistema de mensajería en ella y usar AMQ Online para inicializar los recursos que necesitamos en este sistema.

Aplicación Quarkus


Nuestra aplicación Quarkus se ejecuta en OpenShift y es una versión modificada de amqp-quickstart . Un ejemplo completo del lado del cliente se puede encontrar aquí .

Generador de pedidos


El generador cada 5 segundos simplemente envía monótonamente identificadores de orden creciente a la dirección de "órdenes".

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

Manejador de pedidos


El procesador de pedidos es aún más simple, simplemente devuelve el identificador de confirmación a la dirección "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


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

Personalización


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

Conectores


La configuración del conector se puede proporcionar en la etapa de compilación utilizando el archivo de propiedades de la aplicación:

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

Para no complicar esto, utilizaremos la cola de mensajes solo para la dirección de "pedidos". Y la dirección "confirmaciones" en nuestra aplicación utilizará la cola en la memoria.

Punto final AMQP


En la etapa de compilación, el nombre de host y el número de puerto para el punto final AMQP son desconocidos, por lo que deben implementarse. El punto final se puede establecer en el mapa de configuración, creado por AMQ Online, por lo que los definiremos a través de las 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 cuenta de servicio se puede usar 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 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);
    }
}

Montaje y despliegue de la aplicación.


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

Luego, siguiendo las instrucciones allí, debe descargar la 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

Después de estos comandos, la aplicación se implementará, pero no se iniciará hasta que configuremos los recursos de mensajería necesarios en AMQ Online.

Configuración de mensajería


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

Espacio de dirección


El objeto AddressSpace en AMQ Online es un grupo de direcciones que comparten puntos finales de conexión, así como políticas de autenticación y autorización. Al crear un espacio de direcciones, puede especificar cómo se proporcionarán los puntos finales del sistema 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

Direcciones


Las direcciones se utilizan para enviar y recibir mensajes. Cada dirección tiene un tipo que define su semántica, así como un plan que establece la cantidad de recursos reservados. 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 enviar y recibir mensajes a sus direcciones, solo las aplicaciones de confianza pueden hacerlo, debe crear un usuario en el sistema de mensajería. Para las aplicaciones que se ejecutan en un clúster, los clientes pueden autenticarse utilizando una cuenta de servicio OpenShift. La "cuenta de servicio" del usuario se puede definir, por ejemplo, de la siguiente manera:

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 personalizar la aplicación


Para que AMQ Online cree el mapa de configuración que utilizamos para implementar la información de punto final de AMQP, debe especificar el rol y el enlace de rol (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 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 solicitud


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

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

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

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

Debe verse en el navegador que los tickets se actualizan periódicamente a medida que AMQ Online envía y recibe los mensajes.

Para resumir


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

Esto concluye la serie Quarkus, pero hay muchas cosas nuevas e interesantes por delante, ¡quédate con nosotros!

All Articles