[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M73FAW1VPWT2XPPCFE4VS3GY":3,"skill-same:01M73FAW1VPWT2XPPCFE4VS3GY":49},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":28,"repositoryHtmlUrl":29,"repositoryHomepageUrl":30,"ownerHtmlUrl":31,"ownerBlogUrl":32,"ownerDescription":33,"updatedAt":34,"install":35,"resources":48},"01M73FAW1VPWT2XPPCFE4VS3GY","quarkus-patterns",null,"Quarkus 3.x LTS architecture patterns with Camel for messaging, RESTful API design, CDI services, data access with Panache, and async processing. Use for Java Quarkus backend work with event-driven architectures.","Horonomos-laps\u002FYana-AI","Horonomos-laps","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F355299122?v=4","01M76B3QPXE88ET2SQPDPVATZT"," Horonomos-laps","01M72ZQRJPCYPSSWT4D00VJR2A",13,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FHoronomos-laps\u002FYana-AI\u002Fblob\u002Fmain\u002Fcore\u002Fskills\u002Fquarkus-patterns\u002FSKILL.md",[],[],"2026-11-11 15:11:14",false,"---\nname: quarkus-patterns\ndescription: Quarkus 3.x LTS architecture patterns with Camel for messaging, RESTful API design, CDI services, data access with Panache, and async processing. Use for Java Quarkus backend work with event-driven architectures.\norigin: ECC\n---\n\n# Quarkus Development Patterns\n\nQuarkus 3.x architecture and API patterns for cloud-native, event-driven services with Apache Camel.\n\n## When to Activate\n\n- Building REST APIs with JAX-RS or RESTEasy Reactive\n- Structuring resource → service → repository layers\n- Implementing event-driven patterns with Apache Camel and RabbitMQ\n- Configuring Hibernate Panache, caching, or reactive streams\n- Adding validation, exception mapping, or pagination\n- Setting up profiles for dev\u002Fstaging\u002Fproduction environments (YAML config)\n- Custom logging with LogContext and Logback\u002FLogstash encoder\n- Working with CompletableFuture for async operations\n- Implementing conditional flow processing\n- Working with GraalVM native compilation\n\n## Service Layer with Multiple Dependencies\n\n```java\n@Slf4j\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class OrderProcessingService {\n\n    private final OrderValidator orderValidator;\n    private final EventService eventService;\n    private final OrderRepository orderRepository;\n    private final FulfillmentPublisher fulfillmentPublisher;\n    private final AuditPublisher auditPublisher;\n\n    @Transactional\n    public OrderReceipt process(CreateOrderCommand command) {\n        ValidationResult validation = orderValidator.validate(command);\n        if (!validation.valid()) {\n            eventService.createErrorEvent(command, \"ORDER_REJECTED\", validation.message());\n            throw new WebApplicationException(validation.message(), Response.Status.BAD_REQUEST);\n        }\n\n        Order order = Order.from(command);\n        orderRepository.persist(order);\n\n        OrderReceipt receipt = OrderReceipt.from(order);\n        fulfillmentPublisher.publishAsync(receipt);\n        auditPublisher.publish(\"ORDER_ACCEPTED\", receipt);\n        eventService.createSuccessEvent(receipt, \"ORDER_ACCEPTED\");\n\n        log.info(\"Processed order {}\", order.id);\n        return receipt;\n    }\n}\n```\n\n**Key Patterns:**\n- `@RequiredArgsConstructor` for constructor injection via Lombok\n- `@Slf4j` for Logback logging\n- `@Transactional` on service methods that write through Panache or repositories\n- Validate input before persistence or message publication\n- Event tracking for success\u002Ferror scenarios\n- Async Camel message publishing\n\n## Custom Logging Context Pattern (Logback)\n\n```java\n@ApplicationScoped\npublic class ProcessingService {\n    \n    public void processDocument(Document doc) {\n        LogContext logContext = CustomLog.getCurrentContext();\n        try (SafeAutoCloseable ignored = CustomLog.startScope(logContext)) {\n            \u002F\u002F Add context to all log statements\n            logContext.put(\"documentId\", doc.getId().toString());\n            logContext.put(\"documentType\", doc.getType());\n            logContext.put(\"userId\", SecurityContext.getUserId());\n            \n            log.info(\"Starting document processing\");\n            \n            \u002F\u002F All logs within this scope inherit the context\n            processInternal(doc);\n            \n            log.info(\"Document processing completed\");\n        } catch (Exception e) {\n            log.error(\"Document processing failed\", e);\n            throw e;\n        }\n    }\n}\n```\n\n**Logback Configuration (logback.xml):**\n\n```xml\n\u003Cconfiguration>\n    \u003Cappender name=\"CONSOLE\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        \u003Cencoder class=\"net.logstash.logback.encoder.LogstashEncoder\">\n            \u003CincludeContext>true\u003C\u002FincludeContext>\n            \u003CincludeMdc>true\u003C\u002FincludeMdc>\n        \u003C\u002Fencoder>\n    \u003C\u002Fappender>\n    \n    \u003Clogger name=\"com.example\" level=\"INFO\"\u002F>\n    \u003Croot level=\"WARN\">\n        \u003Cappender-ref ref=\"CONSOLE\"\u002F>\n    \u003C\u002Froot>\n\u003C\u002Fconfiguration>\n```\n\n## Event Service Pattern\n\n```java\n@Slf4j\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class EventService {\n    private final EventRepository eventRepository;\n    private final ObjectMapper objectMapper;\n    \n    public void createSuccessEvent(Object payload, String eventType) {\n        Objects.requireNonNull(payload, \"Payload cannot be null\");\n        Event event = new Event();\n        event.setType(eventType);\n        event.setStatus(EventStatus.SUCCESS);\n        event.setPayload(serializePayload(payload));\n        event.setTimestamp(Instant.now());\n        \n        eventRepository.persist(event);\n        log.info(\"Success event created: {}\", eventType);\n    }\n    \n    public void createErrorEvent(Object payload, String eventType, String errorMessage) {\n        Objects.requireNonNull(payload, \"Payload cannot be null\");\n        if (errorMessage == null || errorMessage.isBlank()) {\n            throw new IllegalArgumentException(\"Error message cannot be blank\");\n        }\n        Event event = new Event();\n        event.setType(eventType);\n        event.setStatus(EventStatus.ERROR);\n        event.setErrorMessage(errorMessage);\n        event.setPayload(serializePayload(payload));\n        event.setTimestamp(Instant.now());\n        \n        eventRepository.persist(event);\n        log.error(\"Error event created: {} - {}\", eventType, errorMessage);\n    }\n    \n    private String serializePayload(Object payload) {\n        try {\n            return objectMapper.writeValueAsString(payload);\n        } catch (JsonProcessingException e) {\n            throw new IllegalStateException(\"Failed to serialize event payload\", e);\n        }\n    }\n}\n```\n\n## Camel Message Publishing (RabbitMQ)\n\n```java\n@Slf4j\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class BusinessRulesPublisher {\n    private final ProducerTemplate producerTemplate;\n    \n    public void publishSync(BusinessRulesPayload payload) {\n        producerTemplate.sendBody(\n            \"direct:business-rules-publisher\", \n            payload\n        );\n    }\n}\n```\n\n**Camel Route Configuration:**\n\n```java\n@ApplicationScoped\npublic class BusinessRulesRoute extends RouteBuilder {\n    \n    @ConfigProperty(name = \"camel.rabbitmq.queue.business-rules\")\n    String businessRulesQueue;\n    \n    @ConfigProperty(name = \"rabbitmq.host\")\n    String rabbitHost;\n    \n    @ConfigProperty(name = \"rabbitmq.port\")\n    Integer rabbitPort;\n    \n    @Override\n    public void configure() {\n        from(\"direct:business-rules-publisher\")\n            .routeId(\"business-rules-publisher\")\n            .log(\"Publishing message to RabbitMQ: ${body}\")\n            .marshal().json(JsonLibrary.Jackson)\n            .toF(\"spring-rabbitmq:%s?hostname=%s&portNumber=%d\", \n                businessRulesQueue, rabbitHost, rabbitPort);\n    }\n}\n```\n\n## Camel Direct Routes (In-Memory)\n\n```java\n@ApplicationScoped\npublic class DocumentProcessingRoute extends RouteBuilder {\n    \n    @Override\n    public void configure() {\n        \u002F\u002F Error handling\n        onException(ValidationException.class)\n            .handled(true)\n            .to(\"direct:validation-error-handler\")\n            .log(\"Validation error: ${exception.message}\");\n        \n        \u002F\u002F Main processing route\n        from(\"direct:process-document\")\n            .routeId(\"document-processing\")\n            .log(\"Processing document: ${header.documentId}\")\n            .bean(DocumentValidator.class, \"validate\")\n            .bean(DocumentTransformer.class, \"transform\")\n            .choice()\n                .when(header(\"documentType\").isEqualTo(\"INVOICE\"))\n                    .to(\"direct:process-invoice\")\n                .when(header(\"documentType\").isEqualTo(\"CREDIT_NOTE\"))\n                    .to(\"direct:process-credit-note\")\n                .otherwise()\n                    .to(\"direct:process-generic\")\n            .end();\n        \n        from(\"direct:validation-error-handler\")\n            .bean(EventService.class, \"createErrorEvent\")\n            .log(\"Validation error handled\");\n    }\n}\n```\n\n## Camel File Processing\n\n```java\n@ApplicationScoped\npublic class FileMonitoringRoute extends RouteBuilder {\n    \n    @ConfigProperty(name = \"file.input.directory\")\n    String inputDirectory;\n    \n    @ConfigProperty(name = \"file.processed.directory\")\n    String processedDirectory;\n    \n    @ConfigProperty(name = \"file.error.directory\")\n    String errorDirectory;\n    \n    @Override\n    public void configure() {\n        from(\"file:\" + inputDirectory + \"?move=\" + processedDirectory + \n             \"&moveFailed=\" + errorDirectory + \"&delay=5000\")\n            .routeId(\"file-monitor\")\n            .log(\"Processing file: ${header.CamelFileName}\")\n            .to(\"direct:process-file\");\n        \n        from(\"direct:process-file\")\n            .bean(OrderProcessingService.class, \"processFile\")\n            .log(\"File processing completed\");\n    }\n}\n```\n\n## Camel Bean Invocation\n\n```java\n@ApplicationScoped\npublic class InvoiceRoute extends RouteBuilder {\n    \n    @Override\n    public void configure() {\n        from(\"direct:invoice-validation\")\n            .bean(InvoiceFlowValidator.class, \"validateFlowWithConfig\")\n            .log(\"Validation result: ${body}\");\n        \n        from(\"direct:persist-and-publish\")\n            .bean(DocumentJobService.class, \"createDocumentAndJobEntities\")\n            .bean(BusinessRulesPublisher.class, \"publishAsync\")\n            .bean(EventService.class, \"createSuccessEvent(${body}, 'PUBLISHED')\");\n    }\n}\n```\n\n## REST API Structure\n\n```java\n@Path(\"\u002Fapi\u002Fdocuments\")\n@Produces(MediaType.APPLICATION_JSON)\n@Consumes(MediaType.APPLICATION_JSON)\n@RequiredArgsConstructor\npublic class DocumentResource {\n  private final DocumentService documentService;\n\n  @GET\n  public Response list(\n      @QueryParam(\"page\") @DefaultValue(\"0\") int page,\n      @QueryParam(\"size\") @DefaultValue(\"20\") int size) {\n    List\u003CDocument> documents = documentService.list(page, size);\n    return Response.ok(documents).build();\n  }\n\n  @POST\n  public Response create(@Valid CreateDocumentRequest request, @Context UriInfo uriInfo) {\n    Document document = documentService.create(request);\n    URI location = uriInfo.getAbsolutePathBuilder()\n        .path(String.valueOf(document.id))\n        .build();\n    return Response.created(location).entity(DocumentResponse.from(document)).build();\n  }\n\n  @GET\n  @Path(\"\u002F{id}\")\n  public Response getById(@PathParam(\"id\") Long id) {\n    return documentService.findById(id)\n        .map(DocumentResponse::from)\n        .map(Response::ok)\n        .orElse(Response.status(Response.Status.NOT_FOUND))\n        .build();\n  }\n}\n```\n\n## Repository Pattern (Panache Repository)\n\n```java\n@ApplicationScoped\npublic class DocumentRepository implements PanacheRepository\u003CDocument> {\n  \n  public List\u003CDocument> findByStatus(DocumentStatus status, int page, int size) {\n    return find(\"status = ?1 order by createdAt desc\", status)\n        .page(page, size)\n        .list();\n  }\n\n  public Optional\u003CDocument> findByReferenceNumber(String referenceNumber) {\n    return find(\"referenceNumber\", referenceNumber).firstResultOptional();\n  }\n  \n  public long countByStatusAndDate(DocumentStatus status, LocalDate date) {\n    return count(\"status = ?1 and createdAt >= ?2\", status, date.atStartOfDay());\n  }\n}\n```\n\n## Service Layer with Transactions\n\n```java\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class DocumentService {\n  private final DocumentRepository repo;\n  private final EventService eventService;\n\n  @Transactional\n  public Document create(CreateDocumentRequest request) {\n    Document document = new Document();\n    document.setReferenceNumber(request.referenceNumber());\n    document.setDescription(request.description());\n    document.setStatus(DocumentStatus.PENDING);\n    document.setCreatedAt(Instant.now());\n    \n    repo.persist(document);\n    \n    eventService.createSuccessEvent(document, \"DOCUMENT_CREATED\");\n    \n    return document;\n  }\n\n  public Optional\u003CDocument> findById(Long id) {\n    return repo.findByIdOptional(id);\n  }\n\n  public List\u003CDocument> list(int page, int size) {\n    return repo.findAll()\n        .page(page, size)\n        .list();\n  }\n}\n```\n\n## DTOs and Validation\n\n```java\npublic record CreateDocumentRequest(\n    @NotBlank @Size(max = 200) String referenceNumber,\n    @NotBlank @Size(max = 2000) String description,\n    @NotNull @FutureOrPresent Instant validUntil,\n    @NotEmpty List\u003C@NotBlank String> categories) {}\n\npublic record DocumentResponse(Long id, String referenceNumber, DocumentStatus status) {\n  public static DocumentResponse from(Document document) {\n    return new DocumentResponse(document.getId(), document.getReferenceNumber(), \n        document.getStatus());\n  }\n}\n```\n\n## Exception Mapping\n\n```java\n@Provider\npublic class ValidationExceptionMapper implements ExceptionMapper\u003CConstraintViolationException> {\n  @Override\n  public Response toResponse(ConstraintViolationException exception) {\n    String message = exception.getConstraintViolations().stream()\n        .map(cv -> cv.getPropertyPath() + \": \" + cv.getMessage())\n        .collect(Collectors.joining(\", \"));\n    \n    return Response.status(Response.Status.BAD_REQUEST)\n        .entity(Map.of(\"error\", \"validation_error\", \"message\", message))\n        .build();\n  }\n}\n\n@Provider\n@Slf4j\npublic class GenericExceptionMapper implements ExceptionMapper\u003CException> {\n\n  @Override\n  public Response toResponse(Exception exception) {\n    log.error(\"Unhandled exception\", exception);\n    return Response.status(Response.Status.INTERNAL_SERVER_ERROR)\n        .entity(Map.of(\"error\", \"internal_error\", \"message\", \"An unexpected error occurred\"))\n        .build();\n  }\n}\n```\n\n## CompletableFuture Async Operations\n\n```java\n@Slf4j\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class FileStorageService {\n    private final S3Client s3Client;\n    private final ExecutorService executorService;\n    \n    @ConfigProperty(name = \"storage.bucket-name\")\n    String bucketName;\n    \n    public CompletableFuture\u003CStoredDocumentInfo> uploadOriginalFile(\n            InputStream inputStream, \n            long size, \n            LogContext logContext,\n            InvoiceFormat format) {\n        \n        return CompletableFuture.supplyAsync(() -> {\n            try (SafeAutoCloseable ignored = CustomLog.startScope(logContext)) {\n                String path = generateStoragePath(format);\n                \n                PutObjectRequest request = PutObjectRequest.builder()\n                    .bucket(bucketName)\n                    .key(path)\n                    .contentLength(size)\n                    .build();\n                \n                s3Client.putObject(request, RequestBody.fromInputStream(inputStream, size));\n                \n                log.info(\"File uploaded to S3: {}\", path);\n                \n                return new StoredDocumentInfo(path, size, Instant.now());\n            } catch (Exception e) {\n                log.error(\"Failed to upload file to S3\", e);\n                throw new StorageException(\"Upload failed\", e);\n            }\n        }, executorService);\n    }\n}\n```\n\n## Caching\n\n```java\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class DocumentCacheService {\n  private final DocumentRepository repo;\n\n  @CacheResult(cacheName = \"document-cache\")\n  public Optional\u003CDocument> getById(@CacheKey Long id) {\n    return repo.findByIdOptional(id);\n  }\n\n  @CacheInvalidate(cacheName = \"document-cache\")\n  public void evict(@CacheKey Long id) {}\n\n  @CacheInvalidateAll(cacheName = \"document-cache\")\n  public void evictAll() {}\n}\n```\n\n## Configuration as YAML\n\n```yaml\n# application.yml\n\"%dev\":\n  quarkus:\n    datasource:\n      jdbc:\n        url: jdbc:postgresql:\u002F\u002Flocalhost:5432\u002Fdev_db\n      username: dev_user\n      password: ${DB_PASSWORD}\n    hibernate-orm:\n      database:\n        generation: drop-and-create\n  \n  rabbitmq:\n    host: localhost\n    port: 5672\n    username: ${RABBITMQ_USER}\n    password: ${RABBITMQ_PASSWORD}\n\n\"%test\":\n  quarkus:\n    datasource:\n      jdbc:\n        url: jdbc:h2:mem:test\n    hibernate-orm:\n      database:\n        generation: drop-and-create\n\n\"%prod\":\n  quarkus:\n    datasource:\n      jdbc:\n        url: ${DATABASE_URL}\n      username: ${DB_USER}\n      password: ${DB_PASSWORD}\n    hibernate-orm:\n      database:\n        generation: validate\n  \n  rabbitmq:\n    host: ${RABBITMQ_HOST}\n    port: ${RABBITMQ_PORT}\n    username: ${RABBITMQ_USER}\n    password: ${RABBITMQ_PASSWORD}\n\n# Camel configuration\ncamel:\n  rabbitmq:\n    queue:\n      business-rules: business-rules-queue\n      invoice-processing: invoice-processing-queue\n```\n\n## Health Checks\n\n```java\n@Readiness\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class DatabaseHealthCheck implements HealthCheck {\n  private final AgroalDataSource dataSource;\n\n  @Override\n  public HealthCheckResponse call() {\n    try (Connection conn = dataSource.getConnection()) {\n      boolean valid = conn.isValid(2);\n      return HealthCheckResponse.named(\"Database connection\")\n          .status(valid)\n          .build();\n    } catch (SQLException e) {\n      return HealthCheckResponse.down(\"Database connection\");\n    }\n  }\n}\n\n@Liveness\n@ApplicationScoped\npublic class CamelHealthCheck implements HealthCheck {\n  @Inject\n  CamelContext camelContext;\n\n  @Override\n  public HealthCheckResponse call() {\n    boolean isStarted = camelContext.getStatus().isStarted();\n    return HealthCheckResponse.named(\"Camel Context\")\n        .status(isStarted)\n        .build();\n  }\n}\n```\n\n## Dependencies (Maven)\n\n```xml\n\u003Cproperties>\n    \u003Cquarkus.platform.version>3.27.0\u003C\u002Fquarkus.platform.version>\n    \u003Clombok.version>1.18.42\u003C\u002Flombok.version>\n    \u003Cassertj-core.version>3.24.2\u003C\u002Fassertj-core.version>\n    \u003Cjacoco-maven-plugin.version>0.8.13\u003C\u002Fjacoco-maven-plugin.version>\n    \u003Cmaven.compiler.release>17\u003C\u002Fmaven.compiler.release>\n\u003C\u002Fproperties>\n\n\u003CdependencyManagement>\n    \u003Cdependencies>\n        \u003Cdependency>\n            \u003CgroupId>io.quarkus.platform\u003C\u002FgroupId>\n            \u003CartifactId>quarkus-bom\u003C\u002FartifactId>\n            \u003Cversion>${quarkus.platform.version}\u003C\u002Fversion>\n            \u003Ctype>pom\u003C\u002Ftype>\n            \u003Cscope>import\u003C\u002Fscope>\n        \u003C\u002Fdependency>\n        \u003Cdependency>\n            \u003CgroupId>io.quarkus.platform\u003C\u002FgroupId>\n            \u003CartifactId>quarkus-camel-bom\u003C\u002FartifactId>\n            \u003Cversion>${quarkus.platform.version}\u003C\u002Fversion>\n            \u003Ctype>pom\u003C\u002Ftype>\n            \u003Cscope>import\u003C\u002Fscope>\n        \u003C\u002Fdependency>\n    \u003C\u002Fdependencies>\n\u003C\u002FdependencyManagement>\n\n\u003Cdependencies>\n    \u003C!-- Quarkus Core -->\n    \u003Cdependency>\n        \u003CgroupId>io.quarkus\u003C\u002FgroupId>\n        \u003CartifactId>quarkus-arc\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n        \u003CgroupId>io.quarkus\u003C\u002FgroupId>\n        \u003CartifactId>quarkus-config-yaml\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \n    \u003C!-- Camel Extensions -->\n    \u003Cdependency>\n        \u003CgroupId>org.apache.camel.quarkus\u003C\u002FgroupId>\n        \u003CartifactId>camel-quarkus-spring-rabbitmq\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n        \u003CgroupId>org.apache.camel.quarkus\u003C\u002FgroupId>\n        \u003CartifactId>camel-quarkus-direct\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n        \u003CgroupId>org.apache.camel.quarkus\u003C\u002FgroupId>\n        \u003CartifactId>camel-quarkus-bean\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \n    \u003C!-- Lombok -->\n    \u003Cdependency>\n        \u003CgroupId>org.projectlombok\u003C\u002FgroupId>\n        \u003CartifactId>lombok\u003C\u002FartifactId>\n        \u003Cversion>${lombok.version}\u003C\u002Fversion>\n        \u003Cscope>provided\u003C\u002Fscope>\n    \u003C\u002Fdependency>\n    \n    \u003C!-- Logging -->\n    \u003Cdependency>\n        \u003CgroupId>io.quarkiverse.logging.logback\u003C\u002FgroupId>\n        \u003CartifactId>quarkus-logging-logback\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n        \u003CgroupId>net.logstash.logback\u003C\u002FgroupId>\n        \u003CartifactId>logstash-logback-encoder\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n\u003C\u002Fdependencies>\n```\n\n## Best Practices\n\n### Architecture\n- Use `@RequiredArgsConstructor` with Lombok for constructor injection\n- Keep service layer thin; delegate complex logic to specialized classes\n- Use Camel routes for message routing and integration patterns\n- Prefer Panache Repository pattern for data access\n\n### Event-Driven\n- Always track operations with EventService (success\u002Ferror events)\n- Use Camel `direct:` endpoints for in-memory routing\n- Use `spring-rabbitmq` component for RabbitMQ integration\n- Implement async publishing with `ProducerTemplate.asyncSendBody()`\n\n### Logging\n- Use Logback with Logstash encoder for structured logging\n- Propagate LogContext through service calls with `SafeAutoCloseable`\n- Add contextual information to LogContext for request tracing\n- Use `@Slf4j` instead of manual logger instantiation\n\n### Async Operations\n- Use CompletableFuture for non-blocking I\u002FO operations\n- Call `.join()` when you need to wait for completion\n- Handle exceptions from CompletableFuture properly\n- Pass LogContext to async operations for tracing\n\n### Configuration\n- Use YAML configuration (`quarkus-config-yaml`)\n- Profile-aware configuration for dev\u002Ftest\u002Fprod environments\n- Externalize sensitive configuration to environment variables\n- Use `@ConfigProperty` for type-safe config injection\n\n### Validation\n- Validate at resource layer with `@Valid`\n- Use Bean Validation annotations on DTOs\n- Map exceptions to proper HTTP responses with `@Provider`\n\n### Transactions\n- Use `@Transactional` on service methods that modify data\n- Keep transactions short and focused\n- Avoid calling async operations within transactions\n\n### Testing\n- Use `camel-quarkus-junit5` for route testing\n- Use AssertJ for assertions\n- Mock all external dependencies\n- Test conditional flow logic thoroughly\n\n### Quarkus-Specific\n- Stay on latest LTS version (3.x)\n- Use Quarkus dev mode for hot reload\n- Add health checks for production readiness\n- Test native compilation compatibility periodically\n","# Quarkus Development Patterns\n\nQuarkus 3.x architecture and API patterns for cloud-native, event-driven services with Apache Camel.\n\n## When to Activate\n\n- Building REST APIs with JAX-RS or RESTEasy Reactive\n- Structuring resource → service → repository layers\n- Implementing event-driven patterns with Apache Camel and RabbitMQ\n- Configuring Hibernate Panache, caching, or reactive streams\n- Adding validation, exception mapping, or pagination\n- Setting up profiles for dev\u002Fstaging\u002Fproduction environments (YAML config)\n- Custom logging with LogContext and Logback\u002FLogstash encoder\n- Working with CompletableFuture for async operations\n- Implementing conditional flow processing\n- Working with GraalVM native compilation\n\n## Service Layer with Multiple Dependencies\n\n```java\n@Slf4j\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class OrderProcessingService {\n\n    private final OrderValidator orderValidator;\n    private final EventService eventService;\n    private final OrderRepository orderRepository;\n    private final FulfillmentPublisher fulfillmentPublisher;\n    private final AuditPublisher auditPublisher;\n\n    @Transactional\n    public OrderReceipt process(CreateOrderCommand command) {\n        ValidationResult validation = orderValidator.validate(command);\n        if (!validation.valid()) {\n            eventService.createErrorEvent(command, \"ORDER_REJECTED\", validation.message());\n            throw new WebApplicationException(validation.message(), Response.Status.BAD_REQUEST);\n        }\n\n        Order order = Order.from(command);\n        orderRepository.persist(order);\n\n        OrderReceipt receipt = OrderReceipt.from(order);\n        fulfillmentPublisher.publishAsync(receipt);\n        auditPublisher.publish(\"ORDER_ACCEPTED\", receipt);\n        eventService.createSuccessEvent(receipt, \"ORDER_ACCEPTED\");\n\n        log.info(\"Processed order {}\", order.id);\n        return receipt;\n    }\n}\n```\n\n**Key Patterns:**\n- `@RequiredArgsConstructor` for constructor injection via Lombok\n- `@Slf4j` for Logback logging\n- `@Transactional` on service methods that write through Panache or repositories\n- Validate input before persistence or message publication\n- Event tracking for success\u002Ferror scenarios\n- Async Camel message publishing\n\n## Custom Logging Context Pattern (Logback)\n\n```java\n@ApplicationScoped\npublic class ProcessingService {\n    \n    public void processDocument(Document doc) {\n        LogContext logContext = CustomLog.getCurrentContext();\n        try (SafeAutoCloseable ignored = CustomLog.startScope(logContext)) {\n            \u002F\u002F Add context to all log statements\n            logContext.put(\"documentId\", doc.getId().toString());\n            logContext.put(\"documentType\", doc.getType());\n            logContext.put(\"userId\", SecurityContext.getUserId());\n            \n            log.info(\"Starting document processing\");\n            \n            \u002F\u002F All logs within this scope inherit the context\n            processInternal(doc);\n            \n            log.info(\"Document processing completed\");\n        } catch (Exception e) {\n            log.error(\"Document processing failed\", e);\n            throw e;\n        }\n    }\n}\n```\n\n**Logback Configuration (logback.xml):**\n\n```xml\n\u003Cconfiguration>\n    \u003Cappender name=\"CONSOLE\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        \u003Cencoder class=\"net.logstash.logback.encoder.LogstashEncoder\">\n            \u003CincludeContext>true\u003C\u002FincludeContext>\n            \u003CincludeMdc>true\u003C\u002FincludeMdc>\n        \u003C\u002Fencoder>\n    \u003C\u002Fappender>\n    \n    \u003Clogger name=\"com.example\" level=\"INFO\"\u002F>\n    \u003Croot level=\"WARN\">\n        \u003Cappender-ref ref=\"CONSOLE\"\u002F>\n    \u003C\u002Froot>\n\u003C\u002Fconfiguration>\n```\n\n## Event Service Pattern\n\n```java\n@Slf4j\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class EventService {\n    private final EventRepository eventRepository;\n    private final ObjectMapper objectMapper;\n    \n    public void createSuccessEvent(Object payload, String eventType) {\n        Objects.requireNonNull(payload, \"Payload cannot be null\");\n        Event event = new Event();\n        event.setType(eventType);\n        event.setStatus(EventStatus.SUCCESS);\n        event.setPayload(serializePayload(payload));\n        event.setTimestamp(Instant.now());\n        \n        eventRepository.persist(event);\n        log.info(\"Success event created: {}\", eventType);\n    }\n    \n    public void createErrorEvent(Object payload, String eventType, String errorMessage) {\n        Objects.requireNonNull(payload, \"Payload cannot be null\");\n        if (errorMessage == null || errorMessage.isBlank()) {\n            throw new IllegalArgumentException(\"Error message cannot be blank\");\n        }\n        Event event = new Event();\n        event.setType(eventType);\n        event.setStatus(EventStatus.ERROR);\n        event.setErrorMessage(errorMessage);\n        event.setPayload(serializePayload(payload));\n        event.setTimestamp(Instant.now());\n        \n        eventRepository.persist(event);\n        log.error(\"Error event created: {} - {}\", eventType, errorMessage);\n    }\n    \n    private String serializePayload(Object payload) {\n        try {\n            return objectMapper.writeValueAsString(payload);\n        } catch (JsonProcessingException e) {\n            throw new IllegalStateException(\"Failed to serialize event payload\", e);\n        }\n    }\n}\n```\n\n## Camel Message Publishing (RabbitMQ)\n\n```java\n@Slf4j\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class BusinessRulesPublisher {\n    private final ProducerTemplate producerTemplate;\n    \n    public void publishSync(BusinessRulesPayload payload) {\n        producerTemplate.sendBody(\n            \"direct:business-rules-publisher\", \n            payload\n        );\n    }\n}\n```\n\n**Camel Route Configuration:**\n\n```java\n@ApplicationScoped\npublic class BusinessRulesRoute extends RouteBuilder {\n    \n    @ConfigProperty(name = \"camel.rabbitmq.queue.business-rules\")\n    String businessRulesQueue;\n    \n    @ConfigProperty(name = \"rabbitmq.host\")\n    String rabbitHost;\n    \n    @ConfigProperty(name = \"rabbitmq.port\")\n    Integer rabbitPort;\n    \n    @Override\n    public void configure() {\n        from(\"direct:business-rules-publisher\")\n            .routeId(\"business-rules-publisher\")\n            .log(\"Publishing message to RabbitMQ: ${body}\")\n            .marshal().json(JsonLibrary.Jackson)\n            .toF(\"spring-rabbitmq:%s?hostname=%s&portNumber=%d\", \n                businessRulesQueue, rabbitHost, rabbitPort);\n    }\n}\n```\n\n## Camel Direct Routes (In-Memory)\n\n```java\n@ApplicationScoped\npublic class DocumentProcessingRoute extends RouteBuilder {\n    \n    @Override\n    public void configure() {\n        \u002F\u002F Error handling\n        onException(ValidationException.class)\n            .handled(true)\n            .to(\"direct:validation-error-handler\")\n            .log(\"Validation error: ${exception.message}\");\n        \n        \u002F\u002F Main processing route\n        from(\"direct:process-document\")\n            .routeId(\"document-processing\")\n            .log(\"Processing document: ${header.documentId}\")\n            .bean(DocumentValidator.class, \"validate\")\n            .bean(DocumentTransformer.class, \"transform\")\n            .choice()\n                .when(header(\"documentType\").isEqualTo(\"INVOICE\"))\n                    .to(\"direct:process-invoice\")\n                .when(header(\"documentType\").isEqualTo(\"CREDIT_NOTE\"))\n                    .to(\"direct:process-credit-note\")\n                .otherwise()\n                    .to(\"direct:process-generic\")\n            .end();\n        \n        from(\"direct:validation-error-handler\")\n            .bean(EventService.class, \"createErrorEvent\")\n            .log(\"Validation error handled\");\n    }\n}\n```\n\n## Camel File Processing\n\n```java\n@ApplicationScoped\npublic class FileMonitoringRoute extends RouteBuilder {\n    \n    @ConfigProperty(name = \"file.input.directory\")\n    String inputDirectory;\n    \n    @ConfigProperty(name = \"file.processed.directory\")\n    String processedDirectory;\n    \n    @ConfigProperty(name = \"file.error.directory\")\n    String errorDirectory;\n    \n    @Override\n    public void configure() {\n        from(\"file:\" + inputDirectory + \"?move=\" + processedDirectory + \n             \"&moveFailed=\" + errorDirectory + \"&delay=5000\")\n            .routeId(\"file-monitor\")\n            .log(\"Processing file: ${header.CamelFileName}\")\n            .to(\"direct:process-file\");\n        \n        from(\"direct:process-file\")\n            .bean(OrderProcessingService.class, \"processFile\")\n            .log(\"File processing completed\");\n    }\n}\n```\n\n## Camel Bean Invocation\n\n```java\n@ApplicationScoped\npublic class InvoiceRoute extends RouteBuilder {\n    \n    @Override\n    public void configure() {\n        from(\"direct:invoice-validation\")\n            .bean(InvoiceFlowValidator.class, \"validateFlowWithConfig\")\n            .log(\"Validation result: ${body}\");\n        \n        from(\"direct:persist-and-publish\")\n            .bean(DocumentJobService.class, \"createDocumentAndJobEntities\")\n            .bean(BusinessRulesPublisher.class, \"publishAsync\")\n            .bean(EventService.class, \"createSuccessEvent(${body}, 'PUBLISHED')\");\n    }\n}\n```\n\n## REST API Structure\n\n```java\n@Path(\"\u002Fapi\u002Fdocuments\")\n@Produces(MediaType.APPLICATION_JSON)\n@Consumes(MediaType.APPLICATION_JSON)\n@RequiredArgsConstructor\npublic class DocumentResource {\n  private final DocumentService documentService;\n\n  @GET\n  public Response list(\n      @QueryParam(\"page\") @DefaultValue(\"0\") int page,\n      @QueryParam(\"size\") @DefaultValue(\"20\") int size) {\n    List\u003CDocument> documents = documentService.list(page, size);\n    return Response.ok(documents).build();\n  }\n\n  @POST\n  public Response create(@Valid CreateDocumentRequest request, @Context UriInfo uriInfo) {\n    Document document = documentService.create(request);\n    URI location = uriInfo.getAbsolutePathBuilder()\n        .path(String.valueOf(document.id))\n        .build();\n    return Response.created(location).entity(DocumentResponse.from(document)).build();\n  }\n\n  @GET\n  @Path(\"\u002F{id}\")\n  public Response getById(@PathParam(\"id\") Long id) {\n    return documentService.findById(id)\n        .map(DocumentResponse::from)\n        .map(Response::ok)\n        .orElse(Response.status(Response.Status.NOT_FOUND))\n        .build();\n  }\n}\n```\n\n## Repository Pattern (Panache Repository)\n\n```java\n@ApplicationScoped\npublic class DocumentRepository implements PanacheRepository\u003CDocument> {\n  \n  public List\u003CDocument> findByStatus(DocumentStatus status, int page, int size) {\n    return find(\"status = ?1 order by createdAt desc\", status)\n        .page(page, size)\n        .list();\n  }\n\n  public Optional\u003CDocument> findByReferenceNumber(String referenceNumber) {\n    return find(\"referenceNumber\", referenceNumber).firstResultOptional();\n  }\n  \n  public long countByStatusAndDate(DocumentStatus status, LocalDate date) {\n    return count(\"status = ?1 and createdAt >= ?2\", status, date.atStartOfDay());\n  }\n}\n```\n\n## Service Layer with Transactions\n\n```java\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class DocumentService {\n  private final DocumentRepository repo;\n  private final EventService eventService;\n\n  @Transactional\n  public Document create(CreateDocumentRequest request) {\n    Document document = new Document();\n    document.setReferenceNumber(request.referenceNumber());\n    document.setDescription(request.description());\n    document.setStatus(DocumentStatus.PENDING);\n    document.setCreatedAt(Instant.now());\n    \n    repo.persist(document);\n    \n    eventService.createSuccessEvent(document, \"DOCUMENT_CREATED\");\n    \n    return document;\n  }\n\n  public Optional\u003CDocument> findById(Long id) {\n    return repo.findByIdOptional(id);\n  }\n\n  public List\u003CDocument> list(int page, int size) {\n    return repo.findAll()\n        .page(page, size)\n        .list();\n  }\n}\n```\n\n## DTOs and Validation\n\n```java\npublic record CreateDocumentRequest(\n    @NotBlank @Size(max = 200) String referenceNumber,\n    @NotBlank @Size(max = 2000) String description,\n    @NotNull @FutureOrPresent Instant validUntil,\n    @NotEmpty List\u003C@NotBlank String> categories) {}\n\npublic record DocumentResponse(Long id, String referenceNumber, DocumentStatus status) {\n  public static DocumentResponse from(Document document) {\n    return new DocumentResponse(document.getId(), document.getReferenceNumber(), \n        document.getStatus());\n  }\n}\n```\n\n## Exception Mapping\n\n```java\n@Provider\npublic class ValidationExceptionMapper implements ExceptionMapper\u003CConstraintViolationException> {\n  @Override\n  public Response toResponse(ConstraintViolationException exception) {\n    String message = exception.getConstraintViolations().stream()\n        .map(cv -> cv.getPropertyPath() + \": \" + cv.getMessage())\n        .collect(Collectors.joining(\", \"));\n    \n    return Response.status(Response.Status.BAD_REQUEST)\n        .entity(Map.of(\"error\", \"validation_error\", \"message\", message))\n        .build();\n  }\n}\n\n@Provider\n@Slf4j\npublic class GenericExceptionMapper implements ExceptionMapper\u003CException> {\n\n  @Override\n  public Response toResponse(Exception exception) {\n    log.error(\"Unhandled exception\", exception);\n    return Response.status(Response.Status.INTERNAL_SERVER_ERROR)\n        .entity(Map.of(\"error\", \"internal_error\", \"message\", \"An unexpected error occurred\"))\n        .build();\n  }\n}\n```\n\n## CompletableFuture Async Operations\n\n```java\n@Slf4j\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class FileStorageService {\n    private final S3Client s3Client;\n    private final ExecutorService executorService;\n    \n    @ConfigProperty(name = \"storage.bucket-name\")\n    String bucketName;\n    \n    public CompletableFuture\u003CStoredDocumentInfo> uploadOriginalFile(\n            InputStream inputStream, \n            long size, \n            LogContext logContext,\n            InvoiceFormat format) {\n        \n        return CompletableFuture.supplyAsync(() -> {\n            try (SafeAutoCloseable ignored = CustomLog.startScope(logContext)) {\n                String path = generateStoragePath(format);\n                \n                PutObjectRequest request = PutObjectRequest.builder()\n                    .bucket(bucketName)\n                    .key(path)\n                    .contentLength(size)\n                    .build();\n                \n                s3Client.putObject(request, RequestBody.fromInputStream(inputStream, size));\n                \n                log.info(\"File uploaded to S3: {}\", path);\n                \n                return new StoredDocumentInfo(path, size, Instant.now());\n            } catch (Exception e) {\n                log.error(\"Failed to upload file to S3\", e);\n                throw new StorageException(\"Upload failed\", e);\n            }\n        }, executorService);\n    }\n}\n```\n\n## Caching\n\n```java\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class DocumentCacheService {\n  private final DocumentRepository repo;\n\n  @CacheResult(cacheName = \"document-cache\")\n  public Optional\u003CDocument> getById(@CacheKey Long id) {\n    return repo.findByIdOptional(id);\n  }\n\n  @CacheInvalidate(cacheName = \"document-cache\")\n  public void evict(@CacheKey Long id) {}\n\n  @CacheInvalidateAll(cacheName = \"document-cache\")\n  public void evictAll() {}\n}\n```\n\n## Configuration as YAML\n\n```yaml\n# application.yml\n\"%dev\":\n  quarkus:\n    datasource:\n      jdbc:\n        url: jdbc:postgresql:\u002F\u002Flocalhost:5432\u002Fdev_db\n      username: dev_user\n      password: ${DB_PASSWORD}\n    hibernate-orm:\n      database:\n        generation: drop-and-create\n  \n  rabbitmq:\n    host: localhost\n    port: 5672\n    username: ${RABBITMQ_USER}\n    password: ${RABBITMQ_PASSWORD}\n\n\"%test\":\n  quarkus:\n    datasource:\n      jdbc:\n        url: jdbc:h2:mem:test\n    hibernate-orm:\n      database:\n        generation: drop-and-create\n\n\"%prod\":\n  quarkus:\n    datasource:\n      jdbc:\n        url: ${DATABASE_URL}\n      username: ${DB_USER}\n      password: ${DB_PASSWORD}\n    hibernate-orm:\n      database:\n        generation: validate\n  \n  rabbitmq:\n    host: ${RABBITMQ_HOST}\n    port: ${RABBITMQ_PORT}\n    username: ${RABBITMQ_USER}\n    password: ${RABBITMQ_PASSWORD}\n\n# Camel configuration\ncamel:\n  rabbitmq:\n    queue:\n      business-rules: business-rules-queue\n      invoice-processing: invoice-processing-queue\n```\n\n## Health Checks\n\n```java\n@Readiness\n@ApplicationScoped\n@RequiredArgsConstructor\npublic class DatabaseHealthCheck implements HealthCheck {\n  private final AgroalDataSource dataSource;\n\n  @Override\n  public HealthCheckResponse call() {\n    try (Connection conn = dataSource.getConnection()) {\n      boolean valid = conn.isValid(2);\n      return HealthCheckResponse.named(\"Database connection\")\n          .status(valid)\n          .build();\n    } catch (SQLException e) {\n      return HealthCheckResponse.down(\"Database connection\");\n    }\n  }\n}\n\n@Liveness\n@ApplicationScoped\npublic class CamelHealthCheck implements HealthCheck {\n  @Inject\n  CamelContext camelContext;\n\n  @Override\n  public HealthCheckResponse call() {\n    boolean isStarted = camelContext.getStatus().isStarted();\n    return HealthCheckResponse.named(\"Camel Context\")\n        .status(isStarted)\n        .build();\n  }\n}\n```\n\n## Dependencies (Maven)\n\n```xml\n\u003Cproperties>\n    \u003Cquarkus.platform.version>3.27.0\u003C\u002Fquarkus.platform.version>\n    \u003Clombok.version>1.18.42\u003C\u002Flombok.version>\n    \u003Cassertj-core.version>3.24.2\u003C\u002Fassertj-core.version>\n    \u003Cjacoco-maven-plugin.version>0.8.13\u003C\u002Fjacoco-maven-plugin.version>\n    \u003Cmaven.compiler.release>17\u003C\u002Fmaven.compiler.release>\n\u003C\u002Fproperties>\n\n\u003CdependencyManagement>\n    \u003Cdependencies>\n        \u003Cdependency>\n            \u003CgroupId>io.quarkus.platform\u003C\u002FgroupId>\n            \u003CartifactId>quarkus-bom\u003C\u002FartifactId>\n            \u003Cversion>${quarkus.platform.version}\u003C\u002Fversion>\n            \u003Ctype>pom\u003C\u002Ftype>\n            \u003Cscope>import\u003C\u002Fscope>\n        \u003C\u002Fdependency>\n        \u003Cdependency>\n            \u003CgroupId>io.quarkus.platform\u003C\u002FgroupId>\n            \u003CartifactId>quarkus-camel-bom\u003C\u002FartifactId>\n            \u003Cversion>${quarkus.platform.version}\u003C\u002Fversion>\n            \u003Ctype>pom\u003C\u002Ftype>\n            \u003Cscope>import\u003C\u002Fscope>\n        \u003C\u002Fdependency>\n    \u003C\u002Fdependencies>\n\u003C\u002FdependencyManagement>\n\n\u003Cdependencies>\n    \u003C!-- Quarkus Core -->\n    \u003Cdependency>\n        \u003CgroupId>io.quarkus\u003C\u002FgroupId>\n        \u003CartifactId>quarkus-arc\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n        \u003CgroupId>io.quarkus\u003C\u002FgroupId>\n        \u003CartifactId>quarkus-config-yaml\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \n    \u003C!-- Camel Extensions -->\n    \u003Cdependency>\n        \u003CgroupId>org.apache.camel.quarkus\u003C\u002FgroupId>\n        \u003CartifactId>camel-quarkus-spring-rabbitmq\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n        \u003CgroupId>org.apache.camel.quarkus\u003C\u002FgroupId>\n        \u003CartifactId>camel-quarkus-direct\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n        \u003CgroupId>org.apache.camel.quarkus\u003C\u002FgroupId>\n        \u003CartifactId>camel-quarkus-bean\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \n    \u003C!-- Lombok -->\n    \u003Cdependency>\n        \u003CgroupId>org.projectlombok\u003C\u002FgroupId>\n        \u003CartifactId>lombok\u003C\u002FartifactId>\n        \u003Cversion>${lombok.version}\u003C\u002Fversion>\n        \u003Cscope>provided\u003C\u002Fscope>\n    \u003C\u002Fdependency>\n    \n    \u003C!-- Logging -->\n    \u003Cdependency>\n        \u003CgroupId>io.quarkiverse.logging.logback\u003C\u002FgroupId>\n        \u003CartifactId>quarkus-logging-logback\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n        \u003CgroupId>net.logstash.logback\u003C\u002FgroupId>\n        \u003CartifactId>logstash-logback-encoder\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n\u003C\u002Fdependencies>\n```\n\n## Best Practices\n\n### Architecture\n- Use `@RequiredArgsConstructor` with Lombok for constructor injection\n- Keep service layer thin; delegate complex logic to specialized classes\n- Use Camel routes for message routing and integration patterns\n- Prefer Panache Repository pattern for data access\n\n### Event-Driven\n- Always track operations with EventService (success\u002Ferror events)\n- Use Camel `direct:` endpoints for in-memory routing\n- Use `spring-rabbitmq` component for RabbitMQ integration\n- Implement async publishing with `ProducerTemplate.asyncSendBody()`\n\n### Logging\n- Use Logback with Logstash encoder for structured logging\n- Propagate LogContext through service calls with `SafeAutoCloseable`\n- Add contextual information to LogContext for request tracing\n- Use `@Slf4j` instead of manual logger instantiation\n\n### Async Operations\n- Use CompletableFuture for non-blocking I\u002FO operations\n- Call `.join()` when you need to wait for completion\n- Handle exceptions from CompletableFuture properly\n- Pass LogContext to async operations for tracing\n\n### Configuration\n- Use YAML configuration (`quarkus-config-yaml`)\n- Profile-aware configuration for dev\u002Ftest\u002Fprod environments\n- Externalize sensitive configuration to environment variables\n- Use `@ConfigProperty` for type-safe config injection\n\n### Validation\n- Validate at resource layer with `@Valid`\n- Use Bean Validation annotations on DTOs\n- Map exceptions to proper HTTP responses with `@Provider`\n\n### Transactions\n- Use `@Transactional` on service methods that modify data\n- Keep transactions short and focused\n- Avoid calling async operations within transactions\n\n### Testing\n- Use `camel-quarkus-junit5` for route testing\n- Use AssertJ for assertions\n- Mock all external dependencies\n- Test conditional flow logic thoroughly\n\n### Quarkus-Specific\n- Stay on latest LTS version (3.x)\n- Use Quarkus dev mode for hot reload\n- Add health checks for production readiness\n- Test native compilation compatibility periodically\n",{"name":5,"origin":24,"description":7},"ECC","main","481dcd7dd2e288b9d627a2bd017db70e64e6c6fa","core\u002Fskills\u002Fquarkus-patterns",1,"https:\u002F\u002Fgithub.com\u002FHoronomos-laps\u002FYana-AI","https:\u002F\u002Fyana.vutam.link\u002F","https:\u002F\u002Fgithub.com\u002FHoronomos-laps","https:\u002F\u002Fyana.vutam.link","An open-source governed runtime & execution environment for multi-agent AI systems.","2026-11-11 23:56:26",{"source":8,"skillName":5,"commands":36,"prompt":46,"zipAvailable":47},[37,40,43],{"tool":38,"command":39},"npx","npx skills add Horonomos-laps\u002FYana-AI --skill quarkus-patterns",{"tool":41,"command":42},"bunx","bunx skills add Horonomos-laps\u002FYana-AI --skill quarkus-patterns",{"tool":44,"command":45},"pnpm","pnpm dlx skills add Horonomos-laps\u002FYana-AI --skill quarkus-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FHoronomos-laps\u002FYana-AI\u002Fblob\u002Fmain\u002Fcore\u002Fskills\u002Fquarkus-patterns\u002FSKILL.md",true,[],[50,58,65,73,81,89],{"skillNo":51,"name":52,"nameZh":6,"description":53,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":54,"licenseFileUrl":6,"sourceHtmlUrl":55,"categories":56,"keywords":57,"publishedAt":19},"01M735GKET5YVYKAY62W2P5YXB","openai--sentry--sentry","Use when the user asks to inspect Sentry issues or events, summarize recent production errors, or pull basic Sentry health data via the Sentry API; perform read-only queries with the bundled script and require `SENTRY_AUTH_TOKEN`.","MIT","https:\u002F\u002Fgithub.com\u002FHoronomos-laps\u002FYana-AI\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fopenai--sentry--sentry\u002FSKILL.md",[],[],{"skillNo":59,"name":60,"nameZh":6,"description":61,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":62,"categories":63,"keywords":64,"publishedAt":19},"01M73DCAP83T17HY7SMGK7MGFE","ito-basket-compare","Compare Itô prediction-market baskets against a user's knowledge base, portfolio notes, financial context, watchlist, or research thesis. Use for read-only basket comparison and gap analysis without investment advice or live trading.","https:\u002F\u002Fgithub.com\u002FHoronomos-laps\u002FYana-AI\u002Fblob\u002Fmain\u002Fcore\u002Fskills\u002Fito-basket-compare\u002FSKILL.md",[],[],{"skillNo":66,"name":67,"nameZh":6,"description":68,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":69,"sourceHtmlUrl":70,"categories":71,"keywords":72,"publishedAt":19},"01M734CYEMZFDR3KH6SW0JP8TD","implementing-network-traffic-baselining","Build network traffic baselines from NetFlow\u002FIPFIX data using Python pandas for statistical analysis, z-score anomaly detection, and hourly\u002Fdaily traffic pattern profiling","https:\u002F\u002Fgithub.com\u002Fyanacuti1121\u002FYana-AI\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fimplementing-network-traffic-baselining\u002FLICENSE","https:\u002F\u002Fgithub.com\u002FHoronomos-laps\u002FYana-AI\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fimplementing-network-traffic-baselining\u002FSKILL.md",[],[],{"skillNo":74,"name":75,"nameZh":6,"description":76,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":77,"sourceHtmlUrl":78,"categories":79,"keywords":80,"publishedAt":19},"01M73ASZ6NJRJM44Z2P84NGQ3Q","detecting-evasion-techniques-in-endpoint-logs","Detects defense evasion techniques used by adversaries in endpoint logs including log tampering, timestomping, process injection, and security tool disabling. Use when investigating suspicious endpoint behavior, building detection rules for evasion tactics, or conducting threat hunting for stealthy adversary activity. Activates for requests involving evasion detection, defense evasion analysis, log tampering detection, or MITRE ATT&CK TA0005.","https:\u002F\u002Fgithub.com\u002Fyanacuti1121\u002FYana-AI\u002Fblob\u002Fmain\u002Fcore\u002Fskills\u002Fdetecting-evasion-techniques-in-endpoint-logs\u002FLICENSE","https:\u002F\u002Fgithub.com\u002FHoronomos-laps\u002FYana-AI\u002Fblob\u002Fmain\u002Fcore\u002Fskills\u002Fdetecting-evasion-techniques-in-endpoint-logs\u002FSKILL.md",[],[],{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":85,"sourceHtmlUrl":86,"categories":87,"keywords":88,"publishedAt":19},"01M734AFNXD06Z78QRK0VKGT7Q","implementing-microsegmentation-with-guardicore","Implementing microsegmentation using Akamai Guardicore Segmentation to map application dependencies, create granular network policies, visualize east-west traffic flows, and enforce least-privilege communication between workloads across data centers and cloud.","https:\u002F\u002Fgithub.com\u002Fyanacuti1121\u002FYana-AI\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fimplementing-microsegmentation-with-guardicore\u002FLICENSE","https:\u002F\u002Fgithub.com\u002FHoronomos-laps\u002FYana-AI\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fimplementing-microsegmentation-with-guardicore\u002FSKILL.md",[],[],{"skillNo":90,"name":91,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":94,"publishedAt":19},"01M736TK27QMCXK0DVCH25SJN5","ramdisk-tmpfs-patterns","https:\u002F\u002Fgithub.com\u002FHoronomos-laps\u002FYana-AI\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Framdisk-tmpfs-patterns\u002FSKILL.md",[],[]]