### Complete Audit Log Persistence Example
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/AuditRecord.md
An example of a Kafka listener service that consumes CreateAuditRecordCommand, converts it to an AuditRecord, and persists it to a repository, handling different trigger types and audited data.
```java
@Service
public class AuditLogPersistence {
@Autowired
private AuditRepository repository;
@KafkaListener(topics = "create-audit-record-command")
public void persistAuditRecord(CreateAuditRecordCommand command) {
// Convert Avro to domain model
AuditRecord record = AuditRecordFactory.createAuditRecord(command);
// Extract basic information
String serviceName = record.serviceName();
String systemName = record.systemName();
Instant timestamp = record.timestamp();
// Determine trigger type
if (record.trigger().type() == AuditTrigger.AuditTriggerType.USER) {
AuditTriggerUser user = (AuditTriggerUser) record.trigger();
persistUserAction(serviceName, systemName, timestamp, user, record.auditEvent());
} else {
AuditTriggerSystemComponent system = (AuditTriggerSystemComponent) record.trigger();
persistSystemAction(serviceName, systemName, timestamp, system, record.auditEvent());
}
// Persist audited data if present
if (record.auditedData() != null) {
persistAuditedObject(record.auditedData());
}
}
private void persistUserAction(String serviceName, String systemName, Instant timestamp,
AuditTriggerUser user, AuditEvent event) {
AuditLogEntry entry = new AuditLogEntry();
entry.setServiceName(serviceName);
entry.setSystemName(systemName);
entry.setTimestamp(timestamp);
entry.setEventType(event.eventType());
entry.setUserId(user.id());
entry.setIdentityProvider(user.identityProvider());
if (event.context() != null) {
entry.setUseCase(event.context().useCase());
entry.setProcessId(event.context().processId());
}
repository.save(entry);
}
private void persistSystemAction(String serviceName, String systemName, Instant timestamp,
AuditTriggerSystemComponent system, AuditEvent event) {
AuditLogEntry entry = new AuditLogEntry();
entry.setServiceName(serviceName);
entry.setSystemName(systemName);
entry.setTimestamp(timestamp);
entry.setEventType(event.eventType());
entry.setTriggerDepartment(system.department());
entry.setTriggerSystem(system.system());
entry.setTriggerComponent(system.component());
if (event.context() != null) {
entry.setUseCase(event.context().useCase());
entry.setProcessId(event.context().processId());
}
repository.save(entry);
}
}
```
--------------------------------
### Fluent Builder Pattern Example
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/INDEX.md
Demonstrates the method-chaining DSL provided by the fluent builder pattern for creating audit commands.
```java
builder
.setEventType(AuditEventType.UPDATE)
.setContext("use-case")
.setTriggerUser("user-123", "issuer")
.build()
```
--------------------------------
### Factory Method Example
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/INDEX.md
Illustrates using factory methods to simplify the creation of audit record builders, avoiding boilerplate code.
```java
// Instead of this:
CreateAuditRecordCommandBuilder builder =
CreateAuditRecordCommandBuilder.createCommandBuilder(...);
builder.setTriggerUser(userFromSecurityContext.getId(),
userFromSecurityContext.getIssuer());
// Do this:
CreateAuditRecordCommandBuilder builder =
factory.createWithUserTrigger(Instant.now());
```
--------------------------------
### AuditTriggerSystemComponent Example
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/AuditTrigger.md
Demonstrates creating and accessing properties of an AuditTriggerSystemComponent.
```java
AuditTriggerSystemComponent system = new AuditTriggerSystemComponent(
"IT_OPS", "batch-system", "scheduler");
system.type(); // Returns AuditTriggerType.SYSTEM_COMPONENT
system.department(); // "IT_OPS"
system.system(); // "batch-system"
system.component(); // "scheduler"
```
--------------------------------
### AuditTriggerUser Example
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/AuditTrigger.md
Demonstrates creating and accessing properties of an AuditTriggerUser.
```java
AuditTriggerUser user = new AuditTriggerUser("user-456", "https://auth.example.com");
user.type(); // Returns AuditTriggerType.USER
user.id(); // "user-456"
user.identityProvider(); // "https://auth.example.com"
```
--------------------------------
### Transactional Audit Record Creation
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandTransactionOutboxSender.md
This example demonstrates creating an order and auditing the creation event within the same transaction using CreateAuditRecordCommandTransactionOutboxSender.
```java
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private CreateAuditRecordCommandTransactionOutboxSender auditSender;
@Transactional
public Order createOrder(OrderRequest request) {
// Create order entity
Order order = new Order();
order.setCustomerId(request.getCustomerId());
order.setAmount(request.getAmount());
order.setStatus(OrderStatus.PENDING);
// Save to database (within transaction)
orderRepository.save(order);
// Audit the creation in the SAME transaction
auditSender.auditUserTriggeredEvent(Instant.now(), builder ->
builder
.setEventType(AuditEventType.CREATE)
.setContext("order-creation")
.setAuditObject("Order", order.getId())
.addAuditObjectDataValue("customerId", order.getCustomerId())
.addAuditObjectDataValue("amount", order.getAmount().toString())
.addAuditObjectDataValue("status", order.getStatus().toString())
);
return order;
}
@Transactional
public void fulfillOrder(String orderId) {
Order order = orderRepository.findById(orderId).orElseThrow();
// Update order status
order.setStatus(OrderStatus.FULFILLED);
order.setFulfilledAt(Instant.now());
orderRepository.save(order);
// Audit the status change
auditSender.auditUserTriggeredEvent(Instant.now(), builder ->
builder
.setEventType(AuditEventType.UPDATE)
.setContext("order-fulfillment")
.setAuditObject("Order", orderId)
.addAuditObjectDataValue(AuditObjectDataRole.BEFORE, "status", "PENDING")
.addAuditObjectDataValue(AuditObjectDataRole.AFTER, "status", "FULFILLED")
);
}
}
```
--------------------------------
### Complete Usage Example for CreateAuditRecordCommandBuilder
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilder.md
Demonstrates the complete usage of the CreateAuditRecordCommandBuilder, from initialization to configuring event details, triggers, and audited objects before building the final command.
```java
// Create a builder
CreateAuditRecordCommandBuilder builder = CreateAuditRecordCommandBuilder
.createCommandBuilder("user-service", "user-system", Instant.now(), "proc-abc123");
// Configure the audit event
CreateAuditRecordCommand command = builder
.setEventType(AuditEventType.MODIFY)
.setContext("password-change", "proc-abc123")
.addEventData("reason", "security_incident")
.addEventData("verified_by", "admin")
// Set trigger
.setTriggerUser("user-789", "https://auth.example.com")
// Set audited object
.setAuditObject("UserAccount", "acc-456", "20240115T100000Z")
.addAuditObjectDataValue(AuditObjectDataRole.BEFORE, "password_hash", "***old***")
.addAuditObjectDataValue(AuditObjectDataRole.AFTER, "password_hash", "***new***")
// Build the command
.build();
```
--------------------------------
### Complete Microservice Producer Dependencies
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/modules.md
Example dependency configuration for a microservice acting as an audit command producer using the transactional outbox pattern.
```xml
ch.admin.bit.jeap
jeap-spring-boot-audit-starter-transactional-outbox
```
--------------------------------
### Domain Model Conversion Example
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/INDEX.md
Demonstrates converting Avro messages to plain Java records for simplified processing using AuditRecordFactory.
```java
CreateAuditRecordCommand avro = ...;
AuditRecord domain = AuditRecordFactory.createAuditRecord(avro);
// Now work with typed records and enums instead of Avro generics
```
--------------------------------
### Multi-Topic Auditing Service Example
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/SpringAutoConfiguration.md
Demonstrates auditing events to multiple topics using qualified senders. This service injects specific `CreateAuditRecordCommandTransactionOutboxSender` instances for primary and secondary audit streams.
```java
@Service
public class AuditingService {
@Autowired
@Qualifier("audit-primary")
private CreateAuditRecordCommandTransactionOutboxSender primarySender;
@Autowired
@Qualifier("audit-secondary")
private CreateAuditRecordCommandTransactionOutboxSender secondarySender;
@Transactional
public void auditEvent() {
primarySender.auditUserTriggeredEvent(Instant.now(), builder ->
builder.setEventType(AuditEventType.CREATE)
);
secondarySender.auditUserTriggeredEvent(Instant.now(), builder ->
builder.setEventType(AuditEventType.CREATE)
);
}
}
```
--------------------------------
### Audit with Custom Service Names
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilderFactory.md
This example shows how to specify custom service names when creating an audit record, useful for distinguishing between different client applications or services triggering the audit.
```java
import com.example.audit.CreateAuditRecordCommandBuilderFactory;
import com.example.audit.CreateAuditRecordCommand;
import com.example.audit.AuditEventType;
import java.time.Instant;
// Assuming factory is an instance of CreateAuditRecordCommandBuilderFactory
// CreateAuditRecordCommandBuilderFactory factory = ...;
CreateAuditRecordCommand command = factory
.createWithUserTrigger("admin-portal", "admin-system", Instant.now())
.setEventType(AuditEventType.DELETE)
.setContext("user-deprovisioning")
.setAuditObject("UserAccount", "user-456")
.build();
```
--------------------------------
### Analyzing AuditEvent in Java
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/AuditEvent.md
Provides an example of how to analyze an AuditEvent, accessing its type, context, and data elements within a Java service.
```java
@Service
public class AuditAnalyzer {
public void analyzeEvent(AuditEvent event) {
// Get event type
AuditEventType type = event.eventType();
System.out.println("Event type: " + type);
// Get context if present
if (event.context() != null) {
System.out.println("Use case: " + event.context().useCase());
System.out.println("Process: " + event.context().processId());
}
// Process event data
for (AuditEventDataElement element : event.eventDataElements()) {
System.out.println(element.key() + " = " + element.value());
}
}
}
```
--------------------------------
### Transactional Outbox Pattern Example
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/INDEX.md
Shows how the transactional outbox pattern ensures audit commands are sent within the same database transaction as business data.
```java
@Transactional
public void operation() {
updateDatabase(); // In transaction
sender.auditEvent(command); // Also in transaction (written to outbox table)
// Both commit together or both roll back
}
```
--------------------------------
### Audit Aggregation Service Consumer Dependencies
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/modules.md
Example dependency configuration for an audit aggregation service that consumes audit commands, including Kafka integration.
```xml
ch.admin.bit.jeap
jeap-audit-command-consumer
ch.admin.bit.jeap
jeap-messaging-kafka
```
--------------------------------
### Consume and Process Audit Commands with Kafka Listener
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/modules.md
Example of a Kafka listener that consumes 'create-audit-record-command' messages and converts them into an AuditRecord domain model using AuditRecordFactory.
```java
@KafkaListener(topics = "create-audit-record-command")
public void handleAuditCommand(CreateAuditRecordCommand command) {
AuditRecord record = AuditRecordFactory.createAuditRecord(command);
// Process record...
}
```
--------------------------------
### Complete jEAP Audit Configuration
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/configuration.md
This YAML configuration shows a comprehensive setup for jEAP Audit, including enabling it, defining Kafka topics for transactional outbox, and configuring Spring Boot data sources and JPA.
```yaml
jeap:
audit:
enabled: true
transactional-outbox:
topics:
- primary-audit
- secondary-audit
messaging:
kafka:
service-name: user-service
system-name: user-management
contracts:
producers:
- message-type-name: create-audit-record-command
avro-class: ch.admin.bit.jeap.audit.record.create.CreateAuditRecordCommand
spring:
datasource:
url: jdbc:postgresql://localhost:5432/users
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: validate
show-sql: false
```
--------------------------------
### Run integration tests for the transactional outbox starter
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/AGENTS.md
This command specifically runs the tests for the transactional outbox starter module. It leverages embedded Kafka and H2 database for testing.
```bash
./mvnw -pl jeap-spring-boot-audit-starter-transactional-outbox test
```
--------------------------------
### Build a Minimal CreateAuditRecordCommand
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/docs/getting-started.md
Constructs a CreateAuditRecordCommand using the fluent builder API. Requires service name, system name, event type, and trigger.
```java
CreateAuditRecordCommand command = CreateAuditRecordCommandBuilder
.createCommandBuilder(serviceName, systemName, Instant.now())
.setEventType(AuditEventType.CREATED)
.setContext("my-usecase", processId)
.addEventData("key", "value")
.setTriggerUser(userId, identityProvider)
.build();
```
--------------------------------
### CreateAuditRecordCommandTransactionOutboxSender Constructor
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/SpringAutoConfiguration.md
Illustrates the arguments required to construct a sender bean for the transactional outbox. These include the transactional outbox mechanism, a command builder factory, and the topic name.
```java
new CreateAuditRecordCommandTransactionOutboxSender(
TransactionalOutbox transactionalOutbox, // From jeap-messaging-outbox
CreateAuditRecordCommandBuilderFactory builderFactory,
String topic // From configuration
)
```
--------------------------------
### Perform a full Maven build including tests
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/AGENTS.md
Executes all Maven goals, including compilation, testing, and packaging, for the entire project.
```bash
./mvnw verify
```
--------------------------------
### Invalid Configuration: Neither topic nor topics specified
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/configuration.md
This configuration is invalid because neither `topic` nor `topics` are specified. At least one must be present.
```yaml
jeap:
audit:
transactional-outbox: {}
```
--------------------------------
### Invalid Configuration: Empty topics list
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/configuration.md
This configuration is invalid because the `topics` list is empty. Ensure the list contains at least one topic.
```yaml
jeap:
audit:
transactional-outbox:
topics: []
```
--------------------------------
### Build a specific module and its dependencies with Maven
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/AGENTS.md
Use this command to build a single module and its direct dependencies. Replace `` with the target module's name.
```bash
./mvnw -pl -am install
```
--------------------------------
### Create Audit Record Command
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/docs/building-the-command.md
Use the builder directly to construct an audit command. Pass the auditing service name, system name, and a timestamp. An optional process ID can also be provided.
```java
CreateAuditRecordCommand command = CreateAuditRecordCommandBuilder
.createCommandBuilder(serviceName, systemName, Instant.now())
.setEventType(AuditEventType.CREATED)
.addEventData("key1", "value1")
.addEventData("key2", "value2")
.setTriggerUser(userId, identityProvider)
.build();
```
--------------------------------
### Add jEAP Security Starter Dependency
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/errors.md
Include the jEAP Security starter dependency in your project to enable user-trigger functionality.
```xml
ch.admin.bit.jeap
jeap-spring-boot-security-starter
```
--------------------------------
### Audit Pre-built Event Command
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandTransactionOutboxSender.md
Sends a fully constructed `CreateAuditRecordCommand` to the configured topic. Ideal for scenarios where the audit command is built elsewhere.
```java
@Transactional
public void auditEvent(CreateAuditRecordCommand command)
```
```java
CreateAuditRecordCommand command = factory
.createWithUserTrigger(Instant.now())
.setEventType(AuditEventType.DELETE)
.setContext("data-purge")
.setAuditObject("SensitiveData", dataId)
.build();
sender.auditEvent(command);
```
--------------------------------
### Create Audit Record Command Builder Factory Methods
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilder.md
Provides static factory methods to create instances of the CreateAuditRecordCommandBuilder, initializing it with essential audit event details.
```APIDOC
## createCommandBuilder (static)
### Description
Creates a new command builder instance.
### Method Signature
```java
public static CreateAuditRecordCommandBuilder createCommandBuilder(String serviceName, String systemName, Instant timestamp)
public static CreateAuditRecordCommandBuilder createCommandBuilder(String serviceName, String systemName, Instant timestamp, String processId)
```
### Parameters
#### createCommandBuilder(String serviceName, String systemName, Instant timestamp)
- **serviceName** (String) - Required - Name of the auditing microservice
- **systemName** (String) - Required - Name of the system the service belongs to
- **timestamp** (Instant) - Required - Timestamp when the audit event occurred
#### createCommandBuilder(String serviceName, String systemName, Instant timestamp, String processId)
- **serviceName** (String) - Required - Name of the auditing microservice
- **systemName** (String) - Required - Name of the system the service belongs to
- **timestamp** (Instant) - Required - Timestamp when the audit event occurred
- **processId** (String) - Optional - Correlation identifier for related operations
### Returns
`CreateAuditRecordCommandBuilder` - A new builder instance configured with the provided parameters.
### Example
```java
CreateAuditRecordCommandBuilder builder = CreateAuditRecordCommandBuilder
.createCommandBuilder("my-service", "my-system", Instant.now());
```
```
--------------------------------
### Invalid Configuration: Both topic and topics specified
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/configuration.md
This configuration is invalid because both `topic` and `topics` are specified. Ensure only one is used.
```yaml
jeap:
audit:
transactional-outbox:
topic: primary
topics:
- secondary
```
--------------------------------
### auditEvent
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandTransactionOutboxSender.md
Sends a pre-built `CreateAuditRecordCommand` to the configured topic. Use this when you have already constructed the command elsewhere.
```APIDOC
## auditEvent
### Description
Sends a pre-built `CreateAuditRecordCommand` to the configured topic. Use this when you have already constructed the command elsewhere.
### Method Signature
```java
public void auditEvent(CreateAuditRecordCommand command)
```
### Parameters
#### Path Parameters
- **command** (CreateAuditRecordCommand) - Required - The fully constructed audit command
### Request Example
```java
CreateAuditRecordCommand command = factory
.createWithUserTrigger(Instant.now())
.setEventType(AuditEventType.DELETE)
.setContext("data-purge")
.setAuditObject("SensitiveData", dataId)
.build();
sender.auditEvent(command);
```
```
--------------------------------
### CreateAuditRecordCommandTransactionOutboxSender Constructor
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandTransactionOutboxSender.md
Instantiated by Spring auto-configuration. One instance is created per configured topic.
```java
public CreateAuditRecordCommandTransactionOutboxSender(
TransactionalOutbox transactionalOutbox,
CreateAuditRecordCommandBuilderFactory builderFactory,
String topic)
```
--------------------------------
### Create Audit Record Command Builder Instance
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilder.md
Use this factory method to create a new builder instance for constructing audit record commands. It requires service name, system name, and a timestamp.
```java
CreateAuditRecordCommandBuilder builder = CreateAuditRecordCommandBuilder
.createCommandBuilder("my-service", "my-system", Instant.now());
```
--------------------------------
### Invalid Configuration: Blank topic names
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/configuration.md
This configuration is invalid because the `topics` list contains blank or whitespace-only topic names. Topic names must be non-empty.
```yaml
jeap:
audit:
transactional-outbox:
topics:
- ""
- " "
```
--------------------------------
### createWithSystemTriggerFromMessage (with kafka properties)
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilderFactory.md
Creates a builder with a system trigger extracted from a message publisher. Service and system names are taken from Kafka properties.
```APIDOC
## createWithSystemTriggerFromMessage (with kafka properties)
### Description
Creates a builder with a system trigger extracted from a message publisher. Service and system names are taken from Kafka properties.
### Method Signature
```java
public CreateAuditRecordCommandBuilder createWithSystemTriggerFromMessage(String triggeringServiceDepartment, Instant timestamp, Message message)
```
### Parameters
#### Path Parameters
- None
#### Query Parameters
- None
#### Request Body
- None
### Parameters Table
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| triggeringServiceDepartment | String | Yes | Department of the service that triggered the event |
| timestamp | Instant | Yes | Timestamp of the audit event |
| message | Message | Yes | The triggering message (system/component extracted from its publisher) |
### Returns
- `CreateAuditRecordCommandBuilder` — A builder with system trigger and idempotence ID pre-configured from the message.
### Example
```java
@KafkaListener(topics = "business-events")
public void handleBusinessEvent(Message message) {
CreateAuditRecordCommandBuilder builder = factory
.createWithSystemTriggerFromMessage("IT_OPS", Instant.now(), message);
// ... configure builder and build
}
```
```
--------------------------------
### Configure Multiple Audit Topics
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/SpringAutoConfiguration.md
Configure multiple topics for transactional outbox. This creates qualified sender beans.
```yaml
jeap:
audit:
transactional-outbox:
topics:
- audit-primary
- audit-secondary
```
--------------------------------
### Consume and Process Audit Command
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/INDEX.md
This snippet demonstrates how to consume `CreateAuditRecordCommand` from a Kafka topic, convert it into an `AuditRecord` domain model, and process it based on the trigger type and audited data.
```java
AuditRecord record = AuditRecordFactory.createAuditRecord(command);
if (record.trigger().type() == AuditTrigger.AuditTriggerType.USER) {
AuditTriggerUser user = (AuditTriggerUser) record.trigger();
persistUserAction(user, record.auditEvent());
}
if (record.auditedData() != null) {
for (AuditObjectData data : record.auditedData().objectDataList()) {
persistData(data);
}
}
```
--------------------------------
### Build System-Triggered Audit Command from Message
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/INDEX.md
This pattern is for auditing system-initiated events, often triggered by messages from external sources like Kafka. It requires specifying the service name, timestamp, and the message itself.
```java
CreateAuditRecordCommand cmd = factory
.createWithSystemTriggerFromMessage(
"IT_OPS", Instant.now(), message)
.setEventType(AuditEventType.EXECUTE)
.setContext("scheduled-job")
.build();
```
--------------------------------
### Constructing Audit Commands with Builder Pattern
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/README.md
Use the fluent builder to construct audit commands. Set the event type, context, and trigger user before building the command.
```java
builder
.setEventType(AuditEventType.CREATE)
.setContext("use-case")
.setTriggerUser("user-id", "issuer")
.build()
```
--------------------------------
### createWithUserTrigger (with service/system names)
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilderFactory.md
Creates a builder with a user trigger from the security context, allowing explicit specification of service and system names. Throws AuditException if jEAP Security is not on the classpath.
```APIDOC
## createWithUserTrigger (with service/system names)
### Description
Creates a builder with a user trigger from the security context, but allows explicit specification of service and system names.
### Method Signature
```java
public CreateAuditRecordCommandBuilder createWithUserTrigger(String serviceName, String systemName, Instant timestamp)
```
### Parameters
#### Path Parameters
- None
#### Query Parameters
- None
#### Request Body
- None
### Parameters Table
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| serviceName | String | Yes | Name of the auditing microservice |
| systemName | String | Yes | Name of the auditing system |
| timestamp | Instant | Yes | Timestamp of the audit event |
### Throws
- `AuditException` — If jEAP Security is not on the classpath
### Returns
- `CreateAuditRecordCommandBuilder` — A configured builder with user trigger.
### Example
```java
CreateAuditRecordCommandBuilder builder = factory
.createWithUserTrigger("notification-service", "notification-system", Instant.now());
```
```
--------------------------------
### AuditTrigger Pattern Matching
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/AuditTrigger.md
Shows how to use pattern matching to differentiate between user and system component triggers.
```java
AuditTrigger trigger = record.trigger();
if (trigger.type() == AuditTrigger.AuditTriggerType.USER) {
AuditTriggerUser user = (AuditTriggerUser) trigger;
logUserAction(user.id(), user.identityProvider());
} else if (trigger.type() == AuditTrigger.AuditTriggerType.SYSTEM_COMPONENT) {
AuditTriggerSystemComponent system = (AuditTriggerSystemComponent) trigger;
logSystemAction(system.department(), system.system(), system.component());
}
```
--------------------------------
### Configure Kafka Service and System Names
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/configuration.md
Set the service and system names for publisher information in audit commands. These are used as defaults in builder factory convenience methods.
```yaml
jeap:
messaging:
kafka:
service-name: my-service
system-name: my-system
```
--------------------------------
### createWithSystemTriggerFromMessage (explicit names)
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilderFactory.md
Creates a builder with a system trigger from a message, with explicit specification of the auditing service and system names.
```APIDOC
## createWithSystemTriggerFromMessage (explicit names)
### Description
Creates a builder with a system trigger from a message, with explicit specification of the auditing service and system names.
### Method Signature
```java
public CreateAuditRecordCommandBuilder createWithSystemTriggerFromMessage(String serviceName, String systemName, String triggeringServiceDepartment, Instant timestamp, Message message)
```
### Parameters
#### Path Parameters
- None
#### Query Parameters
- None
#### Request Body
- None
### Parameters Table
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| serviceName | String | Yes | Name of the auditing microservice |
| systemName | String | Yes | Name of the auditing system |
| triggeringServiceDepartment | String | Yes | Department of the triggering service |
| timestamp | Instant | Yes | Timestamp of the audit event |
| message | Message | Yes | The triggering message |
### Returns
- `CreateAuditRecordCommandBuilder` — A fully pre-configured builder.
### Example
```java
CreateAuditRecordCommandBuilder builder = factory
.createWithSystemTriggerFromMessage(
"workflow-service",
"workflow-system",
"PROCESSING",
Instant.now(),
message);
```
```
--------------------------------
### Multi-Topic Configuration for Audit Outbox
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/configuration.md
Configure multiple topics for audit records. Each topic will have a dedicated sender bean qualified by its topic name.
```yaml
jeap:
audit:
transactional-outbox:
topics:
- mysystem-audit
- mysystem-audit-secondary
- mysystem-audit-tertiary
```
--------------------------------
### Configure Multiple Topics for Transactional Outbox
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/docs/configuration.md
Use this configuration to send audit commands to a list of Kafka topics. Ensure that either 'topic' or 'topics' is configured, but not both. An audit record sender bean will be registered for each topic.
```yaml
jeap:
audit:
transactional-outbox:
topics:
- mysystem-audit
- mysystem-audit-secondary
```
--------------------------------
### CreateAuditRecordCommandBuilderFactory
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/exported-symbols.md
Factory for creating instances of `CreateAuditRecordCommandBuilder`. Provides methods to create builders with different trigger user configurations.
```APIDOC
## CreateAuditRecordCommandBuilderFactory
### Description
Factory for creating instances of `CreateAuditRecordCommandBuilder`. Provides methods to create builders with different trigger user configurations.
### Constructor
- `CreateAuditRecordCommandBuilderFactory(Optional, KafkaProperties)`
### Instance Methods
- `createWithUserTrigger(Instant): CreateAuditRecordCommandBuilder`
- `createWithUserTrigger(String, String, Instant): CreateAuditRecordCommandBuilder`
- `createWithSystemTriggerFromMessage(String, Instant, Message): CreateAuditRecordCommandBuilder`
- `createWithSystemTriggerFromMessage(String, String, String, Instant, Message): CreateAuditRecordCommandBuilder`
```
--------------------------------
### createWithUserTrigger (no arguments)
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilderFactory.md
Creates a builder with a user trigger extracted from the current security context. Service and system names are taken from Kafka properties. Throws AuditException if jEAP Security is not on the classpath.
```APIDOC
## createWithUserTrigger (no arguments)
### Description
Creates a builder with a user trigger extracted from the current security context. The service and system names are taken from Kafka properties.
### Method Signature
```java
public CreateAuditRecordCommandBuilder createWithUserTrigger(Instant timestamp)
```
### Parameters
#### Path Parameters
- None
#### Query Parameters
- None
#### Request Body
- None
### Parameters Table
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| timestamp | Instant | Yes | Timestamp of the audit event |
### Throws
- `AuditException` — If jEAP Security is not on the classpath (thrown with message "You cannot use user convenience method without jEAP security")
### Returns
- `CreateAuditRecordCommandBuilder` — A builder with user trigger pre-configured from the security token.
### Example
```java
@Autowired
private CreateAuditRecordCommandBuilderFactory factory;
// In a request handler with authenticated user
CreateAuditRecordCommandBuilder builder = factory.createWithUserTrigger(Instant.now());
```
```
--------------------------------
### Create Audit Record Builder with User Trigger (No Args)
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilderFactory.md
Creates a builder with a user trigger from the current security context. Service and system names are derived from Kafka properties. Requires jEAP Security on the classpath.
```java
public CreateAuditRecordCommandBuilder createWithUserTrigger(Instant timestamp)
```
```java
@Autowired
private CreateAuditRecordCommandBuilderFactory factory;
// In a request handler with authenticated user
CreateAuditRecordCommandBuilder builder = factory.createWithUserTrigger(Instant.now());
```
--------------------------------
### Create Audit Record Builder with System Trigger (From Message, Kafka Props)
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilderFactory.md
Creates a builder with a system trigger from a message publisher. Service and system names are taken from Kafka properties. The triggering service department and message are required.
```java
public CreateAuditRecordCommandBuilder createWithSystemTriggerFromMessage(
String triggeringServiceDepartment,
Instant timestamp,
Message message)
```
```java
@KafkaListener(topics = "business-events")
public void handleBusinessEvent(Message message) {
CreateAuditRecordCommandBuilder builder = factory
.createWithSystemTriggerFromMessage("IT_OPS", Instant.now(), message);
// ... configure builder and build
}
```
--------------------------------
### Invalid Configuration: Duplicate topics
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/configuration.md
This configuration is invalid because the `topics` list contains duplicate entries. Each topic name must be unique.
```yaml
jeap:
audit:
transactional-outbox:
topics:
- audit
- audit
```
--------------------------------
### Constructor
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilderFactory.md
The constructor for CreateAuditRecordCommandBuilderFactory, which is instantiated by Spring auto-configuration. It accepts an optional user trigger provider and Kafka properties.
```APIDOC
## Constructor
### Description
Instantiated by Spring auto-configuration. The `triggerUserProvider` is optional and only present if jEAP Security is on the classpath.
### Parameters
#### Constructor Parameters
- **triggerUserProvider** (Optional) - Required - User trigger provider (present only if jEAP Security is available)
- **kafkaProperties** (KafkaProperties) - Required - Kafka configuration for service and system names
```
--------------------------------
### Configure Transactional Outbox Database
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/configuration.md
Configure the transactional outbox's database tables. The outbox requires an 'outbox_event' table for storing messages before delivery.
```yaml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: myuser
password: mypassword
jpa:
hibernate:
ddl-auto: validate
```
--------------------------------
### Build User-Triggered Audit Command
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/INDEX.md
Use this pattern to audit user actions. It automatically extracts user information and allows setting event details, context, and audit objects.
```java
CreateAuditRecordCommand cmd = factory
.createWithUserTrigger(Instant.now())
.setEventType(AuditEventType.UPDATE)
.setContext("email-change")
.setAuditObject("User", userId)
.addAuditObjectDataValue("email", newEmail)
.build();
```
--------------------------------
### Create Audit Record Builder with System Trigger (From Message, Explicit Names)
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilderFactory.md
Creates a builder with a system trigger from a message, allowing explicit specification of auditing service, system names, and triggering service department. The message and timestamp are also required.
```java
public CreateAuditRecordCommandBuilder createWithSystemTriggerFromMessage(
String serviceName,
String systemName,
String triggeringServiceDepartment,
Instant timestamp,
Message message)
```
```java
CreateAuditRecordCommandBuilder builder = factory
.createWithSystemTriggerFromMessage(
"workflow-service",
"workflow-system",
"PROCESSING",
Instant.now(),
message);
```
--------------------------------
### Create AuditRecord from Avro Command
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/AuditRecordFactory.md
This snippet demonstrates how to use the AuditRecordFactory to convert an incoming Avro CreateAuditRecordCommand into a usable AuditRecord domain model within a Kafka listener. It shows accessing key fields of the resulting domain object.
```java
public static AuditRecord createAuditRecord(CreateAuditRecordCommand command)
```
```java
@KafkaListener(topics = "audit-commands")
public void handleAuditCommand(CreateAuditRecordCommand command) {
AuditRecord record = AuditRecordFactory.createAuditRecord(command);
// Now use the domain model
String serviceName = record.serviceName();
Instant timestamp = record.timestamp();
AuditEvent event = record.auditEvent();
AuditTrigger trigger = record.trigger();
// Process the audit record
persistToAuditLog(record);
}
```
--------------------------------
### Minimal jEAP Audit Configuration
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/README.md
This YAML snippet shows the basic configuration required to enable jEAP Audit, including setting the audit event topic and Kafka service/system names.
```yaml
jeap:
audit:
transactional-outbox:
topic: audit-events
messaging:
kafka:
service-name: my-service
system-name: my-system
```
--------------------------------
### CreateAuditRecordCommandTriggerUserProvider
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/exported-symbols.md
Provides the trigger user information for audit commands. Can be configured with different authorization strategies.
```APIDOC
## CreateAuditRecordCommandTriggerUserProvider
### Description
Provides the trigger user information for audit commands. Can be configured with different authorization strategies.
### Constructor
- `CreateAuditRecordCommandTriggerUserProvider(Optional, Optional)`
### Instance Methods
- `provideTriggerUser(CreateAuditRecordCommandBuilder): void`
```
--------------------------------
### User-Triggered Audit with Security Context
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilderFactory.md
Use this when a user action needs to be audited. It requires an `Instant` for the event time and allows setting event type, context, and audit objects.
```java
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import com.example.audit.CreateAuditRecordCommandBuilderFactory;
import com.example.audit.CreateAuditRecordCommandTransactionOutboxSender;
import com.example.audit.CreateAuditRecordCommand;
import com.example.audit.AuditEventType;
import java.time.Instant;
@Service
public class UserService {
@Autowired
private CreateAuditRecordCommandBuilderFactory factory;
@Autowired
private CreateAuditRecordCommandTransactionOutboxSender sender;
public void updateUserEmail(String userId, String newEmail) {
// ... update logic
// Create and send audit command
CreateAuditRecordCommand command = factory
.createWithUserTrigger(Instant.now())
.setEventType(AuditEventType.UPDATE)
.setContext("email-change")
.setAuditObject("User", userId)
.addAuditObjectDataValue("email", newEmail)
.build();
sender.auditEvent(command);
}
}
```
--------------------------------
### Configure Single Audit Topic
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/SpringAutoConfiguration.md
Configure a single topic for transactional outbox. This creates an unqualified sender bean.
```yaml
jeap:
audit:
transactional-outbox:
topic: audit-events
```
--------------------------------
### CreateAuditRecordCommandBuilderFactory Constructor
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilderFactory.md
This is the constructor for the CreateAuditRecordCommandBuilderFactory. It is instantiated by Spring auto-configuration. The triggerUserProvider is optional and only present if jEAP Security is on the classpath.
```java
public CreateAuditRecordCommandBuilderFactory(
Optional triggerUserProvider,
KafkaProperties kafkaProperties)
```
--------------------------------
### CreateAuditRecordCommandBuilder
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/exported-symbols.md
Builder for creating audit record commands. Supports chaining of methods to configure event type, context, data, trigger user, trigger system, and audit objects before building the final command.
```APIDOC
## CreateAuditRecordCommandBuilder
### Description
Builder for creating audit record commands. Supports chaining of methods to configure event type, context, data, trigger user, trigger system, and audit objects before building the final command.
### Static Factory Methods
- `createCommandBuilder(String, String, Instant): CreateAuditRecordCommandBuilder`
- `createCommandBuilder(String, String, Instant, String): CreateAuditRecordCommandBuilder`
### Instance Methods (return `CreateAuditRecordCommandBuilder` for chaining)
- `setEventType(AuditEventType): CreateAuditRecordCommandBuilder`
- `setContext(String): CreateAuditRecordCommandBuilder`
- `setContext(String, String): CreateAuditRecordCommandBuilder`
- `addEventData(String, String): CreateAuditRecordCommandBuilder`
- `setTriggerUser(String, String): CreateAuditRecordCommandBuilder`
- `setTriggerSystem(String, String, String): CreateAuditRecordCommandBuilder`
- `setAuditObject(String, String): CreateAuditRecordCommandBuilder`
- `setAuditObject(String, String, String): CreateAuditRecordCommandBuilder`
- `addAuditObjectDataValue(AuditObjectDataRole, String, String): CreateAuditRecordCommandBuilder`
- `addAuditObjectDataValue(String, String): CreateAuditRecordCommandBuilder`
- `addAuditObjectDataJSON(AuditObjectDataRole, String, String): CreateAuditRecordCommandBuilder`
- `addAuditObjectDataJSON(String, String): CreateAuditRecordCommandBuilder`
- `addAuditObjectDataJSON(AuditObjectDataRole, String, ByteBuffer): CreateAuditRecordCommandBuilder`
- `addAuditObjectDataJSON(String, ByteBuffer): CreateAuditRecordCommandBuilder`
- `addAuditObjectDataS3(AuditObjectDataRole, String, String): CreateAuditRecordCommandBuilder`
- `addAuditObjectDataS3(String, String): CreateAuditRecordCommandBuilder`
- `build(): CreateAuditRecordCommand`
### Inherited Methods (from AvroCommandBuilder)
- `idempotenceId(String): CreateAuditRecordCommandBuilder`
```
--------------------------------
### Injecting Multi-Topic Audit Senders
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/configuration.md
Inject specific `CreateAuditRecordCommandTransactionOutboxSender` instances using `@Qualifier` with the corresponding topic name when using multi-topic configuration.
```java
@Autowired
@Qualifier("mysystem-audit")
private CreateAuditRecordCommandTransactionOutboxSender primarySender;
@Autowired
@Qualifier("mysystem-audit-secondary")
private CreateAuditRecordCommandTransactionOutboxSender secondarySender;
```
--------------------------------
### Handle Unsupported Authentication AuditException
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/errors.md
Catch and handle AuditException when user data cannot be determined from the security context. Log the error and consider falling back to a system trigger.
```java
try {
CreateAuditRecordCommandBuilder builder = factory.createWithUserTrigger(Instant.now());
// configure and build...
} catch (AuditException e) {
if (e.getMessage().contains("Unsupported user Authentication")) {
// Log the unsupported authentication type
logger.error("Failed to extract user from security context: {}", e.getMessage());
// Fall back to system trigger or skip audit
return;
}
}
```
--------------------------------
### Creating Audit Events with Factory
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/README.md
Leverage the Spring-managed factory to create audit events, including user trigger information.
```java
factory.createWithUserTrigger(Instant.now())
```
--------------------------------
### Create Audit Record Builder with User Trigger (Explicit Names)
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/api-reference/CreateAuditRecordCommandBuilderFactory.md
Creates a builder with a user trigger from the security context, allowing explicit specification of service and system names. Requires jEAP Security on the classpath.
```java
public CreateAuditRecordCommandBuilder createWithUserTrigger(
String serviceName,
String systemName,
Instant timestamp)
```
```java
CreateAuditRecordCommandBuilder builder = factory
.createWithUserTrigger("notification-service", "notification-system", Instant.now());
```
--------------------------------
### Build User Modification Audit Command
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/_autodocs/usage-patterns.md
Manually constructs a `CreateAuditRecordCommand` for user modifications. Use this when you need fine-grained control over audit data without a factory. Requires `CreateAuditRecordCommandBuilder` and related enums/classes.
```java
public class ManualAuditBuilder {
public CreateAuditRecordCommand buildUserModificationAudit(
String serviceName,
String systemName,
String userId,
String issuer,
UserModification modification) {
CreateAuditRecordCommandBuilder builder =
CreateAuditRecordCommandBuilder.createCommandBuilder(
serviceName,
systemName,
Instant.now());
builder
.setEventType(AuditEventType.UPDATE)
.setContext("user-modification")
.setTriggerUser(userId, issuer)
.setAuditObject("User", modification.getUserId(), "v1");
// Add before/after values
if (modification.getEmailChanged()) {
builder
.addAuditObjectDataValue(AuditObjectDataRole.BEFORE, "email", modification.getOldEmail())
.addAuditObjectDataValue(AuditObjectDataRole.AFTER, "email", modification.getNewEmail());
}
if (modification.getRolesChanged()) {
builder.addAuditObjectDataValue("rolesUpdated", "true");
}
return builder.build();
}
public CreateAuditRecordCommand buildSystemActionAudit(
String serviceName,
String systemName,
String department,
String system,
String component,
String action) {
CreateAuditRecordCommandBuilder builder =
CreateAuditRecordCommandBuilder.createCommandBuilder(
serviceName,
systemName,
Instant.now());
builder
.setEventType(AuditEventType.EXECUTE)
.setContext("system-action")
.setTriggerSystem(department, system, component)
.setAuditObject("SystemJob", UUID.randomUUID().toString());
builder.addEventData("action", action);
builder.addEventData("timestamp", Instant.now().toString());
return builder.build();
}
}
```
--------------------------------
### Create Audit Record Command with System Trigger
Source: https://github.com/jeap-admin-ch/jeap-audit/blob/main/docs/building-the-command.md
Use this method to create an audit record triggered by a system event, deriving the trigger information from a consumed message. The idempotence ID is prefixed with 'audit-'.
```java
CreateAuditRecordCommandBuilder builder = factory.createWithSystemTriggerFromMessage(triggeringDepartment, Instant.now(), message);
CreateAuditRecordCommand command = builder.build();
```