### Create User API with Interceptor Source: https://github.com/bitweb/java-core-lib/wiki/Retrofit Example of creating a Retrofit API client using the builder, injecting a custom interceptor, and configuring it with properties. ```java @Bean public UserApi createUserApi( @Qualifier("userApiServiceTokenRetrofitRequestInterceptor") ServiceTokenRetrofitRequestInterceptor interceptor ) { log.info("Creating user api for {}", properties.getBaseUrl()); return retrofitBuilder .create(properties.getBaseUrl(), UserApi.class) .add(interceptor) .build(); } ``` -------------------------------- ### Recommended Logback-Spring Configuration Source: https://github.com/bitweb/java-core-lib/wiki/Logging Configure the SilencedGelfTcpAppender in your logback-spring.xml for production environments. This setup directs logs to Graylog via GELF TCP while also outputting to the console. ```xml \\${host} 12201 2 0 100 100 application:${rootProject.name} environment:${environment} version:${rootProject.version} build_number:${buildNumber} ``` -------------------------------- ### TokenProvider for Auth Token Injection Source: https://context7.com/bitweb/java-core-lib/llms.txt Implement TokenProvider to supply authentication tokens for injection into API requests. This example retrieves a Bearer token from the SecurityContext. ```java // Provide a TokenProvider bean for auth token injection @Component public class SecurityContextTokenProvider implements TokenProvider { @Override public String get() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); return (auth instanceof BearerTokenAuthentication b) ? b.getToken().getTokenValue() : null; } } ``` -------------------------------- ### Custom AMQP Listener Interceptor Example Source: https://github.com/bitweb/java-core-lib/wiki/AMQP-Support Implement the AmqpListenerInterceptor interface to create a custom interceptor for processing messages before they reach the listener. Auto-configuration respects the @Order annotation. ```java @Slf4j @RequiredArgsConstructor public class AmqpTraceBeforePublishMessageProcessor implements AmqpBeforePublishMessageProcessor { private final AmqpTraceProperties properties; private final TraceIdContext context; @Override public Message postProcessMessage(Message message) throws AmqpException { log.debug("Adding trace id {} to AMQP message header {} ", context.get(), properties.getHeaderName()); message.getMessageProperties().setHeader(properties.getHeaderName(), context.get()); return message; } } ``` -------------------------------- ### Update TrimmedStringDeserializer API for Jackson 3 in v5.0.0 Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide Use createModule() to get a SimpleModule for Jackson 3's TrimmedStringDeserializer in v5.0.0. ```java // Before (v4.x) TrimmedStringDeserializer.addToObjectMapper(objectMapper); // After (v5.0.0) — for Jackson 3: jsonMapperBuilder.addModule(TrimmedStringDeserializer.createModule()); // After (v5.0.0) — for Jackson 2 (Retrofit): Jackson2TrimmedStringDeserializer.addToObjectMapper(objectMapper); // or objectMapper.registerModule(Jackson2TrimmedStringDeserializer.createModule()); ``` -------------------------------- ### Scheduled Job Implementation in Java Source: https://github.com/bitweb/java-core-lib/wiki/Scheduled-job Example of a scheduled job that extends ScheduledJob and uses a cron expression for scheduling. Ensure the SchedulerTraceIdResolver bean is present in the context. ```java @Component public class ProductionOrderUpdateScheduler extends ScheduledJob { public ProductionOrderUpdateScheduler( final ProductionOrderRowImportComponent runnable, final SchedulerTraceIdResolver traceIdResolver ) { super(runnable, traceIdResolver); } @Scheduled(cron = "${scheduled.production-order-row.cron}") public void schedule() { run(); } } ``` -------------------------------- ### Retrofit API Client Definition Source: https://context7.com/bitweb/java-core-lib/llms.txt Define Retrofit interfaces for API interactions using annotations like @GET, @POST, and @Path. ```java // Declare the Retrofit interface public interface UserApi { @GET("users/{id}") Call> getById(@Path("id") Long id); @POST("users") Call> create(@Body CreateUserRequest body); } ``` -------------------------------- ### Implement Custom Audit Log Data Mapper Source: https://github.com/bitweb/java-core-lib/wiki/Audit-log Example of creating a custom audit log data mapper to extract user-specific information, such as a person code from a JWT in a request header. Ensure the mapper is placed correctly in the filter chain. ```java @Component @RequiredArgsConstructor public class PersonCodeDataMapper implements AuditLogDataMapper { public static final String KEY = "person_code"; private final JwtProcessor processor; private final AuthenticationProperties properties; private final ValidateTokenFeature validateTokenFeature; @Override public String getValue(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) { String token = httpServletRequest.getHeader(properties.getAccessTokenHeaderName()); if (token != null && validateTokenFeature.isValid(token)) { return processor.getSubject(token); } return null; } @Override public String getKey() { return KEY; } } ``` -------------------------------- ### Build Project with Gradle Source: https://github.com/bitweb/java-core-lib/blob/master/CLAUDE.md Standard Gradle command to build the entire project. ```bash ./gradlew build ``` -------------------------------- ### Run Tests with Coverage Reports using Gradle Source: https://github.com/bitweb/java-core-lib/blob/master/CLAUDE.md Build the project and generate test coverage reports. ```bash ./gradlew testAndReport ``` -------------------------------- ### Run All Tests with Gradle Source: https://github.com/bitweb/java-core-lib/blob/master/CLAUDE.md Execute all tests within the project using Gradle. ```bash ./gradlew test ``` -------------------------------- ### Add Spring AMQP Starter Dependency Source: https://github.com/bitweb/java-core-lib/wiki/AMQP-Support Include the Spring Boot AMQP starter dependency for AMQP functionality. ```gradle implementation 'org.springframework.boot:spring-boot-starter-amqp' ``` -------------------------------- ### Run Single Test Class with Gradle Source: https://github.com/bitweb/java-core-lib/blob/master/CLAUDE.md Execute a specific test class using Gradle by providing its fully qualified name. ```bash ./gradlew test --tests "ee.bitweb.core.api.model.exception.ControllerAdvisorIntegrationTests" ``` -------------------------------- ### Include Web Starter Dependency Source: https://github.com/bitweb/java-core-lib/wiki/CORS-autoconfiguration Include the Spring Boot Web starter dependency to use the CORS autoconfiguration feature. ```gradle implementation 'org.springframework.boot:spring-boot-starter-web' ``` -------------------------------- ### Spring Boot AMQP Starter Dependency Source: https://context7.com/bitweb/java-core-lib/llms.txt Include the Spring Boot Starter AMQP dependency in your build.gradle file to enable AMQP functionalities. ```groovy // build.gradle implementation 'org.springframework.boot:spring-boot-starter-amqp' ``` -------------------------------- ### Configure Maven Repositories for Development Source: https://github.com/bitweb/java-core-lib/wiki/Home Define the repositories to use when building or publishing the library locally. ```gradle repositories { mavenLocal() mavenCentral() } ``` -------------------------------- ### Migration from 2.* to 3.* for Controller Advisor Source: https://github.com/bitweb/java-core-lib/wiki/Controller-advisor Update the configuration property to enable the feature when migrating from version 2.* to 3.*. Error message formats have also changed for specific exceptions. ```text ee.bitweb.core.controller-advice.enabled=true to ee.bitweb.core.controller-advice.auto-configuration=true ``` -------------------------------- ### Enable Controller Advisor Auto-Configuration Source: https://github.com/bitweb/java-core-lib/wiki/Controller-advisor Add this property to your configuration to enable the auto-configuration mechanism for the Controller Advisor feature. ```text ee.bitweb.core.controller-advice.auto-configuration=true ``` -------------------------------- ### Run Integration Tests with Gradle Source: https://github.com/bitweb/java-core-lib/blob/master/CLAUDE.md Execute only integration tests, including those tagged with @Tag("integration"). ```bash ./gradlew integrationTest ``` -------------------------------- ### Run Unit Tests with Gradle Source: https://github.com/bitweb/java-core-lib/blob/master/CLAUDE.md Execute only unit tests, excluding those tagged as integration tests. ```bash ./gradlew unitTest ``` -------------------------------- ### Implement Custom Audit Log Writer Source: https://github.com/bitweb/java-core-lib/wiki/Audit-log This Java class demonstrates how to implement a custom audit log writer by extending AuditLogWriteAdapter. It shows how to capture and log audit information, including request method, URL, response status, and duration, while preserving MDC context. ```java public class AuditLogLoggerWriterAdapter implements AuditLogWriteAdapter { public static final String AUDIT = "audit"; @Override public void write(Map container) { Map currentContext = MDC.getCopyOfContextMap(); container.put(AUDIT, "1"); MDC.setContextMap(container); log.info( "{} {} {} {} ms", get(container, RequestMethodMapper.KEY), get(container, RequestUrlDataMapper.KEY), get(container, ResponseStatusMapper.KEY), get(container, AuditLogFilter.DURATION_KEY)); if (currentContext != null) { MDC.setContextMap(currentContext); } } private String get(Map container, String key) { if (container.containsKey(key)) { return container.get(key); } return "UNKNOWN"; } } ``` -------------------------------- ### Enable AMQP Auto-Configuration Source: https://github.com/bitweb/java-core-lib/wiki/AMQP-Support Add this property to application.properties to enable automatic AMQP configuration, including JSON message conversion and Trace ID propagation. ```properties ee.bitweb.core.amqp.auto-configuration=true ``` -------------------------------- ### Required Dependencies for Controller Advisor Source: https://github.com/bitweb/java-core-lib/wiki/Controller-advisor Ensure these dependencies are added to your project as the core library does not provide transitive dependencies. ```gradle implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' ``` -------------------------------- ### Send Message using AmqpService Source: https://github.com/bitweb/java-core-lib/wiki/AMQP-Support Utilize the AmqpService helper class to send messages to a specified queue, with options to set message headers. ```java amqpService.sendMessage( REQUEST_QUEUE, responseQueue, request, message -> { message.getMessageProperties().setHeader(AmqpConstants.VERSION_HEADER_NAME, version.toString()); message.getMessageProperties().setHeader(AmqpConstants.PROCESSLOCK_HEADER_NAME, processLockName); return null; } ); ``` -------------------------------- ### AMQP Auto-Configuration Source: https://context7.com/bitweb/java-core-lib/llms.txt Enable AMQP auto-configuration in application.yml to set up RabbitMQ support with a JSON message converter and listener/publisher interceptors. ```yaml # application.yml ee: bitweb: core: amqp: auto-configuration: true ``` -------------------------------- ### Configure Base Package Scanning for Auto-Configured Components Source: https://github.com/bitweb/java-core-lib/wiki/Home Specify the base packages to scan for auto-configured components in your Spring Boot application. ```java @SpringBootApplication(scanBasePackages = {"ee.bitweb.core.*", "com.example.*"}) ``` -------------------------------- ### Retrofit Configuration Source: https://context7.com/bitweb/java-core-lib/llms.txt Configure Retrofit client settings in application.yml, including timeouts, logging levels, and authentication. ```yaml ee: bitweb: core: retrofit: auto-configuration: true timeout: call: 30000 # ms, 0 = no limit connect: 10000 read: 10000 write: 10000 logging: level: BASIC # NONE | BASIC | HEADERS | BODY | CUSTOM max-loggable-request-body-size: 10240 max-loggable-response-body-size: 10240 redacted-body-urls: - /upload - /download auth-token-injector: enabled: true header-name: Authorization whitelist-urls[0]: "^https://internal\.mycompany\.com/.*" ``` -------------------------------- ### Add logback-gelf Dependency Source: https://github.com/bitweb/java-core-lib/wiki/Logging Include this dependency in your project to use the logback-gelf library, which is required for the SilencedGelfTcpAppender. ```gradle implementation group: 'de.siegmar', name: 'logback-gelf', version: '6.0.1' ``` -------------------------------- ### Enable CORS Autoconfiguration Source: https://github.com/bitweb/java-core-lib/wiki/CORS-autoconfiguration Add this property to your `application.properties` file to enable CORS autoconfiguration. ```text ee.bitweb.core.cors.auto-configuration=true ``` -------------------------------- ### Enable ObjectMapper Auto-configuration Source: https://github.com/bitweb/java-core-lib/wiki/Object-mapper-autoconfiguration Add this property to your application.properties file to enable the ObjectMapper auto-configuration. ```properties ee.bitweb.core.object-mapper.auto-configuration=true ``` -------------------------------- ### Add Retrofit Dependencies Source: https://github.com/bitweb/java-core-lib/wiki/Retrofit Include these Gradle dependencies to use Retrofit and its Jackson converter. Ensure you specify the retrofitVersion. ```gradle implementation group: 'com.squareup.retrofit2', name: 'retrofit', version: "${retrofitVersion}" ``` ```gradle implementation group: 'com.squareup.retrofit2', name: 'converter-jackson', version: "${retrofitVersion}" ``` -------------------------------- ### Enable Retrofit Auto-Configuration Source: https://github.com/bitweb/java-core-lib/wiki/Retrofit Add this property to your application.properties file to enable automatic configuration for Retrofit components. ```properties ee.bitweb.core.retrofit.auto-configuration=true ``` -------------------------------- ### Enable Audit Logging Configuration Source: https://github.com/bitweb/java-core-lib/wiki/Audit-log Add this property to your application.properties file to enable audit log autoconfiguration. ```properties ee.bitweb.core.audit.auto-configuration=true ``` -------------------------------- ### Add Jackson Databind Dependency Source: https://github.com/bitweb/java-core-lib/wiki/AMQP-Support If not using spring-boot-starter-web, add the Jackson databind dependency for JSON serialization and deserialization. ```gradle implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${jacksonVersion}" ``` -------------------------------- ### Add Spring Core Library Dependency Source: https://context7.com/bitweb/java-core-lib/llms.txt Include the `spring-core` library in your project's Gradle build file. Ensure auto-configured component scanning is enabled by including `ee.bitweb.core.*` in your `@SpringBootApplication`'s `scanBasePackages`. ```groovy // build.gradle implementation group: 'ee.bitweb', name: 'spring-core', version: '5.0.0' // Required for auto-configured component scanning @SpringBootApplication(scanBasePackages = {"ee.bitweb.core.*", "com.example.*"}) ``` -------------------------------- ### Migration from 2.x to 3.x Source: https://github.com/bitweb/java-core-lib/wiki/Actuator-security To enable the feature in newer versions, update the configuration property name. This change reflects the evolution of the autoconfiguration property. ```text ee.bitweb.core.actuator.security.auto-configuration ``` -------------------------------- ### Logback GELF Dependency Source: https://context7.com/bitweb/java-core-lib/llms.txt Add the logback-gelf dependency to your Gradle build file to enable GELF logging. ```groovy // build.gradle implementation 'de.siegmar:logback-gelf:6.1.2' ``` -------------------------------- ### Implement Custom Retrofit Logging Mapper Source: https://github.com/bitweb/java-core-lib/wiki/Retrofit Create a custom mapper by implementing the RetrofitLoggingMapper interface, adding it as a Spring component, and configuring it to be included in logging. ```java @Slf4j @Component public class ContentTypeRetrofitLoggerMapper implements RetrofitLoggingMapper { @Override public String getValue(Request request, Response response) { return request.header("Content-Type"); } @Override public String getKey() { return "ContentType"; } } ``` -------------------------------- ### SilencedGelfTcpAppender Configuration Source: https://context7.com/bitweb/java-core-lib/llms.txt Configure a fault-tolerant GELF TCP appender for Logback that silences connection and send exceptions. This prevents application crashes due to logging failures, dropping undeliverable messages. ```xml ${host} 12201 2 0 100 100 application:my-service environment:production ``` -------------------------------- ### Configure Logging Mappers and Level Source: https://github.com/bitweb/java-core-lib/wiki/Retrofit Configure Retrofit logging by setting the logging level and specifying mappers. Default and provided mappers are merged unless the level is CUSTOM. ```properties ee.bitweb.core.retrofit.logging.level=basic ee.bitweb.core.retrofit.logging.mappers=response_body ``` -------------------------------- ### Sending Messages with AmqpService Source: https://context7.com/bitweb/java-core-lib/llms.txt Utilize AmqpService to send messages to RabbitMQ queues. Supports simple sends and sends with reply queues and custom headers. ```java // Sending messages with AmqpService @Service @RequiredArgsConstructor public class OrderPublisher { private static final String ORDER_QUEUE = "orders.created"; private static final String REPLY_QUEUE = "orders.reply"; private final AmqpService amqpService; // Simple send without reply queue public void publish(OrderDto order) { amqpService.sendMessage(ORDER_QUEUE, order); } // Send with reply queue and custom headers public void publishWithVersion(OrderDto order, int version) { amqpService.sendMessage(ORDER_QUEUE, REPLY_QUEUE, order, message -> { message.getMessageProperties().setHeader("x-version", version); message.getMessageProperties().setHeader("x-source", "order-service"); return message; }); } } ``` -------------------------------- ### Add Bitweb Spring Core Dependency Source: https://github.com/bitweb/java-core-lib/blob/master/README.md Include this dependency in your project to use the Bitweb Spring Core library. Check Maven Central for the latest versions. ```gradle implementation group: 'ee.bitweb', name: 'spring-core', version: '5.0.0' ``` -------------------------------- ### Required Dependencies for Actuator Security Source: https://github.com/bitweb/java-core-lib/wiki/Actuator-security Include these dependencies in your project to ensure the actuator security autoconfiguration functions correctly. The core library does not provide transitive dependencies for these. ```gradle implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: "${springBootVersion}" ``` ```gradle implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: "${springBootVersion}" ``` -------------------------------- ### Enable Trace ID Auto-Configuration Source: https://github.com/bitweb/java-core-lib/wiki/Trace-Id Add this property to your configuration to enable the automatic addition and propagation of Trace ID to log entries. This requires the 'spring-boot-starter-web' dependency. ```properties ee.bitweb.core.trace.auto-configuration=true ``` -------------------------------- ### Configure Trace ID Properties Source: https://context7.com/bitweb/java-core-lib/llms.txt Configure trace ID generation and propagation using YAML properties. Customize prefixes, delimiters, lengths, and HTTP header names for trace IDs. ```yaml # application.yml ee: bitweb: core: trace: auto-configuration: true invoker: prefix: "my-svc" # added to trace ID for readability delimiter: "-" length: 20 # [10, 20] http: headerName: X-Trace-ID thread: delimiter: ":" length: 10 # [5, 10] scheduler: length: 20 ``` -------------------------------- ### Update Jackson Imports for v5.0.0 Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide Update imports from com.fasterxml.jackson to tools.jackson when migrating to Jackson 3 in v5.0.0. ```java // Before (v4.x) import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.DeserializationFeature; // After (v5.0.0) import tools.jackson.databind.ObjectMapper; import tools.jackson.databind.DeserializationFeature; ``` -------------------------------- ### StringUtil for String Manipulation Source: https://context7.com/bitweb/java-core-lib/llms.txt Provides null-safe string trimming and secure random alphanumeric string generation. Use StringUtil.trim for safe trimming and StringUtil.random for generating tokens or IDs. ```java // StringUtil.trim – null-safe trim String trimmed = StringUtil.trim(" hello world "); // "hello world" String nullSafe = StringUtil.trim(null); // null ``` ```java // StringUtil.random – secure random alphanumeric string String token = StringUtil.random(32); // e.g. "A3fK9mNqR2sT7uVwX1yZ0bCdEfGhIjKl" String shortId = StringUtil.random(8); // e.g. "Tz4mR9kQ" ``` -------------------------------- ### Configure CORS Auto-Configuration Source: https://context7.com/bitweb/java-core-lib/llms.txt Enable CORS for all paths by registering a CorsConfigurationSource bean. Configure allowed origins, methods, and credential support via application.yml. ```yaml # application.yml ee: bitweb: core: cors: auto-configuration: true path: "/**" allow-credentials: true allowed-origins: - https://app.example.com - https://admin.example.com allowed-methods: - GET - POST - PUT - DELETE - OPTIONS - PATCH ``` ```bash # Preflight request – browser sends before cross-origin POST curl -X OPTIONS https://api.example.com/users \ -H "Origin: https://app.example.com" \ -H "Access-Control-Request-Method: POST" \ -H "Access-Control-Request-Headers: Content-Type" \ -i # → HTTP 200 # Access-Control-Allow-Origin: https://app.example.com # Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS,PATCH # Access-Control-Allow-Credentials: true ``` -------------------------------- ### Custom AmqpListenerInterceptor Source: https://context7.com/bitweb/java-core-lib/llms.txt Implement AmqpListenerInterceptor to intercept incoming messages before they are processed by the listener, useful for tasks like schema validation. ```java // Custom listener interceptor (e.g., request validation) @Component @Order(2) public class SchemaValidationInterceptor implements AmqpListenerInterceptor { @Override public Message preProcess(Message message) throws AmqpException { // validate schema, throw AmqpRejectAndDontRequeueException to dead-letter return message; } } ``` -------------------------------- ### Enable Actuator Security Autoconfiguration Source: https://github.com/bitweb/java-core-lib/wiki/Actuator-security Add this property to your configuration to enable the autoconfiguration mechanism for actuator endpoint security. This is the primary step to activate the feature. ```text ee.bitweb.core.actuator.security.auto-configuration=true ``` -------------------------------- ### Async Thread Pool with MDC Trace Propagation Source: https://context7.com/bitweb/java-core-lib/llms.txt Configure an asynchronous thread pool using `ThreadPoolTaskExecutor` and apply `BasicMDCTaskDecorator` for MDC trace propagation. This ensures trace IDs are correctly managed across asynchronous operations. ```java // Async thread pool with MDC trace propagation @Slf4j @EnableAsync @Configuration @RequiredArgsConstructor public class AsyncConfig implements AsyncConfigurer { private final ThreadTraceIdResolver resolver; @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setThreadNamePrefix("Async-"); executor.setTaskDecorator(new BasicMDCTaskDecorator(resolver)); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor.initialize(); return executor; } } ``` -------------------------------- ### Configure Persistence Exception Log Levels in v5.0.0 Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide Configure entity-not-found-exception and conflict-exception independently in v5.0.0, as the persistence-exception property is removed. ```yaml # Before (v4.x) ee.bitweb.core.api.controller-advisor.log-level: persistence-exception: WARN # affected both entity-not-found and conflict # After (v5.0.0) — configure each independently: ee.bitweb.core.api.controller-advisor.log-level: entity-not-found-exception: WARN conflict-exception: WARN ``` -------------------------------- ### TransactionHelper for Post-Commit Hooks Source: https://context7.com/bitweb/java-core-lib/llms.txt Register callbacks to execute after a database transaction commits successfully. This ensures actions like sending notifications only occur if the transaction succeeds. ```java @Service @RequiredArgsConstructor public class UserRegistrationService { private final UserRepository userRepository; private final AmqpService amqpService; @Transactional public User register(CreateUserRequest req) { User user = userRepository.save(new User(req.getEmail())); // This lambda fires ONLY after the transaction commits successfully. // If the transaction rolls back, the message is NOT sent. TransactionHelper.afterCommit(() -> amqpService.sendMessage("users.registered", new UserRegisteredEvent(user.getId())) ); return user; } } ``` -------------------------------- ### Custom Audit Log Mapper Source: https://context7.com/bitweb/java-core-lib/llms.txt Implements a custom audit log mapper to add specific data, such as the authenticated user's ID, to each audit log entry. This requires implementing the AuditLogDataMapper interface and defining a unique key for the data. ```java // Custom audit mapper – adds authenticated user's ID to every log entry @Component @RequiredArgsConstructor public class UserIdAuditMapper implements AuditLogDataMapper { public static final String KEY = "user_id"; private final SecurityContextHolder securityContextHolder; @Override public String getValue(HttpServletRequest req, HttpServletResponse res) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.isAuthenticated()) { return auth.getName(); } return null; } @Override public String getKey() { return KEY; } } // Custom writer – sends audit entries to a dedicated queue instead of the app log @Component public class AmqpAuditLogWriter implements AuditLogWriteAdapter { private final AmqpService amqpService; @Override public void write(Map container) { amqpService.sendMessage("audit.log.queue", container); } } // Produces INFO log (default writer): // GET /api/users 200 42ms (MDC contains: method, url, status, duration, trace_id, user_id …) ``` -------------------------------- ### Configure Async Executor with Task Decorator Source: https://github.com/bitweb/java-core-lib/wiki/Trace-Id When using @Async, configure a custom ThreadPoolTaskExecutor with a TaskDecorator to ensure Trace ID is propagated to background jobs. BasicMDCTaskDecorator is suitable when security context is not needed. ```java @Slf4j @EnableAsync @Configuration @RequiredArgsConstructor public class AsyncConfig implements AsyncConfigurer { private static final Integer CORE_POOL_SIZE = 10; private static final Integer MAX_POOL_SIZE = 20; private static final String DEFAULT_PREFIX = "CustomAsync-"; private final ThreadTraceIdResolver resolver; @Override public Executor getAsyncExecutor() { log.info("Creating Async thread pool executor"); ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setThreadNamePrefix(DEFAULT_PREFIX); executor.setTaskDecorator(new BasicMDCTaskDecorator(resolver)); executor.setMaxPoolSize(MAX_POOL_SIZE); executor.setCorePoolSize(CORE_POOL_SIZE); executor.initialize(); return executor; } } ``` -------------------------------- ### Update Spring Boot Test Imports Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide The MockMvc auto-configuration has moved to a new package in Spring Boot 4. Update your import statements accordingly. ```java // Before (v4.x) import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; ``` ```java // After (v5.0.0) import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; ``` -------------------------------- ### Include Jackson Java Time Module Dependency Source: https://github.com/bitweb/java-core-lib/wiki/Object-mapper-autoconfiguration Include this dependency in your build file to enable the Java Time module for ObjectMapper, allowing serialization and deserialization of java.time data types. ```gradle implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: "${jacksonVersion}" ``` -------------------------------- ### Custom AmqpBeforePublishMessageProcessor Source: https://context7.com/bitweb/java-core-lib/llms.txt Implement AmqpBeforePublishMessageProcessor to modify messages before they are published, such as adding a correlation ID. ```java // Custom before-publish processor (e.g., adding a correlation ID) @Component @Order(2) public class CorrelationIdProcessor implements AmqpBeforePublishMessageProcessor { @Override public Message postProcessMessage(Message message) throws AmqpException { message.getMessageProperties().setCorrelationId(UUID.randomUUID().toString()); return message; } } ``` -------------------------------- ### Exception Handling with Custom Exceptions Source: https://context7.com/bitweb/java-core-lib/llms.txt Automatically handles custom exceptions like EntityNotFoundException, ConflictException, and MethodArgumentNotValidException by mapping them to appropriate HTTP status codes and response bodies. Throw exceptions from your service layer to leverage this feature. ```java throw new EntityNotFoundException("User", "email", "john@example.com"); // → HTTP 404: // { // "id": "svc-Abc123", // "message": "Entity User not found", // "entity": "User", // "criteria": [{"field": "email", "value": "john@example.com"}] // } ``` ```java throw new ConflictException("User already exists", "User", "email", "john@example.com"); // → HTTP 409: // { // "id": "svc-Abc123", // "message": "User already exists", // "entity": "User", // "criteria": [{"field": "email", "value": "john@example.com"}] // } ``` ```java throw new ValidationException(Set.of( new FieldError("email", "InvalidFormat", "Email is not valid") )); // → HTTP 400: // { // "id": "svc-Abc123", // "message": "Validation failed with errors", // "errors": [{"field": "email", "message": "InvalidFormat", "reason": "Email is not valid"}] // } ``` -------------------------------- ### Configure Jackson for String Trimming Source: https://context7.com/bitweb/java-core-lib/llms.txt Enable automatic trimming of String fields during JSON deserialization by registering the TrimmedStringDeserializer module. This requires the jackson-datatype-jsr310 dependency for Java 8 Date/Time support. ```groovy // build.gradle – required for JavaTimeModule (Jackson 2) implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.2' ``` ```java // Using Jackson 3 module manually (e.g., for a custom JsonMapper) JsonMapper jsonMapper = JsonMapper.builder() .addModule(TrimmedStringDeserializer.createModule()) .disable(DateTimeFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE) .disable(DeserializationFeature.ACCEPT_FLOAT_AS_INT) .build(); ``` ```java // Using Jackson 2 module manually (e.g., for a custom ObjectMapper) ObjectMapper objectMapper = new ObjectMapper(); Jackson2TrimmedStringDeserializer.addToObjectMapper(objectMapper); // or objectMapper.registerModule(Jackson2TrimmedStringDeserializer.createModule()); objectMapper.registerModule(new JavaTimeModule()); objectMapper.disable(ADJUST_DATES_TO_CONTEXT_TIME_ZONE); objectMapper.disable(ACCEPT_FLOAT_AS_INT); ``` -------------------------------- ### Scheduled Job Scaffolding with ScheduledJob Source: https://context7.com/bitweb/java-core-lib/llms.txt Reduce boilerplate for cron jobs by extending ScheduledJob or ScheduledRunnable. This base class handles trace ID generation, error handling, and logging for job execution. ```java // Step 1: implement the unit of work @Component public class CleanupExpiredTokensComponent implements ScheduledRunnable { @Override public void run() { // business logic here – exceptions propagate to ScheduledJob.handleException() tokenRepository.deleteExpiredBefore(Instant.now()); } } // Step 2: define the scheduler invocation class @Component public class CleanupTokensScheduler extends ScheduledJob { public CleanupTokensScheduler( CleanupExpiredTokensComponent runnable, SchedulerTraceIdResolver traceIdResolver ) { super(runnable, traceIdResolver); } @Scheduled(cron = "${scheduled.cleanup-tokens.cron:0 0 * * * *}") public void schedule() { run(); // handles trace ID, logging, and error handling automatically } } // Logs on each invocation: // INFO Started com.example.CleanupTokensScheduler // INFO Finished com.example.CleanupTokensScheduler // ERROR com.example.CleanupTokensScheduler failed: (on exception) ``` -------------------------------- ### Audit Log Configuration Source: https://context7.com/bitweb/java-core-lib/llms.txt Configures the audit log servlet filter to capture HTTP request/response details. Customize loggable sizes, included/sensitive headers, paths to exclude, and whether to include request duration. Ensure the 'AuditLogger' is set to DEBUG level to log request and response bodies. ```yaml ee: bitweb: core: audit: auto-configuration: true max-loggable-response-size: 3072 # bytes max-loggable-request-size: 3072 request-headers: User-Agent, Origin sensitive-headers: Authorization # values are redacted blacklist: /actuator/ # paths to skip include-duration: true # Enable body logging (DEBUG level) logging: level: AuditLogger: DEBUG ``` -------------------------------- ### Enable Request/Response Body Logging Source: https://github.com/bitweb/java-core-lib/wiki/Audit-log To include request and response bodies in audit logs, set the logging level for AuditLogger to DEBUG in your application's configuration properties. ```text logging.level.AuditLogger=DEBUG ``` -------------------------------- ### Update Spring Security & Actuator Imports Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide Spring Boot 4 reorganized several actuator and security packages. Update your import statements to reflect these changes. ```java // Before (v4.x) import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointProperties; import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; ``` ```java // After (v5.0.0) import org.springframework.boot.health.autoconfigure.actuate.endpoint.HealthEndpointProperties; import org.springframework.boot.security.autoconfigure.actuate.web.servlet.EndpointRequest; ``` -------------------------------- ### Spring Bean Registration for Retrofit API Source: https://context7.com/bitweb/java-core-lib/llms.txt Register the Retrofit API client as a Spring bean using SpringAwareRetrofitBuilder. Ensure the base URL is correctly configured. ```java // Register the API client as a Spring bean using SpringAwareRetrofitBuilder @Configuration @RequiredArgsConstructor @Slf4j public class UserApiConfig { private final SpringAwareRetrofitBuilder retrofitBuilder; private final UserApiProperties properties; // holds baseUrl @Bean public UserApi userApi() { log.info("Creating UserApi for {}", properties.getBaseUrl()); return retrofitBuilder .create(properties.getBaseUrl(), UserApi.class) .build(); } } ``` -------------------------------- ### Enable Actuator Security Auto-Configuration Source: https://context7.com/bitweb/java-core-lib/llms.txt Secure Spring Actuator endpoints using HTTP Basic Authentication. A default 'ACTUATOR' role is created with a random password, and the '/health' endpoint is accessible by default to 'ACTUATOR' and 'ANONYMOUS' roles. ```yaml # application.yml ee: bitweb: core: actuator: security: auto-configuration: true role: ACTUATOR health-endpoint-roles: - ACTUATOR - ANONYMOUS disable-unsafe-health-endpoint-warning: false user: name: actuator-user password: my-secure-password # default: random UUID roles: - ACTUATOR ``` ```groovy // build.gradle implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-security' ``` ```bash # Access actuator health (public) curl http://localhost:8080/actuator/health # → {"status":"UP"} # Access protected actuator endpoint with Basic Auth curl -u actuator-user:my-secure-password http://localhost:8080/actuator/env # → {"activeProfiles": [...], "propertySources": [...]} # Unauthorized access returns 401 curl http://localhost:8080/actuator/env # → HTTP 401 Unauthorized ``` -------------------------------- ### Custom Jakarta Validators: @FileType and @Uppercase Source: https://context7.com/bitweb/java-core-lib/llms.txt Use @FileType to validate MIME types of uploaded files and @Uppercase to ensure string fields are in uppercase. Both integrate with ControllerAdvisor for error handling. ```java public class UploadRequest { @NotNull @FileType({FileTypeEnum.PDF, FileTypeEnum.JPEG, FileTypeEnum.PNG}) private MultipartFile document; } ``` ```java public class CountryRequest { @NotBlank @Uppercase private String countryCode; // "EST" ✓, "est" ✗ → "string must be uppercase" } ``` -------------------------------- ### Replace MDCTaskDecorator in v5.0.0 Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide Replace the removed MDCTaskDecorator with BasicMDCTaskDecorator or SecurityAwareMDCTaskDecorator in v5.0.0. ```java // Before (v4.x) new MDCTaskDecorator(resolver); // After (v5.0.0) — choose one: new BasicMDCTaskDecorator(resolver); new SecurityAwareMDCTaskDecorator(resolver); ``` -------------------------------- ### Execute API Call with RetrofitRequestExecutor Source: https://github.com/bitweb/java-core-lib/wiki/Retrofit Use RetrofitRequestExecutor to execute API calls, which handles response data extraction and basic error handling. It throws a RetrofitException on error. ```java public UserResponse byPersonCode(String personCode) { log.info("Requesting user from user server by personCode: {}", personCode); return RetrofitRequestExecutor.execute(userApi.getByPersonCode(personCode)); } ``` -------------------------------- ### Accessing Current Trace ID Source: https://context7.com/bitweb/java-core-lib/llms.txt Retrieve the current trace ID from the `TraceIdContext` within your application services. This allows for logging and tracking requests across different components. ```java // Reading the current trace ID anywhere in the application @Service @RequiredArgsConstructor public class MyService { private final TraceIdContext traceIdContext; public void doWork() { String currentTraceId = traceIdContext.get(); // e.g. "my-svc-A3fK9....:tHs29" log.info("Processing with trace {}", currentTraceId); } } ``` -------------------------------- ### Safe Retrofit API Call Execution Source: https://context7.com/bitweb/java-core-lib/llms.txt Execute Retrofit API calls using RetrofitRequestExecutor for safe handling of responses and exceptions. This utility unwraps the Response and throws RetrofitException on failure. ```java // Execute calls safely – throws RetrofitException on any error @Service @RequiredArgsConstructor public class UserService { private final UserApi userApi; public UserResponse getById(Long id) { // RetrofitRequestExecutor unwraps Response and throws RetrofitException on failure return RetrofitRequestExecutor.execute(userApi.getById(id)); } public UserResponse create(CreateUserRequest req) { return RetrofitRequestExecutor.execute(userApi.create(req)); } } ``` -------------------------------- ### Handle InvalidFormatValidationException in v5.0.0 Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide Catch InvalidFormatValidationException as a RuntimeException in v5.0.0, using getCause() to access the original exception. ```java // Before (v4.x) catch (InvalidFormatValidationException e) { // was a checked exception (InvalidFormatException → JsonProcessingException → IOException) } // After (v5.0.0) catch (InvalidFormatValidationException e) { // now a RuntimeException — no longer needs to be declared in throws clauses e.getCause(); // returns the original InvalidFormatException } ``` -------------------------------- ### Update AMQP Message Converter Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide When overriding the message converter bean, update to `JacksonJsonMessageConverter` and provide a `JsonMapper` instead of an `ObjectMapper`. ```java // Before (v4.x) Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter(objectMapper); ``` ```java // After (v5.0.0) JacksonJsonMessageConverter converter = new JacksonJsonMessageConverter(jsonMapper); ``` -------------------------------- ### Add Jackson 2 JSR310 Datatype for v5.0.0 Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide Explicitly add jackson-datatype-jsr310 to the compile classpath if Jackson 2's JavaTimeModule is needed with a custom ObjectMapper bean in v5.0.0. ```groovy implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310' ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.