Zequent Client SDK - Configuration Guide

Overview

The Zequent Client SDK supports flexible configuration via application.properties or environment variables, allowing you to switch between environments (dev, staging, production) without any code changes.

Configuration Methods

Priority Order (highest to lowest):

  1. Environment Variables (e.g., REMOTE_CONTROL_SERVICE_HOST)
  2. System Properties (e.g., -Dzequent.remote-control-service.host=...)
  3. .env file (automatically loaded by Quarkus)
  4. application.properties (defaults)

Quick Start

1. Choose Your Environment

Copy the appropriate .env template:

# Development (local services)
cp .env.dev.example .env

# Staging (Docker Compose)
cp .env.staging.example .env

# Production (Kubernetes)
cp .env.production.example .env

2. Run Your Application

mvn quarkus:dev

That's it! No code changes needed.

Configuration Reference

Service Configuration

Each service (Remote Control, Mission Autonomy, Live Data) has the following settings:

Remote Control Service

PropertyEnvironment VariableDefaultDescription
zequent.remote-control-service.hostREMOTE_CONTROL_SERVICE_HOSTlocalhostService hostname
zequent.remote-control-service.portREMOTE_CONTROL_SERVICE_PORT8002Service port
zequent.remote-control-service.use-plaintextREMOTE_CONTROL_SERVICE_USE_PLAINTEXTtrueUse plaintext (no TLS)
zequent.remote-control-service.use-storkREMOTE_CONTROL_SERVICE_USE_STORKfalseEnable Stork service discovery
zequent.remote-control-service.stork-service-nameREMOTE_CONTROL_SERVICE_STORK_NAMEremote-control-serviceStork service name
zequent.remote-control-service.load-balancer-typeREMOTE_CONTROL_SERVICE_LOAD_BALANCERROUND_ROBINLoad balancer: ROUND_ROBIN, RANDOM, LEAST_REQUESTS

Mission Autonomy Service

PropertyEnvironment VariableDefaultDescription
zequent.mission-autonomy-service.hostMISSION_AUTONOMY_SERVICE_HOSTlocalhostService hostname
zequent.mission-autonomy-service.portMISSION_AUTONOMY_SERVICE_PORT8004Service port
zequent.mission-autonomy-service.use-plaintextMISSION_AUTONOMY_SERVICE_USE_PLAINTEXTtrueUse plaintext
zequent.mission-autonomy-service.use-storkMISSION_AUTONOMY_SERVICE_USE_STORKfalseEnable Stork
zequent.mission-autonomy-service.stork-service-nameMISSION_AUTONOMY_SERVICE_STORK_NAMEmission-autonomy-serviceStork service name
zequent.mission-autonomy-service.load-balancer-typeMISSION_AUTONOMY_SERVICE_LOAD_BALANCERROUND_ROBINLoad balancer type

Live Data Service

PropertyEnvironment VariableDefaultDescription
zequent.live-data-service.hostLIVE_DATA_SERVICE_HOSTlocalhostService hostname
zequent.live-data-service.portLIVE_DATA_SERVICE_PORT8003Service port
zequent.live-data-service.use-plaintextLIVE_DATA_SERVICE_USE_PLAINTEXTtrueUse plaintext
zequent.live-data-service.use-storkLIVE_DATA_SERVICE_USE_STORKfalseEnable Stork
zequent.live-data-service.stork-service-nameLIVE_DATA_SERVICE_STORK_NAMElive-data-serviceStork service name
zequent.live-data-service.load-balancer-typeLIVE_DATA_SERVICE_LOAD_BALANCERROUND_ROBINLoad balancer type

Connector Service

The Connector Service handles device connectivity and protocol translation. It is consumed internally by Mission Autonomy and Live Data services via gRPC (port 8010, HTTP and gRPC share the same port).

Connection (used by internal services connecting to connector-service):

PropertyEnvironment VariableDefaultDescription
grpc.clients.connector-service.hostCONNECTOR_SERVICE_HOSTlocalhostService hostname
grpc.clients.connector-service.portCONNECTOR_SERVICE_PORT8010gRPC port (shared with HTTP)

Redis:

PropertyEnvironment VariableDefaultDescription
quarkus.redis.hostsREDIS_URLredis://redis:6379Redis connection URL

Database (required for docker and k8s profiles):

PropertyEnvironment VariableDefaultDescription
quarkus.datasource.jdbc.urlDATABASE_URLjdbc:postgresql://zequent_db:5432/zequent_dbJDBC connection URL
quarkus.datasource.reactive.urlDATABASE_REACTIVE_URLpostgresql://zequent_db:5432/zequent_dbReactive (Vert.x) connection URL
quarkus.datasource.usernameDATABASE_USERpostgresDatabase username
quarkus.datasource.passwordDATABASE_PASSWORDpostgresDatabase password

Monitoring (Micrometer / Prometheus):

PropertyEnvironment VariableDefaultDescription
quarkus.micrometer.enabledMICROMETER_ENABLEDfalseEnable Micrometer metrics
quarkus.micrometer.export.prometheus.enabledPROMETHEUS_ENABLEDfalseEnable Prometheus endpoint
quarkus.micrometer.export.prometheus.pathPROMETHEUS_PATH/q/metricsPrometheus scrape path
quarkus.micrometer.binder.jvmMICROMETER_BINDER_JVMfalseJVM metrics
quarkus.micrometer.binder.systemMICROMETER_BINDER_SYSTEMfalseSystem metrics
quarkus.micrometer.binder.http-server.enabledHTTP_SERVER_ENABLEDfalseHTTP server metrics
quarkus.micrometer.binder.grpc-server.enabledGRPC_SERVER_ENABLEDfalsegRPC server metrics
quarkus.micrometer.binder.grpc-client.enabledGRPC_CLIENT_ENABLEDfalsegRPC client metrics

OpenTelemetry:

PropertyEnvironment VariableDefaultDescription
quarkus.otel.traces.enabledOTEL_TRACES_ENABLEDfalseEnable distributed tracing
quarkus.otel.metrics.enabledOTEL_METRICS_ENABLEDfalseEnable OTEL metrics export
quarkus.otel.logs.enabledOTEL_LOGS_ENABLEDfalseEnable OTEL log export
quarkus.otel.exporter.otlp.endpointOTEL_ENDPOINThttp://jaeger-all-in-one:4317OTLP collector endpoint
quarkus.otel.resource.attributesOTEL_RESOURCE_ATTRIBUTESservice.name=connector-serviceOTEL resource attributes

Global Resilience Settings

PropertyEnvironment VariableDefaultDescription
zequent.resilience.max-retry-attemptsZEQUENT_MAX_RETRY_ATTEMPTS3Maximum retry attempts
zequent.resilience.retry-delay-millisZEQUENT_RETRY_DELAY_MS1000Delay between retries (ms)
zequent.resilience.circuit-breaker-failure-thresholdZEQUENT_CIRCUIT_BREAKER_THRESHOLD5Failures before circuit opens
zequent.resilience.circuit-breaker-wait-duration-millisZEQUENT_CIRCUIT_BREAKER_WAIT_MS30000Wait before retry (ms)
zequent.resilience.connection-timeout-secondsZEQUENT_CONNECTION_TIMEOUT_SEC30Connection timeout
zequent.resilience.request-timeout-secondsZEQUENT_REQUEST_TIMEOUT_SEC60Request timeout

Environment Examples

Development (.env.dev.example)

# Local development - all services on localhost
REMOTE_CONTROL_SERVICE_HOST=localhost
REMOTE_CONTROL_SERVICE_PORT=8002
REMOTE_CONTROL_SERVICE_USE_PLAINTEXT=true
REMOTE_CONTROL_SERVICE_USE_STORK=false

Usage:

cp .env.dev.example .env
mvn quarkus:dev

Staging - Docker Compose (.env.staging.example)

# Docker Compose - use service names
REMOTE_CONTROL_SERVICE_HOST=remote-control-service
REMOTE_CONTROL_SERVICE_PORT=8002
REMOTE_CONTROL_SERVICE_USE_PLAINTEXT=true
REMOTE_CONTROL_SERVICE_USE_STORK=false

# Connector Service (internal - consumed by mission-autonomy and live-data)
CONNECTOR_SERVICE_HOST=connector-service
CONNECTOR_SERVICE_PORT=8010
REDIS_URL=redis://redis:6379
DATABASE_URL=jdbc:postgresql://zequent_db:5432/zequent_db
DATABASE_REACTIVE_URL=postgresql://zequent_db:5432/zequent_db
DATABASE_USER=postgres
DATABASE_PASSWORD=postgres

docker-compose.yml:

services:
  remote-control-service:
    image: zequent/remote-control:latest
    ports:
      - "8002:8002"

  my-app:
    image: my-app:latest
    env_file: .env

Usage:

cp .env.staging.example .env
docker-compose up

Production - Kubernetes (.env.production.example)

# Kubernetes with Stork service discovery
REMOTE_CONTROL_SERVICE_USE_STORK=true
REMOTE_CONTROL_SERVICE_STORK_NAME=remote-control-service
REMOTE_CONTROL_SERVICE_USE_PLAINTEXT=false
REMOTE_CONTROL_SERVICE_LOAD_BALANCER=LEAST_REQUESTS

Kubernetes deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    spec:
      containers:
      - name: my-app
        image: my-app:latest
        env:
        - name: REMOTE_CONTROL_SERVICE_USE_STORK
          value: "true"
        - name: REMOTE_CONTROL_SERVICE_STORK_NAME
          value: "remote-control-service"
        - name: REMOTE_CONTROL_SERVICE_USE_PLAINTEXT
          value: "false"
        - name: ZEQUENT_MAX_RETRY_ATTEMPTS
          value: "5"

Code Usage

With CDI (Recommended)

@ApplicationScoped
public class MyService {

    @Inject
    ZequentClient client;  // Automatically configured from properties!

    public void doSomething() {
        var request = TakeoffRequest.builder()
            .sn("YOUR_DEVICE_SN")
            .latitude(47.3769f)
            .longitude(8.5417f)
            .altitude(100.0f)
            .build();

        var response = client.remoteControl().takeoff(request).join();
    }
}

Standalone (Programmatic)

You can still use the builder if needed:

ZequentClient client = ZequentClient.builder()
    .remoteControl()
        .host("custom-host")
        .port(8002)
        .done()
    .build();

Load Balancer Types

TypeDescriptionUse Case
ROUND_ROBINDistribute requests evenly across instancesGeneral purpose (default)
RANDOMRandom instance selectionSimple load distribution
LEAST_REQUESTSRoute to instance with fewest active requestsOptimized for varying request durations
POWER_OF_TWO_CHOICESPick best of 2 random instancesBalance between random and least-requests

Stork Service Discovery

Kubernetes

REMOTE_CONTROL_SERVICE_USE_STORK=true
REMOTE_CONTROL_SERVICE_STORK_NAME=remote-control-service

Stork will automatically discover service endpoints via Kubernetes DNS.

Consul

Add to application.properties:

stork.remote-control-service.service-discovery.type=consul
stork.remote-control-service.service-discovery.consul-host=consul.example.com
stork.remote-control-service.service-discovery.consul-port=8500

Tips

1. Environment Switching

Never change code! Just switch .env files:

# Development
cp .env.dev.example .env && mvn quarkus:dev

# Staging
cp .env.staging.example .env && docker-compose up

# Production
# Set environment variables in K8s and deploy

2. Override Individual Settings

Mix defaults with overrides:

# Use .env defaults but override one service
REMOTE_CONTROL_SERVICE_HOST=custom-host mvn quarkus:dev

3. Validate Configuration

Check logs on startup:

Service 'remote-control' configured: host=localhost, port=8002, useStork=false
Service 'mission-autonomy' configured: host=localhost, port=8004, useStork=false
Service 'live-data' configured: host=localhost, port=8003, useStork=false
Service 'connector' configured: host=localhost, port=8010

Troubleshooting

Problem: Services not connecting

Check 1: Verify environment variables

echo $REMOTE_CONTROL_SERVICE_HOST
echo $REMOTE_CONTROL_SERVICE_PORT

Check 2: Check application logs for configuration

Service 'remote-control' configured: host=..., port=...

Check 3: Test connectivity

telnet $REMOTE_CONTROL_SERVICE_HOST $REMOTE_CONTROL_SERVICE_PORT

Problem: Stork not discovering services

Check 1: Verify Stork is enabled

echo $REMOTE_CONTROL_SERVICE_USE_STORK
# Should be: true

Check 2: Check Kubernetes service exists

kubectl get service remote-control-service

Check 3: Check Stork logs

Stork discovering service: remote-control-service

Summary

No code changes for environment switching Properties or environment variables - your choice Multi-service - each service independently configured Stork support - automatic service discovery Load balancing - per-service configuration Resilience - built-in retry, circuit breaker, timeouts

Just copy the right .env file and run!

Was this page helpful?