Conceptos
Esta sección contiene explicaciones y ayuda para llevar a cabo las siguientes tareas. con eventos de IPF:
-
Suscribiéndose a eventos
-
Uso de implementaciones del evento IPF API
-
Definiendo sus propios eventos para la publicación utilizando el evento API
Event jerarquía
Todos los eventos extienden 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 el tipo contiene la carga útil del evento que hereda de este.
Generación y suscripción a eventos
Las dos subsecciones a continuación suponen que se ha creado una implementación de bus. Los eventos 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 eventos
Tenga en cuenta que los eventos publicados en un bus antes de que se reconozca una suscripción no se entregarán 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 este eventProcessor solo reciba eventos 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 eventos.
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 todos los eventos posibles que pueden ser generados 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 que todos los eventos pasen. Sobrescribir este método permite un control más detallado
control sobre los eventos 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 eventos
Para definir custom eventos, cree una clase de evento como una subclase de IPFSystemEvent<T>, donde el T el tipo es el tipo de
carga útil que será publicada. Dependiendo del uso del nuevo evento, la carga útil no necesita ser necesariamente
serializable, pero se recomienda que se haga así, ya que los eventos generalmente necesitarán ser serializados eventualmente.
sobre algún medio (cola de mensajes, archivo, RPC).
Documentación de eventos
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 (desde el
@EventDescriptionannotation) -
Resumen/no resumen
-
Tipo de carga
Semántica de bus
Esta sección define el comportamiento del evento 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 la entrega de un evento. |
El suscriptor no es notificado nuevamente (entrega como máximo una vez) |
Semántica predeterminada del bus de eventos
Todos los eventos tienen una "fuente", definida de manera amplia como el nodo o la aplicación desde la cual se publicó un evento del sistema.
El bus de eventos IPF predeterminado busca una Configuración (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, no necesitará definir ipf.system-events.source, pero usted querrá asegurarse de que su aplicación defina ipf.application.name. Si es necesario que la fuente de eventos del sistema 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 valor predeterminado:`${? ipf.application.name}` |
nombre-de-la-aplicación |
nombre-del-anfitrión |
nombre-de-la-aplicación |
fuente-explícitamente-definida |
nombre-de-aplicación |
nombre-del-anfitrión |
fuente-explícitamente-definida |
El predeterminado:`${? ipf.application.name}` |
|
nombre-del-anfitrión |
nombre-del-anfitrión |
El predeterminado:`${? ipf.application.name}` |
|
|
UNKNOWN |
Escribiendo un custom implementación del bus de eventos
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 MavenPlugin Surefire |