Events System
The EDK provides an event system extension that builds on the IDK core events infrastructure, adding enterprise-specific event types, subsystems, and rich filtering capabilities.
Overview
The EDK events module (lib-events-event-api) defines:
- Event Types - EDK-specific event categories for authorization, persistence, and integration operations
- Subsystems - Logical groupings for filtering and routing events
- Transmitter Interfaces - Contracts for sending events to external systems
Modules
| Module | Description |
|---|---|
lib-events-event-api | EDK event types, subsystems, and transmitter interfaces |
lib-events-event-persistence-api | Event persistence interfaces and models |
lib-events-event-persistence-postgresql | PostgreSQL event storage |
lib-events-event-persistence-mysql | MySQL event storage |
lib-events-event-persistence-sqlite | SQLite event storage |
lib-events-event-spring | Spring Boot auto-configuration for events |
Event Categories
Authorization Events
Events related to policy evaluation and authorization decisions:
| Event | Description |
|---|---|
AuthorizationRequested | Policy evaluation initiated |
AuthorizationGranted | Access permitted by policy |
AuthorizationDenied | Access denied by policy |
CircuitBreakerOpened | PDP circuit breaker tripped |
CircuitBreakerClosed | PDP circuit breaker recovered |
Persistence Events
Events related to database operations:
| Event | Description |
|---|---|
EntityCreated | New entity persisted |
EntityUpdated | Existing entity modified |
EntityDeleted | Entity soft-deleted |
ConnectionPoolExhausted | Database pool limit reached |
TenantDatabaseRouted | Request routed to tenant database |
Integration Events
Events related to external service integration:
| Event | Description |
|---|---|
ExternalServiceCalled | Outbound API request made |
ExternalServiceFailed | Outbound API request failed |
WebhookDispatched | Webhook notification sent |
Subsystems
Events are categorized into subsystems for filtering:
| Subsystem | Description |
|---|---|
AUTHZ | Authorization and policy events |
PERSISTENCE | Database and storage events |
INTEGRATION | External service events |
AUDIT | Audit trail events |
Usage
Subscribing to Events
import com.sphereon.events.api.EventSubscriber
import com.sphereon.events.api.AuthorizationEvent
class AuthorizationAuditSubscriber : EventSubscriber<AuthorizationEvent> {
override suspend fun onEvent(event: AuthorizationEvent) {
when (event) {
is AuthorizationEvent.Denied -> {
logger.warn("Access denied: ${event.principal} -> ${event.resource}")
}
is AuthorizationEvent.Granted -> {
logger.debug("Access granted: ${event.principal} -> ${event.resource}")
}
}
}
}
Transmitting Events
The transmitter interface allows sending events to external systems:
import com.sphereon.events.api.EventTransmitter
import com.sphereon.events.api.Event
class WebhookEventTransmitter(
private val httpClient: HttpClient,
private val webhookUrl: String
) : EventTransmitter {
override suspend fun transmit(event: Event) {
httpClient.post(webhookUrl) {
contentType(ContentType.Application.Json)
setBody(event.toJson())
}
}
}
Integration with IDK Events
The EDK events module extends the IDK core events system:
import com.sphereon.core.events.EventHub
import com.sphereon.edk.events.EdkEventTypes
// Register EDK event types with the IDK event hub
val eventHub: EventHub = sessionComponent.eventHub
eventHub.subscribe(EdkEventTypes.AUTHORIZATION) { event ->
// Handle authorization events
}
eventHub.subscribe(EdkEventTypes.PERSISTENCE) { event ->
// Handle persistence events
}
Configuration
Configure event handling in your application:
sphereon:
events:
enabled: true
subsystems:
authz:
enabled: true
log-level: DEBUG
persistence:
enabled: true
log-level: INFO
integration:
enabled: false
transmitters:
webhook:
enabled: true
url: https://events.example.com/webhook
batch-size: 100
flush-interval-ms: 5000
Event Persistence
The EDK provides database-backed event storage for audit trails, compliance, and event replay.
Configuration
dependencies {
// Choose your database backend
implementation("com.sphereon.edk:lib-events-event-persistence-postgresql:0.13.0")
// or
implementation("com.sphereon.edk:lib-events-event-persistence-mysql:0.13.0")
// or
implementation("com.sphereon.edk:lib-events-event-persistence-sqlite:0.13.0")
}
Using Event Persistence
import com.sphereon.events.persistence.api.EventRepository
import com.sphereon.events.persistence.api.EventQuery
class AuditService(
private val eventRepository: EventRepository
) {
// Store an event
suspend fun recordEvent(event: Event) {
eventRepository.save(event)
}
// Query events with filters
suspend fun getAuthorizationEvents(
tenantId: String,
startTime: Instant,
endTime: Instant
): List<Event> {
return eventRepository.query(
EventQuery(
subsystem = "AUTHZ",
tenantId = tenantId,
timeRange = startTime..endTime
)
)
}
// Paginated queries for large result sets
suspend fun getRecentEvents(page: Int, pageSize: Int): Page<Event> {
return eventRepository.queryPaged(
EventQuery(
orderBy = EventQuery.OrderBy.TIMESTAMP_DESC
),
page = page,
pageSize = pageSize
)
}
}
Spring Boot Integration
With the Spring module, event persistence is auto-configured:
dependencies {
implementation("com.sphereon.edk:lib-events-event-spring:0.13.0")
implementation("com.sphereon.edk:lib-events-event-persistence-postgresql:0.13.0")
}
# application.yml
sphereon:
events:
persistence:
enabled: true
table-name: sphereon_events
retention-days: 90 # Auto-cleanup after 90 days
import com.sphereon.events.persistence.api.EventRepository
import org.springframework.stereotype.Service
@Service
class AuditService(
private val eventRepository: EventRepository // Auto-injected
) {
suspend fun getAuditTrail(entityId: String): List<Event> {
return eventRepository.queryByEntityId(entityId)
}
}
Retention Policies
Configure automatic cleanup of old events:
sphereon:
events:
persistence:
retention:
enabled: true
days: 90
cleanup-schedule: "0 0 2 * * *" # Daily at 2 AM
Best Practices
Use subsystem filtering. Subscribe only to the event subsystems you need to minimize processing overhead.
Handle events asynchronously. Event handlers should not block the main execution flow. Use coroutines for any I/O operations.
Implement idempotent handlers. Events may be delivered more than once in distributed scenarios.
Log authorization denials. Always log denied authorization attempts for security auditing.
Persist critical events. Use event persistence for audit trails and compliance requirements. Configure appropriate retention policies based on regulatory needs.