Conceptos

Esta sección contiene explicaciones y ayuda para llevar a cabo las siguientes tareas. con IPF events:

  • Suscribiéndose a events

  • Uso de implementaciones del IPF event API

  • Definiendo su propio events para la publicación utilizando el event API

Event jerarquía

Todo events extender el nivel superior IPFSystemEvent<T>, que tiene los siguientes miembros: tienen los siguientes miembros (y getters asociados):

public abstract class IPFSystemEvent<T> {
    private static final EventVersion DEFAULT_VERSION = new EventVersion(1, 0, 0);

    private String name;
    private EventLevel level;
    private Instant createdAt;
    private EventVersion version;
    private EventType type;
    private ProcessingContext processingContext;
    private String source;
    private Map<String, String> metadata;
    private T payload;

El IPFSystemEvent está parametrizado, y el T tipo contiene la carga útil de la event subclaseando este.

Levantamiento y suscripción a events

Las dos subsecciones a continuación suponen que se ha creado una implementación de bus. La events API y la implementación se encuentra en dos módulos diferentes para permitir la conectividad de diferentes implementaciones de bus y procesador.

Para utilizar el DefaultEventBus implementación que se utiliza en los ejemplos a continuación, declare las siguientes dependencias en pom.xml:

<dependencies>
    <dependency>
        <groupId>com.iconsolutions.ipf.core.systemevents</groupId>
        <artifactId>ipf-system-events-api</artifactId>
        <version>${ipf-system-events.version}</version>
    </dependency>
    <dependency>
        <groupId>com.iconsolutions.ipf.core.systemevents</groupId>
        <artifactId>ipf-system-events-impl</artifactId>
        <version>${ipf-system-events.version}</version>
    </dependency>
</dependencies>

Los ejemplos a continuación suponen un autobús con el nombre eventBus ya ha sido creado de esta manera:

    private final EventBus eventBus = DefaultEventBus.getInstance();

Suscribiéndose a events

Tenga en cuenta que events publicado a un bus antes de que se reconozca una suscripción no será entregado a ese suscriptor.

Hay dos subscribe métodos como se describe en la interfaz. Aquí está el primero:

    <T extends IPFSystemEvent> boolean subscribe(Class<T> clazz, EventProcessor<? extends T> eventProcessor);

Esta llamada permite el suministro eventProcessor para suscribirse al bus, pero también ofrece una opción adicional Class para denotar un nivel específico en la jerarquía de clases en el que suscribirse. Si consideramos la siguiente jerarquía, por ejemplo:

|- IPFSystemEvent
|--> FunctionalSystemEvent
|---> TestSpecEvent

Podemos emitir un subscribe llame así:

        eventBus.subscribe(TestSpecEvent.class, eventProcessor);

Esto garantizará que esto eventProcessor solo recibirá events de tipo TestSpecEventy sus subclases, y ningún otro tipo de IPFSystem Event.

Utilice esta llamada cuando solo esté interesado en un conjunto específico de events.

Aquí está la segunda forma de suscribirse:

    default boolean subscribe(EventProcessor<IPFSystemEvent<?>> eventProcessor) {

Esto es una abreviatura para suscribirse de la siguiente manera:

        var subscribed = eventBus.subscribe(IPFSystemEvent.class, eventProcessor);

Utilice esta llamada si está potencialmente interesado en todas las posibles events que puede ser planteado por este sistema.

Ajustando el enfoque con el EventProcessor

Si examinamos la definición de la interfaz de la EventProcessor podemos ver el siguiente método de interfaz (con un valor predeterminado implementación), además de la (esperada)notify:

    /**
     * A predicate to filter which events to accept for processing
     *
     * @return whether this {@link EventProcessor} should process the given {@link IPFSystemEvent}.
     */
    default Predicate<T> predicate() {
        return a -> true;
    }

Este predicado permite al procesador inspeccionar cada mensaje entrante y decidir si está interesado en esto. mensaje particular.

La implementación predeterminada - a → true - permite todo events a través. Sobrescribir este método permite un control más detallado control sobre el events que se pasan a la notify método.

Vea a continuación diferentes ejemplos de uso de cómo se pueden utilizar los predicados para reducir el enfoque de un procesador.

Aumento events

Supongamos que queremos recaudar un event significando el inicio de un IPF flow. Para hacer eso podemos llamar al raise método como este:

        var testSpecEvent = new TestSpecEvent(PROCESSING_CONTEXT, "B");
        eventBus.raise(testSpecEvent);

Definiendo custom events

Para definir custom events, cree un event clase como una subclase de IPFSystemEvent<T>, donde el T el tipo es el tipo de carga útil que se publicará. Dependiendo del uso de la nueva event la carga útil no necesariamente necesita ser serializable, pero se recomienda que se haga el caso como events generalmente eventually necesita ser serializado sobre algún medio (cola de mensajes, archivo, RPC).

Documentando events

Hay una utilidad en el ipf-system-events-api módulo que recupera todas las subclases de IPFSystemEvent en el classpath y puede enumerar sus:

  • Nombre (el getSimpleName() de la clase)

  • Descripción (de la @EventDescription annotation)

  • Abstract/no abstract

  • Tipo de carga

Semántica de bus

Esta sección define el comportamiento que el event API en situaciones específicas:

Situación Comportamiento

El evento se genera antes de que un suscriptor se suscriba con éxito.

El evento no se entrega al suscriptor.

El suscriptor no recibe un event entrega

El suscriptor no es notificado nuevamente (entrega como máximo una vez)

Default event bus semántica

Todo events tiene una "fuente", definida de manera amplia como el nodo o la aplicación de la cual un system event fue publicado. La IPF predeterminada event el bus busca una Config (HOCON) valor llamado ipf.system-events.source, que a su vez es un marcador de posición para ipf.application.name.

Si ipf.system-events.source no se resuelve a un valor en tiempo de ejecución, entonces se utilizará el valor predeterminado, que será la salida de InetAddress.getLocalHost().getHostName(). Si eso genera una excepción, la fuente será UNKNOWN.

En la mayoría de los casos, usted no necesitará definir ipf.system-events.source, pero usted querrá asegurarse de que su aplicación defina ipf.application.name. Si es necesario para el system event la fuente para que sea diferente del nombre de la aplicación, deberá definir ipf.system-events.source explícitamente.

Tabla 1. Tabla que describe cómo el system event la fuente está determinada:
Valor de ipf.system-events.source Valor de ipf.application.name Nombre de host actual Fuente

El predeterminado:`${? ipf.application.name}`

nombre-de-aplicación

nombre-del-anfitrión

nombre-de-aplicación

fuente-definida-explícitamente

nombre-de-aplicación

nombre-del-anfitrión

fuente-explícitamente-definida

El valor predeterminado:`${? ipf.application.name}`

<does not exist>

nombre-del-anfitrión

nombre-del-anfitrión

El predeterminado:`${? ipf.application.name}`

<does not exist>

<unknown or failed to get>

UNKNOWN

Escribiendo un custom event implementación de bus

Si el existente en memoria DefaultEventBus definido en el -impl el paquete es insuficiente, es posible implementar su propio autobús.

Hay un kit de prueba de compatibilidad (TCK) en el -api proyecto que permite a futuros implementadores de autobuses probar la corrección de su implementación.

La prueba está disponible en un test-jar versión de la -api módulo. Cree una dependencia así:

<dependencies>
    <dependency>
        <groupId>com.iconsolutions.ipf.core.systemevents</groupId>
        <artifactId>ipf-system-events-api</artifactId>
        <version>${ipf-system-events.version}</version>
        <type>test-jar</type>
        <scope>test</scope>
    </dependency>
</dependencies>

El TCK es un resumen JUnit clase de prueba - EventBusTestSpec - con el siguiente método abstracto:

    abstract EventBus getEventBus();

Haga que su prueba extienda esta clase e implemente este método abstracto para permitir que la prueba se ejecute. También puede añadir su propio @Test métodos en esta clase (y otras) si desea probar otros escenarios no cubiertos por el TCK.

Recuerde tener su TCK la clase de implementación termina con la palabra `Test` para que sea recogido automáticamente por el
Maven Plugin Surefire