### 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(); ```