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.
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
@EventDescriptionannotation) -
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.
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}` |
|
nombre-del-anfitrión |
nombre-del-anfitrión |
El predeterminado:`${? ipf.application.name}` |
|
|
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 |