Skip to content

Jafly. Starter Core

Starter Core

Assemble core infrastructure conventions for WebClient, actuator, logging, configuration, and service discovery.

Use this starter at the infrastructure foundation of a service. Enable optional integrations with their own settings rather than assuming discovery or remote configuration is required. The property classes below separate client, propagation, registry, logging, and actuator concerns.

Maven artifact Packaging Source project
org.fireflyframework:fireflyframework-starter-core jar modules/starter-core

Part of Team-wide architecture.

Broker-backed messaging comes from the separate EDA transport adapters. This starter supplies no KCL consumer or AWS Glue schema-registry integration. Applications that add those SDKs must select and qualify their own SDK and protobuf combination.

In the onboarding service

A larger onboarding service may adopt this bundle for shared HTTP-client and operational settings. Compare those dependencies with the tutorial's small CQRS/WebFlux set before adding the starter.

Add the component

Installation and version availability explains source builds and published releases.

<dependency>
    <groupId>org.fireflyframework</groupId>
    <artifactId>fireflyframework-starter-core</artifactId>
    <version>26.10.20-SNAPSHOT</version>
</dependency>

Quick start

The injection examples use Lombok @RequiredArgsConstructor. Add its provided dependency and annotation processor as described in Constructor injection.

The Java examples in this section are API fragments for application code. Use the stated imports and supply the application-owned collaborators described alongside them.

Add the dependency and the auto-configurations do the rest. The listed auto-configurations register its beans. A resilient, transaction-aware WebClient (and WebClientTemplate) are available for injection:

import lombok.RequiredArgsConstructor;
import org.fireflyframework.core.web.client.WebClientTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Service
@RequiredArgsConstructor
public class CustomerGateway {

    private final WebClientTemplate webClient;



    // Inbound headers (minus the configured skip-list) are forwarded downstream,
    // and X-Transaction-Id is propagated automatically.
    public Mono<Customer> fetch(String baseUrl, String id, ServerWebExchange exchange) {
        return webClient.get(baseUrl, "/customers/" + id, Customer.class, exchange);
    }
}

Prefer the raw WebClient? The auto-configured bean is already resilience-wrapped (circuit breaker, retry, timeout, bulkhead, metrics):

import lombok.RequiredArgsConstructor;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@Service
@RequiredArgsConstructor
public class InventoryClient {

    private final WebClient webClient; // resilient + transaction-aware by default



    public Mono<Stock> stock(String sku) {
        return webClient.get()
                .uri("https://inventory.internal/stock/{sku}", sku)
                .retrieve()
                .bodyToMono(Stock.class);
    }
}

Enable optional infrastructure features through configuration (all opt-in by default):

firefly:
  cloud:
    config:
      enabled: true
      uri: http://config-server:8888
  service:
    registry:
      enabled: true
      type: eureka

Configuration and wiring

The firefly.actuator namespace is bound by ActuatorProperties.java. Nested configuration is declared in the linked class. Defaults are the field initializers.

Setting Java type Source default
firefly.actuator.endpoints Endpoints new Endpoints()
firefly.actuator.metrics Metrics new Metrics()
firefly.actuator.tracing Tracing new Tracing()
firefly.actuator.health Health new Health()
firefly.actuator.extended-metrics ExtendedMetrics new ExtendedMetrics()

The spring.banner namespace is bound by FireflyBannerAutoConfiguration.java. Nested configuration is declared in the linked class. Defaults are the field initializers.

Setting Java type Source default

The firefly.webclient.propagation namespace is bound by HeaderPropagationProperties.java. Nested configuration is declared in the linked class. Defaults are the field initializers.

Setting Java type Source default
firefly.webclient.propagation.enabled boolean true
firefly.webclient.propagation.allowed-headers List<String> nested/default initializer; see source

The firefly.webclient namespace is bound by WebClientProperties.java. Nested configuration is declared in the linked class. Defaults are the field initializers.

Setting Java type Source default
firefly.webclient.enabled boolean true
firefly.webclient.skip-headers List<String> not initialized
firefly.webclient.connect-timeout-ms int 5000
firefly.webclient.read-timeout-ms int 10000
firefly.webclient.write-timeout-ms int 10000
firefly.webclient.max-in-memory-size int 16777216
firefly.webclient.ssl Ssl new Ssl()
firefly.webclient.proxy Proxy new Proxy()
firefly.webclient.connection-pool ConnectionPool new ConnectionPool()
firefly.webclient.http2 Http2 new Http2()
firefly.webclient.codec Codec new Codec()

The firefly.cloud.config namespace is bound by CloudConfigProperties.java. Nested configuration is declared in the linked class. Defaults are the field initializers.

Setting Java type Source default
firefly.cloud.config.enabled boolean false
firefly.cloud.config.uri String "http://localhost:8888"
firefly.cloud.config.name String ""
firefly.cloud.config.profile String ""
firefly.cloud.config.label String "main"
firefly.cloud.config.fail-fast boolean false
firefly.cloud.config.timeout-ms int 5000
firefly.cloud.config.retry boolean true
firefly.cloud.config.max-retries int 6
firefly.cloud.config.initial-retry-interval-ms int 1000
firefly.cloud.config.max-retry-interval-ms int 2000
firefly.cloud.config.retry-multiplier double 1.1
firefly.cloud.config.refresh-enabled boolean true

The firefly.service.registry namespace is bound by ServiceRegistryProperties.java. Nested configuration is declared in the linked class. Defaults are the field initializers.

Setting Java type Source default
firefly.service.registry.enabled boolean false
firefly.service.registry.type RegistryType RegistryType.EUREKA
firefly.service.registry.eureka EurekaConfig new EurekaConfig()
firefly.service.registry.consul ConsulConfig new ConsulConfig()

The firefly.logging namespace is bound by LoggingProperties.java. Nested configuration is declared in the linked class. Defaults are the field initializers.

Setting Java type Source default
firefly.logging.json Json new Json()
firefly.logging.performance Performance new Performance()
firefly.logging.cache Cache new Cache()

The firefly.webclient.resilience namespace is bound by WebClientResilienceProperties.java. Nested configuration is declared in the linked class. Defaults are the field initializers.

Setting Java type Source default
firefly.webclient.resilience.circuit-breaker CircuitBreakerProperties new CircuitBreakerProperties()
firefly.webclient.resilience.retry RetryProperties new RetryProperties()
firefly.webclient.resilience.timeout TimeoutProperties new TimeoutProperties()
firefly.webclient.resilience.bulkhead BulkheadProperties new BulkheadProperties()
firefly.webclient.resilience.enabled boolean true

Property-based wiring conditions found in this module:

Public API and extension points

Type Contract and responsibility
WebClientTemplate Defines addHeaders, post, put, delete operations.
ResilientWebClient A decorator for WebClient that adds resilience patterns like circuit breaker, retry, timeout, bulkhead, and metrics.
HeaderPropagationProperties Configuration for inbound-to-outbound HTTP header propagation.
CloudConfigProperties Configuration properties for Spring Cloud Config.
ActuatorProperties Configuration properties for Spring Boot Actuator.
Related component Why it belongs nearby
Kernel Share a consistent exception vocabulary across application, domain, and infrastructure boundaries.
Common EDA Library Publish and consume events through a common envelope and transport-independent APIs.
Observability Provide a common metrics, tracing, health, and context-propagation foundation for framework components.
Common CQRS Library Separate commands and queries with reactive dispatch, execution context, validation, and authorization hooks.
: Orchestration Coordinate workflows, compensating sagas, and try-confirm-cancel operations in a reactive application.

Build and test

Use Java 25. From the repository root, build this component with its required dependencies:

git clone https://github.com/fireflyframework/fireflyframework-jafly.git
cd fireflyframework-jafly
./mvnw -pl :fireflyframework-starter-core -am verify
./mvnw -pl :fireflyframework-starter-core -am install

verify runs the selected projects' tests. install makes the current build available in your local Maven repository.

Representative test sources:

Test fixture

The shouldLoadHttpClientMetricsConfig test demonstrates one concrete behavior. Excerpt from EnhancedActuatorAutoConfigurationTest.java. The test class supplies its fixtures and imports.

@Test
void shouldLoadHttpClientMetricsConfig() {
    contextRunner
            .withPropertyValues("firefly.actuator.metrics.http.client.enabled=true")
            .run(context -> {
                assertThat(context).hasSingleBean(HttpClientMetricsConfig.class);

                // Verify HTTP client components are present
                assertThat(context).hasBean("httpClientHealthIndicator");
                assertThat(context).hasBean("restTemplateMetricsCustomizer");

                assertThat(context.getBean("httpClientHealthIndicator")).isInstanceOf(HealthIndicator.class);

                // Test health indicator
                HealthIndicator healthIndicator = (HealthIndicator) context.getBean("httpClientHealthIndicator");
                assertThat(healthIndicator.health()).isNotNull();
            });
}

Detailed reference

Configuration

All properties live under the firefly.* namespace and map to validated @ConfigurationProperties classes. The values below are the configured defaults from the source.

firefly:
  # Reactive WebClient (WebClientProperties) -------------------------------
  webclient:
    enabled: true
    skip-headers: []            # inbound headers NOT forwarded downstream
    connect-timeout-ms: 5000
    read-timeout-ms: 10000
    write-timeout-ms: 10000
    max-in-memory-size: 16777216   # 16 MB
    connection-pool:
      enabled: true
      max-connections: 500
      max-pending-acquires: 1000
      max-idle-time-ms: 30000
      max-life-time-ms: 60000
      metrics-enabled: true
    http2:
      enabled: true
      max-concurrent-streams: 100
    ssl:
      enabled: false
      verify-hostname: true
    proxy:
      enabled: false
    # WebClient resilience (WebClientResilienceProperties) -----------------
    resilience:
      enabled: true
      circuit-breaker:
        failure-rate-threshold: 50          # percent
        wait-duration-in-open-state-ms: 10000
        permitted-number-of-calls-in-half-open-state: 5
        sliding-window-size: 10
      retry:
        max-attempts: 3
        initial-backoff-ms: 500
        max-backoff-ms: 5000
        backoff-multiplier: 2.0
      timeout:
        timeout-ms: 5000
      bulkhead:
        max-concurrent-calls: 25
        max-wait-duration-ms: 0

  # Actuator & observability (ActuatorProperties) -------------------------
  actuator:
    endpoints:
      enabled: true
      web:
        exposure: "*"
        base-path: /actuator
    metrics:
      enabled: true
      prometheus:
        enabled: true
        path: /actuator/prometheus
    tracing:
      enabled: true
      sampling:
        probability: 0.1
      propagation:
        type: [B3, W3C]
      zipkin:
        enabled: false
        base-url: http://localhost:9411
    health:
      show-details: always
      show-components: true

  # Structured logging (LoggingProperties) --------------------------------
  logging:
    json:
      recursive-parsing-enabled: true
      max-recursion-depth: 10
      max-json-size-bytes: 1048576       # 1 MB
      strict-validation: false
    performance:
      metrics-enabled: true
    cache:
      enabled: true
      max-validation-cache-size: 1000
      eviction-strategy: CLEAR_ALL       # or LRU

  # Spring Cloud Config client (CloudConfigProperties) — opt-in -----------
  cloud:
    config:
      enabled: false
      uri: http://localhost:8888
      label: main
      fail-fast: false
      retry: true
      max-retries: 6
      refresh-enabled: true

  # Service registry (ServiceRegistryProperties) — opt-in -----------------
  service:
    registry:
      enabled: false
      type: eureka                       # eureka | consul
      eureka:
        service-url: http://localhost:8761/eureka/
        prefer-ip-address: true
      consul:
        host: localhost
        port: 8500

  # Orchestration integration (auto-activates if module present) ----------
  orchestration:
    enabled: true

Key prefixes at a glance:

Prefix Class Purpose Default state
firefly.webclient WebClientProperties Reactive WebClient: timeouts, pool, SSL, proxy, HTTP/2, codecs enabled
firefly.webclient.resilience WebClientResilienceProperties Circuit breaker, retry, timeout, bulkhead enabled
firefly.actuator ActuatorProperties Endpoints, metrics, Prometheus, tracing, health, extended meters enabled
firefly.logging LoggingProperties JSON parsing, cache, and performance for structured logging enabled
firefly.cloud.config CloudConfigProperties Spring Cloud Config client disabled (opt-in)
firefly.service.registry ServiceRegistryProperties Eureka / Consul discovery disabled (opt-in)
firefly.orchestration (gate) Saga/TCC/Workflow integration enabled when module present

Auto-Configurations

Registered in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:

Auto-configuration Responsibility
FireflyBannerAutoConfiguration Firefly-branded startup banner
WebFluxAutoConfiguration Jackson JSON codecs (JSR-310, ISO-8601) for WebFlux
WebClientAutoConfiguration Resilient WebClient, WebClient.Builder, and WebClientTemplate beans
WebClientBuilderCustomizer Applies timeouts, pooling, SSL, proxy, HTTP/2, codec config
WebFilterAutoConfiguration Registers the TransactionFilter
WebClientResilienceAutoConfiguration Resilience4j registries (circuit breaker, retry, time limiter, bulkhead)
ActuatorDefaultPropertiesAutoConfiguration / ActuatorAutoConfiguration Actuator endpoint, metrics, and health defaults
DefaultHealthAutoConfiguration Default health indicators
DefaultInfoContributorAutoConfiguration Enhanced /actuator/info contributor
TracingAutoConfiguration Distributed tracing (sampling, propagation, Zipkin)
CloudConfigAutoConfiguration Spring Cloud Config client (opt-in)
ServiceRegistryAutoConfiguration Eureka / Consul registration (opt-in)
OrchestrationAutoConfiguration Saga/TCC/Workflow support (classpath-gated)

Continue the application

Use the Starter Domain guide for the next part of this integration. The runnable submission/query service is in Getting started.

Source and further reading