Setup Otoroshi

in this section we are going to configure otoroshi before running it for the first time

Setup the database

Right now, Otoroshi supports multiple datastore. You can choose one datastore over another depending on your use case.

Redis

The redis datastore is quite nice when you want to easily deploy several Otoroshi instances.

Documentation

In memory

The in-memory datastore is kind of interesting. It can be used for testing purposes, but it is also a good candidate for production because of its fastness.

Start with

Cassandra
Clustering

Experimental support, should be used in cluster mode for leaders

Documentation

Postgresql
Clustering

Or any postgresql compatible databse like cockroachdb for instance (experimental support, should be used in cluster mode for leaders)

Documentation

FileDB

The filedb datastore is pretty handy for testing purposes, but is not supposed to be used in production mode. Not suitable for production usage.

the first thing to setup is what kind of datastore you want to use with the otoroshi.storage setting

otoroshi {
  storage = "inmemory" # the storage used by otoroshi. possible values are lettuce (for redis), inmemory, file, http, s3, cassandra, postgresql             
  storage = ${?APP_STORAGE} # the storage used by otoroshi. possible values are lettuce (for redis), inmemory, file, http, s3, cassandra, postgresql  
  storage = ${?OTOROSHI_STORAGE} # the storage used by otoroshi. possible values are lettuce (for redis), inmemory, file, http, s3, cassandra, postgresql  
}

depending on the value you chose, you will be able to configure your datastore with the following configuration

inmemory
otoroshi {
  storage = "inmemory"
  inmemory { # configuration to fetch/store otoroshi state in memory
    windowSize = 99
    windowSize = ${?INMEMORY_WINDOW_SIZE}
    windowSize = ${?OTOROSHI_INMEMORY_WINDOW_SIZE}
    experimental = false
    experimental = ${?INMEMORY_EXPERIMENTAL_STORE}
    experimental = ${?OTOROSHI_INMEMORY_EXPERIMENTAL_STORE}
    optimized = false
    optimized = ${?INMEMORY_OPTIMIZED}
    optimized = ${?OTOROSHI_INMEMORY_OPTIMIZED}
    modern = false
    modern =  ${?INMEMORY_MODERN}
    modern =  ${?OTOROSHI_INMEMORY_MODERN}
  }
}
file
otoroshi {
  storage = "file"
  filedb { # configuration to fetch/store otoroshi state from a file
    windowSize = 99
    windowSize = ${?FILEDB_WINDOW_SIZE}
    windowSize = ${?OTOROSHI_FILEDB_WINDOW_SIZE}
    path = "./filedb/state.ndjson"
    path = ${?FILEDB_PATH}
    path = ${?OTOROSHI_FILEDB_PATH}
  }
}
http
otoroshi {
  storage = "http"
  httpdb { # configuration to fetch/store otoroshi state from an http endpoint
    url = "http://127.0.0.1:8888/worker-0/state.json"
    headers = {}
    timeout = 10000
    pollEvery = 10000
  }
}
s3
otoroshi {
  storage = "s3"
  s3db { # configuration to fetch/store otoroshi state from a S3 bucket
    bucket = "otoroshi-states"
    bucket = ${?OTOROSHI_DB_S3_BUCKET}
    endpoint = "https://otoroshi-states.foo.bar"
    endpoint = ${?OTOROSHI_DB_S3_ENDPOINT}
    region = "eu-west-1"
    region = ${?OTOROSHI_DB_S3_REGION}
    access = "secret"
    access = ${?OTOROSHI_DB_S3_ACCESS}
    secret = "secret"
    secret = ${?OTOROSHI_DB_S3_SECRET}
    key = "/otoroshi/states/state"
    key = ${?OTOROSHI_DB_S3_KEY}
    chunkSize = 8388608
    chunkSize = ${?OTOROSHI_DB_S3_CHUNK_SIZE}
    v4auth = true
    v4auth = ${?OTOROSHI_DB_S3_V4_AUTH}
    writeEvery = 60000 # write interval
    writeEvery = ${?OTOROSHI_DB_S3_WRITE_EVERY} # write interval
    acl = "Private"
    acl = ${?OTOROSHI_DB_S3_ACL}
  }
}
redis
otoroshi {
  storage = "lettuce"
  redis { 
    lettuce { # configuration to fetch/store otoroshi state from a redis datastore using the lettuce driver (the next default one)
      connection = "default"
      connection = ${?REDIS_LETTUCE_CONNECTION}
      connection = ${?OTOROSHI_REDIS_LETTUCE_CONNECTION}
      uri =  ${?REDIS_LETTUCE_URI}
      uri =  ${?OTOROSHI_REDIS_LETTUCE_URI}
      uri =  ${?REDIS_URL}
      uri =  ${?OTOROSHI_REDIS_URL}
      uris = []
      urisStr = ${?REDIS_LETTUCE_URIS}
      urisStr = ${?OTOROSHI_REDIS_LETTUCE_URIS}
      readFrom = "MASTER_PREFERRED"
      readFrom = ${?REDIS_LETTUCE_READ_FROM}
      readFrom = ${?OTOROSHI_REDIS_LETTUCE_READ_FROM}
      startTLS = false
      startTLS = ${?REDIS_LETTUCE_START_TLS}
      startTLS = ${?OTOROSHI_REDIS_LETTUCE_START_TLS}
      verifyPeers = true
      verifyPeers = ${?REDIS_LETTUCE_VERIFY_PEERS}
      verifyPeers = ${?OTOROSHI_REDIS_LETTUCE_VERIFY_PEERS}
    }
  }
}
postgresql
otoroshi {
  # postrgesql settings. everything possible with the client
  # WARNING: this is an experimental support and everything might not work as expected !!!
  storage = "postgresql"
  pg { 
    uri = ${?PG_URI}
    uri = ${?OTOROSHI_PG_URI}
    uri = ${?POSTGRESQL_ADDON_URI}
    uri = ${?OTOROSHI_POSTGRESQL_ADDON_URI}
    poolSize = 20
    poolSize = ${?PG_POOL_SIZE}
    poolSize = ${?OTOROSHI_PG_POOL_SIZE}
    port = 5432
    port = ${?PG_PORT}
    port = ${?OTOROSHI_PG_PORT}
    host = "localhost"
    host = ${?PG_HOST}
    host = ${?OTOROSHI_PG_HOST}
    database = "otoroshi"
    database = ${?PG_DATABASE}
    database = ${?OTOROSHI_PG_DATABASE}
    user = "otoroshi"
    user = ${?PG_USER}
    user = ${?OTOROSHI_PG_USER}
    password = "otoroshi"
    password = ${?PG_PASSWORD}
    password = ${?OTOROSHI_PG_PASSWORD}
    logQueries = ${?PG_DEBUG_QUERIES}
    logQueries = ${?OTOROSHI_PG_DEBUG_QUERIES}
    avoidJsonPath = false
    avoidJsonPath = ${?PG_AVOID_JSON_PATH}
    avoidJsonPath = ${?OTOROSHI_PG_AVOID_JSON_PATH}
    optimized = true
    optimized = ${?PG_OPTIMIZED}
    optimized = ${?OTOROSHI_PG_OPTIMIZED}
    connect-timeout = ${?PG_CONNECT_TIMEOUT}
    connect-timeout = ${?OTOROSHI_PG_CONNECT_TIMEOUT}
    idle-timeout = ${?PG_IDLE_TIMEOUT}
    idle-timeout = ${?OTOROSHI_PG_IDLE_TIMEOUT}
    log-activity = ${?PG_LOG_ACTIVITY}
    log-activity = ${?OTOROSHI_PG_LOG_ACTIVITY}
    pipelining-limit = ${?PG_PIPELINING_LIMIT}
    pipelining-limit = ${?OTOROSHI_PG_PIPELINING_LIMIT}
    ssl {
      enabled = false
      enabled = ${?PG_SSL_ENABLED}
      enabled = ${?OTOROSHI_PG_SSL_ENABLED}
      mode = "verify_ca"
      mode = ${?PG_SSL_MODE}
      mode = ${?OTOROSHI_PG_SSL_MODE}
      trusted-certs-path = []
      trusted-certs = []
      trusted-cert-path = ${?PG_SSL_TRUSTED_CERT_PATH}
      trusted-cert-path = ${?OTOROSHI_PG_SSL_TRUSTED_CERT_PATH}
      trusted-cert = ${?PG_SSL_TRUSTED_CERT}
      trusted-cert = ${?OTOROSHI_PG_SSL_TRUSTED_CERT}
      client-certs-path = []
      client-certs = []
      client-cert-path = ${?PG_SSL_CLIENT_CERT_PATH}
      client-cert-path = ${?OTOROSHI_PG_SSL_CLIENT_CERT_PATH}
      client-cert = ${?PG_SSL_CLIENT_CERT}
      client-cert = ${?OTOROSHI_PG_SSL_CLIENT_CERT}
      trust-all = ${?PG_SSL_TRUST_ALL}
      trust-all = ${?OTOROSHI_PG_SSL_TRUST_ALL}
    }
  }
}
cassandra
otoroshi {
  storage = "cassandra"
  cassandra { # cassandra settings. everything possible with the client
    windowSize = 99
    windowSize = ${?CASSANDRA_WINDOW_SIZE}
    windowSize = ${?OTOROSHI_CASSANDRA_WINDOW_SIZE}
    host = "127.0.0.1"
    host = ${?CASSANDRA_HOST}
    host = ${?OTOROSHI_CASSANDRA_HOST}
    port = 9042
    port = ${?CASSANDRA_PORT}
    port = ${?OTOROSHI_CASSANDRA_PORT}
    replicationFactor = 1
    replicationFactor = ${?CASSANDRA_REPLICATION_FACTOR}
    replicationFactor = ${?OTOROSHI_CASSANDRA_REPLICATION_FACTOR}
    replicationOptions = ${?CASSANDRA_REPLICATION_OPTIONS}
    replicationOptions = ${?OTOROSHI_CASSANDRA_REPLICATION_OPTIONS}
    durableWrites = true
    durableWrites = ${?CASSANDRA_DURABLE_WRITES}
    durableWrites = ${?OTOROSHI_CASSANDRA_DURABLE_WRITES}
    basic.contact-points = [ ${app.cassandra.host}":"${app.cassandra.port} ]
    basic.session-name = "otoroshi"
    basic.session-name = ${?OTOROSHI_CASSANDRA_SESSION_NAME}
    basic.session-keyspace = ${?OTOROSHI_CASSANDRA_SESSION_KEYSPACE}
    basic.config-reload-interval = 5 minutes
    basic.request {
      timeout = 10 seconds
      consistency = LOCAL_ONE
      consistency = ${?OTOROSHI_CASSANDRA_CONSISTENCY}
      page-size = 5000
      page-size = ${?OTOROSHI_CASSANDRA_PAGE_SIZE}
      serial-consistency = SERIAL
      serial-consistency = ${?OTOROSHI_CASSANDRA_SERIAL_CONSISTENCY}
      default-idempotence = false
      default-idempotence = ${?OTOROSHI_CASSANDRA_DEFAULT_IDEMPOTENCE}
    }
    basic.load-balancing-policy {
      class = DefaultLoadBalancingPolicy
      local-datacenter = datacenter1
      local-datacenter = ${?OTOROSHI_CASSANDRA_LOCAL_DATACENTER}
      # filter.class=
      slow-replica-avoidance = true
    }
    basic.cloud {
      # secure-connect-bundle = /location/of/secure/connect/bundle
    }
    basic.application {
      # name =
      # version =
    }
    basic.graph {
      # name = your-graph-name
      traversal-source = "g"
      # is-system-query = false
      # read-consistency-level = LOCAL_QUORUM
      # write-consistency-level = LOCAL_ONE
      # timeout = 10 seconds
    }
    advanced.connection {
      connect-timeout = 5 seconds
      init-query-timeout = 500 milliseconds
      set-keyspace-timeout = ${datastax-java-driver.advanced.connection.init-query-timeout}
      pool {
        local {
          size = 1
        }
        remote {
          size = 1
        }
      }
      max-requests-per-connection = 1024
      max-orphan-requests = 256
      warn-on-init-error = true
    }
    advanced.reconnect-on-init = false
    advanced.reconnection-policy {
      class = ExponentialReconnectionPolicy
      base-delay = 1 second
      max-delay = 60 seconds
    }
    advanced.retry-policy {
      class = DefaultRetryPolicy
    }
    advanced.speculative-execution-policy {
      class = NoSpeculativeExecutionPolicy
      # max-executions = 3
      # delay = 100 milliseconds
    }
    advanced.auth-provider {
      # class = PlainTextAuthProvider
      username = ${?CASSANDRA_USERNAME}
      username = ${?OTOROSHI_CASSANDRA_USERNAME}
      password = ${?CASSANDRA_PASSWORD}
      password = ${?OTOROSHI_CASSANDRA_PASSWORD}
      authorization-id = ${?OTOROSHI_CASSANDRA_AUTHORIZATION_ID}
      //service = "cassandra"
      # login-configuration {
      #   principal = "cassandra@DATASTAX.COM"
      #   useKeyTab = "true"
      #   refreshKrb5Config = "true"
      #   keyTab = "/path/to/keytab/file"
      # }
      # sasl-properties {
      #   javax.security.sasl.qop = "auth-conf"
      # }
    }
    advanced.ssl-engine-factory {
      # class = DefaultSslEngineFactory
      # cipher-suites = [ "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA" ]
      # hostname-validation = true
      # truststore-path = /path/to/client.truststore
      # truststore-password = password123
      # keystore-path = /path/to/client.keystore
      # keystore-password = password123
    }
    advanced.timestamp-generator {
      class = AtomicTimestampGenerator
      drift-warning {
        threshold = 1 second
        interval = 10 seconds
      }
      force-java-clock = false
    }
    advanced.request-tracker {
      class = NoopRequestTracker
      logs {
        # success.enabled = true
        slow {
          # threshold = 1 second
          # enabled = true
        }
        # error.enabled = true
        # max-query-length = 500
        # show-values = true
        # max-value-length = 50
        # max-values = 50
        # show-stack-traces = true
      }
    }
    advanced.throttler {
      class = PassThroughRequestThrottler
      # max-queue-size = 10000
      # max-concurrent-requests = 10000
      # max-requests-per-second = 10000
      # drain-interval = 10 milliseconds
    }
    advanced.node-state-listener.class = NoopNodeStateListener
    advanced.schema-change-listener.class = NoopSchemaChangeListener
    advanced.address-translator {
      class = PassThroughAddressTranslator
    }
    advanced.resolve-contact-points = true
    advanced.protocol {
      version = V4
      version = ${?OTOROSHI_CASSANDRA_PROTOCOL_VERSION}
      compression = lz4
      compression = ${?OTOROSHI_CASSANDRA_PROTOCOL_COMPRESSION}
      max-frame-length = 256 MB
    }
    advanced.request {
      warn-if-set-keyspace = false
      trace {
        attempts = 5
        interval = 3 milliseconds
        consistency = ONE
      }
      log-warnings = true
    }
    advanced.graph {
      # sub-protocol = "graphson-2.0"
      paging-enabled = "AUTO"
      paging-options {
        page-size = ${datastax-java-driver.advanced.continuous-paging.page-size}
        max-pages = ${datastax-java-driver.advanced.continuous-paging.max-pages}
        max-pages-per-second = ${datastax-java-driver.advanced.continuous-paging.max-pages-per-second}
        max-enqueued-pages = ${datastax-java-driver.advanced.continuous-paging.max-enqueued-pages}
      }
    }
    advanced.continuous-paging {
      page-size = ${datastax-java-driver.basic.request.page-size}
      page-size-in-bytes = false
      max-pages = 0
      max-pages-per-second = 0
      max-enqueued-pages = 4
      timeout {
        first-page = 2 seconds
        other-pages = 1 second
      }
    }
    advanced.monitor-reporting {
      enabled = true
    }
    advanced.metrics {
      session {
        enabled = [
          # bytes-sent,
          # bytes-received
          # connected-nodes,
          # cql-requests,
          # cql-client-timeouts,
          # cql-prepared-cache-size,
          # throttling.delay,
          # throttling.queue-size,
          # throttling.errors,
          # continuous-cql-requests,
          # graph-requests,
          # graph-client-timeouts
        ]
        cql-requests {
          highest-latency = 3 seconds
          significant-digits = 3
          refresh-interval = 5 minutes
        }
        throttling.delay {
          highest-latency = 3 seconds
          significant-digits = 3
          refresh-interval = 5 minutes
        }
        continuous-cql-requests {
          highest-latency = 120 seconds
          significant-digits = 3
          refresh-interval = 5 minutes
        }
        graph-requests {
          highest-latency = 12 seconds
          significant-digits = 3
          refresh-interval = 5 minutes
        }
      }
      node {
        enabled = [
          # pool.open-connections,
          # pool.available-streams,
          # pool.in-flight,
          # pool.orphaned-streams,
          # bytes-sent,
          # bytes-received,
          # cql-messages,
          # errors.request.unsent,
          # errors.request.aborted,
          # errors.request.write-timeouts,
          # errors.request.read-timeouts,
          # errors.request.unavailables,
          # errors.request.others,
          # retries.total,
          # retries.aborted,
          # retries.read-timeout,
          # retries.write-timeout,
          # retries.unavailable,
          # retries.other,
          # ignores.total,
          # ignores.aborted,
          # ignores.read-timeout,
          # ignores.write-timeout,
          # ignores.unavailable,
          # ignores.other,
          # speculative-executions,
          # errors.connection.init,
          # errors.connection.auth,
          # graph-messages,
        ]
        cql-messages {
          highest-latency = 3 seconds
          significant-digits = 3
          refresh-interval = 5 minutes
        }
        graph-messages {
          highest-latency = 3 seconds
          significant-digits = 3
          refresh-interval = 5 minutes
        }
      }
    }
    advanced.socket {
      tcp-no-delay = true
      //keep-alive = false
      //reuse-address = true
      //linger-interval = 0
      //receive-buffer-size = 65535
      //send-buffer-size = 65535
    }
    advanced.heartbeat {
      interval = 30 seconds
      timeout = ${datastax-java-driver.advanced.connection.init-query-timeout}
    }
    advanced.metadata {
      topology-event-debouncer {
        window = 1 second
        max-events = 20
      }
      schema {
        enabled = true
        # refreshed-keyspaces = [ "ks1", "ks2" ]
        request-timeout = ${datastax-java-driver.basic.request.timeout}
        request-page-size = ${datastax-java-driver.basic.request.page-size}
        debouncer {
          window = 1 second
          max-events = 20
        }
      }
      token-map.enabled = true
    }
    advanced.control-connection {
      timeout = ${datastax-java-driver.advanced.connection.init-query-timeout}
      schema-agreement {
        interval = 200 milliseconds
        timeout = 10 seconds
        warn-on-failure = true
      }
    }
    advanced.prepared-statements {
      prepare-on-all-nodes = true
      reprepare-on-up {
        enabled = true
        check-system-table = false
        max-statements = 0
        max-parallelism = 100
        timeout = ${datastax-java-driver.advanced.connection.init-query-timeout}
      }
    }
    advanced.netty {
      daemon = false
      io-group {
        size = 0
        shutdown {quiet-period = 2, timeout = 15, unit = SECONDS}
      }
      admin-group {
        size = 2
        shutdown {quiet-period = 2, timeout = 15, unit = SECONDS}
      }
      timer {
        tick-duration = 100 milliseconds
        ticks-per-wheel = 2048
      }
    }
    advanced.coalescer {
      max-runs-with-no-work = 5
      reschedule-interval = 10 microseconds
    }
  }
}

Setup your hosts before running

By default, Otoroshi starts with domain oto.tools that automatically targets 127.0.0.1 with no changes to your /etc/hosts file. Of course you can change the domain value, you have to add the values in your /etc/hosts file according to the setting you put in Otoroshi configuration or define the right ip address at the DNS provider level

  • otoroshi.domain => mydomain.org
  • otoroshi.backoffice.subdomain => otoroshi
  • otoroshi.privateapps.subdomain => privateapps
  • otoroshi.adminapi.exposedSubdomain => otoroshi-api
  • otoroshi.adminapi.targetSubdomain => otoroshi-admin-internal-api

for instance if you want to change the default domain and use something like otoroshi.mydomain.org, then start otoroshi like

java -Dotoroshi.domain=mydomain.org -jar otoroshi.jar
Warning

Otoroshi cannot be accessed using http://127.0.0.1:8080 or http://localhost:8080 because Otoroshi uses Otoroshi to serve it’s own UI and API. When otoroshi starts with an empty database, it will create a service descriptor for that using otoroshi.domain and the settings listed on this page and in the here that serve Otoroshi API and UI on http://otoroshi-api.${otoroshi.domain} and http://otoroshi.${otoroshi.domain}. Once the descriptor is saved in database, if you want to change otoroshi.domain, you’ll have to edit the descriptor in the database or restart Otoroshi with an empty database.

Warning

if your otoroshi instance runs behind a reverse proxy (L4 / L7) or inside a docker container where exposed ports (that you will use to access otoroshi) are not the same that the ones configured in otoroshi (http.port and https.port), you’ll have to configure otoroshi exposed port to avoid bad redirection URLs when using authentication modules and other otoroshi tools. To do that, just set the values of the exposed ports in otoroshi.exposed-ports.http = $theExposedHttpPort (OTOROSHI_EXPOSED_PORTS_HTTP) and otoroshi.exposed-ports.https = $theExposedHttpsPort (OTOROSHI_EXPOSED_PORTS_HTTPS)

Setup your configuration file

There is a lot of things you can configure in Otoroshi. By default, Otoroshi provides a configuration that should be enough for testing purpose. But you’ll likely need to update this configuration when you’ll need to move into production.

In this page, any configuration property can be set at runtime using a -D flag when launching Otoroshi like

java -Dhttp.port=8080 -jar otoroshi.jar

or

./bin/otoroshi -Dhttp.port=8080 

if you want to define your own config file and use it on an otoroshi instance, use the following flag

java -Dconfig.file=/path/to/otoroshi.conf -jar otoroshi.jar

Example of a custom. configuration file

include "application.conf"

http.port = 8080

app {
  storage = "inmemory"
  importFrom = "./my-state.json"
  env = "prod"
  domain = "oto.tools"
  rootScheme = "http"
  snowflake {
    seed = 0
  }
  events {
    maxSize = 1000
  }
  backoffice {
    subdomain = "otoroshi"
    session {
      exp = 86400000
    }
  }
  privateapps {
    subdomain = "privateapps"
    session {
      exp = 86400000
    }
  }
  adminapi {
    targetSubdomain = "otoroshi-admin-internal-api"
    exposedSubdomain = "otoroshi-api"
    defaultValues {
      backOfficeGroupId = "admin-api-group"
      backOfficeApiKeyClientId = "admin-api-apikey-id"
      backOfficeApiKeyClientSecret = "admin-api-apikey-secret"
      backOfficeServiceId = "admin-api-service"
    }
  }
  claim {
    sharedKey = "mysecret"
  }
  filedb {
    path = "./filedb/state.ndjson"
  }
}

play.http {
  session {
    secure = false
    httpOnly = true
    maxAge = 2592000000
    domain = ".oto.tools"
    cookieName = "oto-sess"
  }
}

Reference configuration


app { storage = "inmemory" # the storage used by otoroshi. possible values are lettuce (for redis), inmemory, file, http, s3, cassandra, postgresql storage = ${?APP_STORAGE} # the storage used by otoroshi. possible values are lettuce (for redis), inmemory, file, http, s3, cassandra, postgresql storage = ${?OTOROSHI_STORAGE} # the storage used by otoroshi. possible values are lettuce (for redis), inmemory, file, http, s3, cassandra, postgresql storageRoot = "otoroshi" # the prefix used for storage keys storageRoot = ${?APP_STORAGE_ROOT} # the prefix used for storage keys storageRoot = ${?OTOROSHI_STORAGE_ROOT} # the prefix used for storage keys eventsName = "otoroshi" # the name of the event producer eventsName = ${?APP_EVENTS_NAME} # the name of the event producer eventsName = ${?OTOROSHI_EVENTS_NAME} # the name of the event producer importFrom = ${?APP_IMPORT_FROM} # file path to import otoroshi initial configuration importFrom = ${?OTOROSHI_IMPORT_FROM} # file path to import otoroshi initial configuration env = "prod" # env name, should always be prod except in dev mode env = ${?APP_ENV} # env name, should always be prod except in dev mode env = ${?OTOROSHI_ENV} # env name, should always be prod except in dev mode liveJs = false # enabled live JS loading for dev mode domain = "oto.tools" # default domain for basic otoroshi services domain = ${?APP_DOMAIN} # default domain for basic otoroshi services domain = ${?OTOROSHI_DOMAIN} # default domain for basic otoroshi services commitId = "HEAD" commitId = ${?COMMIT_ID} commitId = ${?OTOROSHI_COMMIT_ID} rootScheme = "http" # default root scheme when composing urls rootScheme = ${?APP_ROOT_SCHEME} # default root scheme when composing urls rootScheme = ${?OTOROSHI_ROOT_SCHEME} # default root scheme when composing urls throttlingWindow = 10 # the number of second used to compute throttling number throttlingWindow = ${?THROTTLING_WINDOW} # the number of second used to compute throttling number throttlingWindow = ${?OTOROSHI_THROTTLING_WINDOW} # the number of second used to compute throttling number checkForUpdates = true # enable automatic version update checks checkForUpdates = ${?CHECK_FOR_UPDATES} # enable automatic version update checks checkForUpdates = ${?OTOROSHI_CHECK_FOR_UPDATES} # enable automatic version update checks overheadThreshold = 500.0 # the value threshold (in milliseconds) used to send HighOverheadAlert overheadThreshold = ${?OVERHEAD_THRESHOLD} # the value threshold (in milliseconds) used to send HighOverheadAlert overheadThreshold = ${?OTOROSHI_OVERHEAD_THRESHOLD} # the value threshold (in milliseconds) used to send HighOverheadAlert adminLogin = ${?OTOROSHI_INITIAL_ADMIN_LOGIN} # the initial admin login adminPassword = ${?OTOROSHI_INITIAL_ADMIN_PASSWORD} # the initial admin password initialCustomization = ${?OTOROSHI_INITIAL_CUSTOMIZATION} # otoroshi inital configuration that will be merged with a new confguration. Shaped like an otoroshi export boot { failOnTimeout = false # otoroshi will exit if a subsystem failed its init failOnTimeout = ${?OTOROSHI_BOOT_FAIL_ON_TIMEOUT} # otoroshi will exit if a subsystem failed its init globalWait = true # should we wait until everything is setup to accept http requests globalWait = ${?OTOROSHI_BOOT_GLOBAL_WAIT} # should we wait until everything is setup to accept http requests globalWaitTimeout = 60000 # max wait before accepting requests globalWaitTimeout = ${?OTOROSHI_BOOT_GLOBAL_WAIT_TIMEOUT} # max wait before accepting requests waitForPluginsSearch = true # should we wait for classpath plugins search before accepting http requests waitForPluginsSearch = ${?OTOROSHI_BOOT_WAIT_FOR_PLUGINS_SEARCH} # should we wait for classpath plugins search before accepting http requests waitForPluginsSearchTimeout = 20000 # max wait for classpath plugins search before accepting http requests waitForPluginsSearchTimeout = ${?OTOROSHI_BOOT_WAIT_FOR_PLUGINS_SEARCH_TIMEOUT} # max wait for classpath plugins search before accepting http requests waitForScriptsCompilation = true # should we wait for plugins compilation before accepting http requests waitForScriptsCompilation = ${?OTOROSHI_BOOT_WAIT_FOR_SCRIPTS_COMPILATION} # should we wait for plugins compilation before accepting http requests waitForScriptsCompilationTimeout = 30000 # max wait for plugins compilation before accepting http requests waitForScriptsCompilationTimeout = ${?OTOROSHI_BOOT_WAIT_FOR_SCRIPTS_COMPILATION_TIMEOUT} # max wait for plugins compilation before accepting http requests waitForTlsInit = true # should we wait for first TLS context initialization before accepting http requests waitForTlsInit = ${?OTOROSHI_BOOT_WAIT_FOR_TLS_INIT} # should we wait for first TLS context initialization before accepting http requests waitForTlsInitTimeout = 10000 # max wait for first TLS context initialization before accepting http requests waitForTlsInitTimeout = ${?OTOROSHI_BOOT_WAIT_FOR_TLS_INIT_TIMEOUT} # max wait for first TLS context initialization before accepting http requests waitForFirstClusterFetch = true # should we wait for first cluster initialization before accepting http requests waitForFirstClusterFetch = ${?OTOROSHI_BOOT_WAIT_FOR_FIRST_CLUSTER_FETCH} # should we wait for first cluster initialization before accepting http requests waitForFirstClusterFetchTimeout = 10000 # max wait for first cluster initialization before accepting http requests waitForFirstClusterFetchTimeout = ${?OTOROSHI_BOOT_WAIT_FOR_FIRST_CLUSTER_TIMEOUT} # max wait for first cluster initialization before accepting http requests waitForFirstClusterStateCache = true # should we wait for first cluster initialization before accepting http requests waitForFirstClusterStateCache = ${?OTOROSHI_BOOT_WAIT_FOR_FIRST_CLUSTER_STATE_CACHE} # should we wait for first cluster initialization before accepting http requests waitForFirstClusterStateCacheTimeout = 10000 # max wait for first cluster initialization before accepting http requests waitForFirstClusterStateCacheTimeout = ${?OTOROSHI_BOOT_WAIT_FOR_FIRST_CLUSTER_STATE_CACHE_TIMEOUT} # max wait for first cluster initialization before accepting http requests } instance { instanceId = ${?OTOROSHI_INSTANCE_ID} # the instance id number = 0 # the instance number. Can be found in otoroshi events number = ${?OTOROSHI_INSTANCE_NUMBER} # the instance number. Can be found in otoroshi events number = ${?INSTANCE_NUMBER} # the instance number. Can be found in otoroshi events name = "otoroshi" # instance name name = ${?OTOROSHI_INSTANCE_NAME} # instance name logo = ${?OTOROSHI_INSTANCE_LOGO} # instance logo zone = "local" # instance zone (optional) zone = ${?OTOROSHI_INSTANCE_ZONE} # instance zone (optional) region = "local" # instance region (optional) region = ${?OTOROSHI_INSTANCE_REGION} # instance region (optional) dc = "local" # instance dc (optional) dc = ${?OTOROSHI_INSTANCE_DATACENTER} # instance dc (optional) provider = "local" # instance provider (optional) provider = ${?OTOROSHI_INSTANCE_PROVIDER} # instance provider (optional) rack = "local" # instance rack (optional) rack = ${?OTOROSHI_INSTANCE_RACK} # instance rack (optional) title = ${?OTOROSHI_INSTANCE_TITLE} # the title displayed in UI top left } longRequestTimeout = 10800000 longRequestTimeout = ${?OTOROSHI_PROXY_LONG_REQUEST_TIMEOUT} } health { limit = 1000 # the value threshold (in milliseconds) used to indicate if an otoroshi instance is healthy or not limit = ${?HEALTH_LIMIT} # the value threshold (in milliseconds) used to indicate if an otoroshi instance is healthy or not limit = ${?OTOROSHI_HEALTH_LIMIT} # the value threshold (in milliseconds) used to indicate if an otoroshi instance is healthy or not accessKey = ${?HEALTH_ACCESS_KEY} # the key to access /health edpoint accessKey = ${?OTOROSHI_HEALTH_ACCESS_KEY} # the key to access /health edpoint } snowflake { seed = 0 # the seed number used to generate unique ids. Should be different for every instances seed = ${?INSTANCE_NUMBER} # the seed number used to generate unique ids. Should be different for every instances seed = ${?OTOROSHI_INSTANCE_NUMBER} # the seed number used to generate unique ids. Should be different for every instances seed = ${?SNOWFLAKE_SEED} # the seed number used to generate unique ids. Should be different for every instances seed = ${?OTOROSHI_SNOWFLAKE_SEED} # the seed number used to generate unique ids. Should be different for every instances } events { maxSize = 1000 # the amount of event kept in the datastore maxSize = ${?MAX_EVENTS_SIZE} # the amount of event kept in the datastore maxSize = ${?OTOROSHI_MAX_EVENTS_SIZE} # the amount of event kept in the datastore } exposed-ports { http = ${?APP_EXPOSED_PORTS_HTTP} # the exposed http port for otoroshi (when in a container or behind a proxy) http = ${?OTOROSHI_EXPOSED_PORTS_HTTP} # the exposed http port for otoroshi (when in a container or behind a proxy) https = ${?APP_EXPOSED_PORTS_HTTPS} # the exposed https port for otoroshi (when in a container or behind a proxy https = ${?OTOROSHI_EXPOSED_PORTS_HTTPS} # the exposed https port for otoroshi (when in a container or behind a proxy } backoffice { exposed = true # expose the backoffice ui exposed = ${?APP_BACKOFFICE_EXPOSED} # expose the backoffice ui exposed = ${?OTOROSHI_BACKOFFICE_EXPOSED} # expose the backoffice ui subdomain = "otoroshi" # the backoffice subdomain subdomain = ${?APP_BACKOFFICE_SUBDOMAIN} # the backoffice subdomain subdomain = ${?OTOROSHI_BACKOFFICE_SUBDOMAIN} # the backoffice subdomain domains = [] # the backoffice domains domainsStr = ${?APP_BACKOFFICE_DOMAINS} # the backoffice domains domainsStr = ${?OTOROSHI_BACKOFFICE_DOMAINS} # the backoffice domains # useNewEngine = false # avoid backoffice admin api proxy # useNewEngine = ${?OTOROSHI_BACKOFFICE_USE_NEW_ENGINE} # avoid backoffice admin api proxy usePlay = true # avoid backoffice http call for admin api usePlay = ${?OTOROSHI_BACKOFFICE_USE_PLAY} # avoid backoffice http call for admin api session { exp = 86400000 # the backoffice cookie expiration exp = ${?APP_BACKOFFICE_SESSION_EXP} # the backoffice cookie expiration exp = ${?OTOROSHI_BACKOFFICE_SESSION_EXP} # the backoffice cookie expiration } } privateapps { subdomain = "privateapps" # privateapps (proxy sso) domain subdomain = ${?APP_PRIVATEAPPS_SUBDOMAIN} # privateapps (proxy sso) domain subdomain = ${?OTOROSHI_PRIVATEAPPS_SUBDOMAIN} # privateapps (proxy sso) domain domains = [] domainsStr = ${?APP_PRIVATEAPPS_DOMAINS} domainsStr = ${?OTOROSHI_PRIVATEAPPS_DOMAINS} session { exp = 86400000 # the privateapps cookie expiration exp = ${?APP_PRIVATEAPPS_SESSION_EXP} # the privateapps cookie expiration exp = ${?OTOROSHI_PRIVATEAPPS_SESSION_EXP} # the privateapps cookie expiration } } adminapi { exposed = true # expose the admin api exposed = ${?ADMIN_API_EXPOSED} # expose the admin api exposed = ${?OTOROSHI_ADMIN_API_EXPOSED} # expose the admin api targetSubdomain = "otoroshi-admin-internal-api" # admin api target subdomain as targeted by otoroshi service targetSubdomain = ${?ADMIN_API_TARGET_SUBDOMAIN} # admin api target subdomain as targeted by otoroshi service targetSubdomain = ${?OTOROSHI_ADMIN_API_TARGET_SUBDOMAIN} # admin api target subdomain as targeted by otoroshi service exposedSubdomain = "otoroshi-api" # admin api exposed subdomain as exposed by otoroshi service exposedSubdomain = ${?ADMIN_API_EXPOSED_SUBDOMAIN} # admin api exposed subdomain as exposed by otoroshi service exposedSubdomain = ${?OTOROSHI_ADMIN_API_EXPOSED_SUBDOMAIN} # admin api exposed subdomain as exposed by otoroshi service additionalExposedDomain = ${?ADMIN_API_ADDITIONAL_EXPOSED_DOMAIN} # admin api additional exposed subdomain as exposed by otoroshi service additionalExposedDomain = ${?OTOROSHI_ADMIN_API_ADDITIONAL_EXPOSED_DOMAIN} # admin api additional exposed subdomain as exposed by otoroshi service domains = [] domainsStr = ${?ADMIN_API_DOMAINS} domainsStr = ${?OTOROSHI_ADMIN_API_DOMAINS} exposedDomains = [] exposedDomainsStr = ${?ADMIN_API_EXPOSED_DOMAINS} exposedDomainsStr = ${?OTOROSHI_ADMIN_API_EXPOSED_DOMAINS} defaultValues { backOfficeGroupId = "admin-api-group" # default value for admin api service group backOfficeGroupId = ${?ADMIN_API_GROUP} # default value for admin api service group backOfficeGroupId = ${?OTOROSHI_ADMIN_API_GROUP} # default value for admin api service group backOfficeApiKeyClientId = "admin-api-apikey-id" # default value for admin api apikey id backOfficeApiKeyClientId = ${?ADMIN_API_CLIENT_ID} # default value for admin api apikey id backOfficeApiKeyClientId = ${?OTOROSHI_ADMIN_API_CLIENT_ID} # default value for admin api apikey id backOfficeApiKeyClientSecret = "admin-api-apikey-secret" # default value for admin api apikey secret backOfficeApiKeyClientSecret = ${?otoroshi.admin-api-secret} # default value for admin api apikey secret backOfficeApiKeyClientSecret = ${?OTOROSHI_otoroshi.admin-api-secret} # default value for admin api apikey secret backOfficeApiKeyClientSecret = ${?ADMIN_API_CLIENT_SECRET} # default value for admin api apikey secret backOfficeApiKeyClientSecret = ${?OTOROSHI_ADMIN_API_CLIENT_SECRET} # default value for admin api apikey secret backOfficeServiceId = "admin-api-service" # default value for admin api service id backOfficeServiceId = ${?ADMIN_API_SERVICE_ID} # default value for admin api service id backOfficeServiceId = ${?OTOROSHI_ADMIN_API_SERVICE_ID} # default value for admin api service id } proxy { https = false # backoffice proxy admin api over https https = ${?ADMIN_API_HTTPS} # backoffice proxy admin api over https https = ${?OTOROSHI_ADMIN_API_HTTPS} # backoffice proxy admin api over https local = true # backoffice proxy admin api on localhost local = ${?ADMIN_API_LOCAL} # backoffice proxy admin api on localhost local = ${?OTOROSHI_ADMIN_API_LOCAL} # backoffice proxy admin api on localhost } } claim { sharedKey = "secret" # the default secret used to sign otoroshi exchange protocol tokens sharedKey = ${?CLAIM_SHAREDKEY} # the default secret used to sign otoroshi exchange protocol tokens sharedKey = ${?OTOROSHI_CLAIM_SHAREDKEY} # the default secret used to sign otoroshi exchange protocol tokens } webhooks { } redis { # configuration to fetch/store otoroshi state from a redis datastore using rediscala host = "localhost" host = ${?REDIS_HOST} host = ${?OTOROSHI_REDIS_HOST} port = 6379 port = ${?REDIS_PORT} port = ${?OTOROSHI_REDIS_PORT} password = ${?REDIS_PASSWORD} password = ${?OTOROSHI_REDIS_PASSWORD} windowSize = 99 windowSize = ${?REDIS_WINDOW_SIZE} windowSize = ${?OTOROSHI_REDIS_WINDOW_SIZE} slaves = [] slavesStr = ${?REDIS_SLAVES} slavesStr = ${?OTOROSHI_REDIS_SLAVES} slavesStr = ${?REDIS_MEMBERS} slavesStr = ${?OTOROSHI_REDIS_MEMBERS} useScan = false useScan = ${?REDIS_USE_SCAN} useScan = ${?OTOROSHI_REDIS_USE_SCAN} pool { members = [] members = ${?REDIS_POOL_MEMBERS} members = ${?OTOROSHI_REDIS_POOL_MEMBERS} } mpool { members = [] membersStr = ${?REDIS_MPOOL_MEMBERS} membersStr = ${?OTOROSHI_REDIS_MPOOL_MEMBERS} } lf { master { host = ${?REDIS_LF_HOST} host = ${?OTOROSHI_REDIS_LF_HOST} port = ${?REDIS_LF_PORT} port = ${?OTOROSHI_REDIS_LF_PORT} password = ${?REDIS_LF_PASSWORD} password = ${?OTOROSHI_REDIS_LF_PASSWORD} } slaves = [] slavesStr = ${?REDIS_LF_SLAVES} slavesStr = ${?OTOROSHI_REDIS_LF_SLAVES} slavesStr = ${?REDIS_LF_MEMBERS} slavesStr = ${?OTOROSHI_REDIS_LF_MEMBERS} } sentinels { master = ${?REDIS_SENTINELS_MASTER} master = ${?OTOROSHI_REDIS_SENTINELS_MASTER} password = ${?REDIS_SENTINELS_PASSWORD} password = ${?OTOROSHI_REDIS_SENTINELS_PASSWORD} db = ${?REDIS_SENTINELS_DB} db = ${?OTOROSHI_REDIS_SENTINELS_DB} name = ${?REDIS_SENTINELS_NAME} name = ${?OTOROSHI_REDIS_SENTINELS_NAME} members = [] membersStr = ${?REDIS_SENTINELS_MEMBERS} membersStr = ${?OTOROSHI_REDIS_SENTINELS_MEMBERS} lf { master = ${?REDIS_SENTINELS_LF_MASTER} master = ${?OTOROSHI_REDIS_SENTINELS_LF_MASTER} members = [] membersStr = ${?REDIS_SENTINELS_LF_MEMBERS} membersStr = ${?OTOROSHI_REDIS_SENTINELS_LF_MEMBERS} } } cluster { members = [] membersStr = ${?REDIS_CLUSTER_MEMBERS} membersStr = ${?OTOROSHI_REDIS_CLUSTER_MEMBERS} } lettuce { # configuration to fetch/store otoroshi state from a redis datastore using the lettuce driver (the next default one) connection = "default" connection = ${?REDIS_LETTUCE_CONNECTION} connection = ${?OTOROSHI_REDIS_LETTUCE_CONNECTION} uri = ${?REDIS_LETTUCE_URI} uri = ${?OTOROSHI_REDIS_LETTUCE_URI} uri = ${?REDIS_URL} uri = ${?OTOROSHI_REDIS_URL} uris = [] urisStr = ${?REDIS_LETTUCE_URIS} urisStr = ${?OTOROSHI_REDIS_LETTUCE_URIS} readFrom = "MASTER_PREFERRED" readFrom = ${?REDIS_LETTUCE_READ_FROM} readFrom = ${?OTOROSHI_REDIS_LETTUCE_READ_FROM} startTLS = false startTLS = ${?REDIS_LETTUCE_START_TLS} startTLS = ${?OTOROSHI_REDIS_LETTUCE_START_TLS} verifyPeers = true verifyPeers = ${?REDIS_LETTUCE_VERIFY_PEERS} verifyPeers = ${?OTOROSHI_REDIS_LETTUCE_VERIFY_PEERS} } } inmemory { # configuration to fetch/store otoroshi state in memory windowSize = 99 windowSize = ${?INMEMORY_WINDOW_SIZE} windowSize = ${?OTOROSHI_INMEMORY_WINDOW_SIZE} experimental = false experimental = ${?INMEMORY_EXPERIMENTAL_STORE} experimental = ${?OTOROSHI_INMEMORY_EXPERIMENTAL_STORE} optimized = false optimized = ${?INMEMORY_OPTIMIZED} optimized = ${?OTOROSHI_INMEMORY_OPTIMIZED} modern = false modern = ${?INMEMORY_MODERN} modern = ${?OTOROSHI_INMEMORY_MODERN} } filedb { # configuration to fetch/store otoroshi state from a file windowSize = 99 windowSize = ${?FILEDB_WINDOW_SIZE} windowSize = ${?OTOROSHI_FILEDB_WINDOW_SIZE} path = "./filedb/state.ndjson" path = ${?FILEDB_PATH} path = ${?OTOROSHI_FILEDB_PATH} } httpdb { # configuration to fetch/store otoroshi state from an http endpoint url = "http://127.0.0.1:8888/worker-0/state.json" headers = {} timeout = 10000 pollEvery = 10000 } s3db { # configuration to fetch/store otoroshi state from a S3 bucket bucket = "otoroshi-states" bucket = ${?OTOROSHI_DB_S3_BUCKET} endpoint = "https://otoroshi-states.foo.bar" endpoint = ${?OTOROSHI_DB_S3_ENDPOINT} region = "eu-west-1" region = ${?OTOROSHI_DB_S3_REGION} access = "secret" access = ${?OTOROSHI_DB_S3_ACCESS} secret = "secret" secret = ${?OTOROSHI_DB_S3_SECRET} key = "/otoroshi/states/state" key = ${?OTOROSHI_DB_S3_KEY} chunkSize = 8388608 chunkSize = ${?OTOROSHI_DB_S3_CHUNK_SIZE} v4auth = true v4auth = ${?OTOROSHI_DB_S3_V4_AUTH} writeEvery = 60000 # write interval writeEvery = ${?OTOROSHI_DB_S3_WRITE_EVERY} # write interval acl = "Private" acl = ${?OTOROSHI_DB_S3_ACL} } pg { # postrgesql settings. everything possible with the client uri = ${?PG_URI} uri = ${?OTOROSHI_PG_URI} uri = ${?POSTGRESQL_ADDON_URI} uri = ${?OTOROSHI_POSTGRESQL_ADDON_URI} poolSize = 20 poolSize = ${?PG_POOL_SIZE} poolSize = ${?OTOROSHI_PG_POOL_SIZE} port = 5432 port = ${?PG_PORT} port = ${?OTOROSHI_PG_PORT} host = "localhost" host = ${?PG_HOST} host = ${?OTOROSHI_PG_HOST} database = "otoroshi" database = ${?PG_DATABASE} database = ${?OTOROSHI_PG_DATABASE} user = "otoroshi" user = ${?PG_USER} user = ${?OTOROSHI_PG_USER} password = "otoroshi" password = ${?PG_PASSWORD} password = ${?OTOROSHI_PG_PASSWORD} logQueries = ${?PG_DEBUG_QUERIES} logQueries = ${?OTOROSHI_PG_DEBUG_QUERIES} avoidJsonPath = false avoidJsonPath = ${?PG_AVOID_JSON_PATH} avoidJsonPath = ${?OTOROSHI_PG_AVOID_JSON_PATH} optimized = true optimized = ${?PG_OPTIMIZED} optimized = ${?OTOROSHI_PG_OPTIMIZED} connect-timeout = ${?PG_CONNECT_TIMEOUT} connect-timeout = ${?OTOROSHI_PG_CONNECT_TIMEOUT} idle-timeout = ${?PG_IDLE_TIMEOUT} idle-timeout = ${?OTOROSHI_PG_IDLE_TIMEOUT} log-activity = ${?PG_LOG_ACTIVITY} log-activity = ${?OTOROSHI_PG_LOG_ACTIVITY} pipelining-limit = ${?PG_PIPELINING_LIMIT} pipelining-limit = ${?OTOROSHI_PG_PIPELINING_LIMIT} ssl { enabled = false enabled = ${?PG_SSL_ENABLED} enabled = ${?OTOROSHI_PG_SSL_ENABLED} mode = "verify_ca" mode = ${?PG_SSL_MODE} mode = ${?OTOROSHI_PG_SSL_MODE} trusted-certs-path = [] trusted-certs = [] trusted-cert-path = ${?PG_SSL_TRUSTED_CERT_PATH} trusted-cert-path = ${?OTOROSHI_PG_SSL_TRUSTED_CERT_PATH} trusted-cert = ${?PG_SSL_TRUSTED_CERT} trusted-cert = ${?OTOROSHI_PG_SSL_TRUSTED_CERT} client-certs-path = [] client-certs = [] client-cert-path = ${?PG_SSL_CLIENT_CERT_PATH} client-cert-path = ${?OTOROSHI_PG_SSL_CLIENT_CERT_PATH} client-cert = ${?PG_SSL_CLIENT_CERT} client-cert = ${?OTOROSHI_PG_SSL_CLIENT_CERT} trust-all = ${?PG_SSL_TRUST_ALL} trust-all = ${?OTOROSHI_PG_SSL_TRUST_ALL} } } cassandra { # cassandra settings. everything possible with the client windowSize = 99 windowSize = ${?CASSANDRA_WINDOW_SIZE} windowSize = ${?OTOROSHI_CASSANDRA_WINDOW_SIZE} host = "127.0.0.1" host = ${?CASSANDRA_HOST} host = ${?OTOROSHI_CASSANDRA_HOST} port = 9042 port = ${?CASSANDRA_PORT} port = ${?OTOROSHI_CASSANDRA_PORT} replicationFactor = 1 replicationFactor = ${?CASSANDRA_REPLICATION_FACTOR} replicationFactor = ${?OTOROSHI_CASSANDRA_REPLICATION_FACTOR} replicationOptions = ${?CASSANDRA_REPLICATION_OPTIONS} replicationOptions = ${?OTOROSHI_CASSANDRA_REPLICATION_OPTIONS} durableWrites = true durableWrites = ${?CASSANDRA_DURABLE_WRITES} durableWrites = ${?OTOROSHI_CASSANDRA_DURABLE_WRITES} basic.contact-points = [ ${app.cassandra.host}":"${app.cassandra.port} ] basic.session-name = "otoroshi" basic.session-name = ${?OTOROSHI_CASSANDRA_SESSION_NAME} basic.session-keyspace = ${?OTOROSHI_CASSANDRA_SESSION_KEYSPACE} basic.config-reload-interval = 5 minutes basic.request { timeout = 10 seconds consistency = LOCAL_ONE consistency = ${?OTOROSHI_CASSANDRA_CONSISTENCY} page-size = 5000 page-size = ${?OTOROSHI_CASSANDRA_PAGE_SIZE} serial-consistency = SERIAL serial-consistency = ${?OTOROSHI_CASSANDRA_SERIAL_CONSISTENCY} default-idempotence = false default-idempotence = ${?OTOROSHI_CASSANDRA_DEFAULT_IDEMPOTENCE} } basic.load-balancing-policy { class = DefaultLoadBalancingPolicy local-datacenter = datacenter1 local-datacenter = ${?OTOROSHI_CASSANDRA_LOCAL_DATACENTER} # filter.class= slow-replica-avoidance = true } basic.cloud { # secure-connect-bundle = /location/of/secure/connect/bundle } basic.application { # name = # version = } basic.graph { # name = your-graph-name traversal-source = "g" # is-system-query = false # read-consistency-level = LOCAL_QUORUM # write-consistency-level = LOCAL_ONE # timeout = 10 seconds } advanced.connection { connect-timeout = 5 seconds init-query-timeout = 500 milliseconds set-keyspace-timeout = ${datastax-java-driver.advanced.connection.init-query-timeout} pool { local { size = 1 } remote { size = 1 } } max-requests-per-connection = 1024 max-orphan-requests = 256 warn-on-init-error = true } advanced.reconnect-on-init = false advanced.reconnection-policy { class = ExponentialReconnectionPolicy base-delay = 1 second max-delay = 60 seconds } advanced.retry-policy { class = DefaultRetryPolicy } advanced.speculative-execution-policy { class = NoSpeculativeExecutionPolicy # max-executions = 3 # delay = 100 milliseconds } advanced.auth-provider { # class = PlainTextAuthProvider username = ${?CASSANDRA_USERNAME} username = ${?OTOROSHI_CASSANDRA_USERNAME} password = ${?CASSANDRA_PASSWORD} password = ${?OTOROSHI_CASSANDRA_PASSWORD} authorization-id = ${?OTOROSHI_CASSANDRA_AUTHORIZATION_ID} //service = "cassandra" # login-configuration { # principal = "cassandra@DATASTAX.COM" # useKeyTab = "true" # refreshKrb5Config = "true" # keyTab = "/path/to/keytab/file" # } # sasl-properties { # javax.security.sasl.qop = "auth-conf" # } } advanced.ssl-engine-factory { # class = DefaultSslEngineFactory # cipher-suites = [ "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA" ] # hostname-validation = true # truststore-path = /path/to/client.truststore # truststore-password = password123 # keystore-path = /path/to/client.keystore # keystore-password = password123 } advanced.timestamp-generator { class = AtomicTimestampGenerator drift-warning { threshold = 1 second interval = 10 seconds } force-java-clock = false } advanced.request-tracker { class = NoopRequestTracker logs { # success.enabled = true slow { # threshold = 1 second # enabled = true } # error.enabled = true # max-query-length = 500 # show-values = true # max-value-length = 50 # max-values = 50 # show-stack-traces = true } } advanced.throttler { class = PassThroughRequestThrottler # max-queue-size = 10000 # max-concurrent-requests = 10000 # max-requests-per-second = 10000 # drain-interval = 10 milliseconds } advanced.node-state-listener.class = NoopNodeStateListener advanced.schema-change-listener.class = NoopSchemaChangeListener advanced.address-translator { class = PassThroughAddressTranslator } advanced.resolve-contact-points = true advanced.protocol { version = V4 version = ${?OTOROSHI_CASSANDRA_PROTOCOL_VERSION} compression = lz4 compression = ${?OTOROSHI_CASSANDRA_PROTOCOL_COMPRESSION} max-frame-length = 256 MB } advanced.request { warn-if-set-keyspace = false trace { attempts = 5 interval = 3 milliseconds consistency = ONE } log-warnings = true } advanced.graph { # sub-protocol = "graphson-2.0" paging-enabled = "AUTO" paging-options { page-size = ${datastax-java-driver.advanced.continuous-paging.page-size} max-pages = ${datastax-java-driver.advanced.continuous-paging.max-pages} max-pages-per-second = ${datastax-java-driver.advanced.continuous-paging.max-pages-per-second} max-enqueued-pages = ${datastax-java-driver.advanced.continuous-paging.max-enqueued-pages} } } advanced.continuous-paging { page-size = ${datastax-java-driver.basic.request.page-size} page-size-in-bytes = false max-pages = 0 max-pages-per-second = 0 max-enqueued-pages = 4 timeout { first-page = 2 seconds other-pages = 1 second } } advanced.monitor-reporting { enabled = true } advanced.metrics { session { enabled = [ # bytes-sent, # bytes-received # connected-nodes, # cql-requests, # cql-client-timeouts, # cql-prepared-cache-size, # throttling.delay, # throttling.queue-size, # throttling.errors, # continuous-cql-requests, # graph-requests, # graph-client-timeouts ] cql-requests { highest-latency = 3 seconds significant-digits = 3 refresh-interval = 5 minutes } throttling.delay { highest-latency = 3 seconds significant-digits = 3 refresh-interval = 5 minutes } continuous-cql-requests { highest-latency = 120 seconds significant-digits = 3 refresh-interval = 5 minutes } graph-requests { highest-latency = 12 seconds significant-digits = 3 refresh-interval = 5 minutes } } node { enabled = [ # pool.open-connections, # pool.available-streams, # pool.in-flight, # pool.orphaned-streams, # bytes-sent, # bytes-received, # cql-messages, # errors.request.unsent, # errors.request.aborted, # errors.request.write-timeouts, # errors.request.read-timeouts, # errors.request.unavailables, # errors.request.others, # retries.total, # retries.aborted, # retries.read-timeout, # retries.write-timeout, # retries.unavailable, # retries.other, # ignores.total, # ignores.aborted, # ignores.read-timeout, # ignores.write-timeout, # ignores.unavailable, # ignores.other, # speculative-executions, # errors.connection.init, # errors.connection.auth, # graph-messages, ] cql-messages { highest-latency = 3 seconds significant-digits = 3 refresh-interval = 5 minutes } graph-messages { highest-latency = 3 seconds significant-digits = 3 refresh-interval = 5 minutes } } } advanced.socket { tcp-no-delay = true //keep-alive = false //reuse-address = true //linger-interval = 0 //receive-buffer-size = 65535 //send-buffer-size = 65535 } advanced.heartbeat { interval = 30 seconds timeout = ${datastax-java-driver.advanced.connection.init-query-timeout} } advanced.metadata { topology-event-debouncer { window = 1 second max-events = 20 } schema { enabled = true # refreshed-keyspaces = [ "ks1", "ks2" ] request-timeout = ${datastax-java-driver.basic.request.timeout} request-page-size = ${datastax-java-driver.basic.request.page-size} debouncer { window = 1 second max-events = 20 } } token-map.enabled = true } advanced.control-connection { timeout = ${datastax-java-driver.advanced.connection.init-query-timeout} schema-agreement { interval = 200 milliseconds timeout = 10 seconds warn-on-failure = true } } advanced.prepared-statements { prepare-on-all-nodes = true reprepare-on-up { enabled = true check-system-table = false max-statements = 0 max-parallelism = 100 timeout = ${datastax-java-driver.advanced.connection.init-query-timeout} } } advanced.netty { daemon = false io-group { size = 0 shutdown {quiet-period = 2, timeout = 15, unit = SECONDS} } admin-group { size = 2 shutdown {quiet-period = 2, timeout = 15, unit = SECONDS} } timer { tick-duration = 100 milliseconds ticks-per-wheel = 2048 } } advanced.coalescer { max-runs-with-no-work = 5 reschedule-interval = 10 microseconds } } actorsystems { otoroshi { akka { # otoroshi actorsystem configuration version = ${akka.version} log-dead-letters-during-shutdown = false jvm-exit-on-fatal-error = false default-dispatcher { type = Dispatcher executor = "fork-join-executor" fork-join-executor { parallelism-factor = 4.0 parallelism-factor = ${?OTOROSHI_CORE_DISPATCHER_PARALLELISM_FACTOR} parallelism-min = 8 parallelism-min = ${?OTOROSHI_CORE_DISPATCHER_PARALLELISM_MIN} parallelism-max = 128 parallelism-max = ${?OTOROSHI_CORE_DISPATCHER_PARALLELISM_MAX} task-peeking-mode = "FIFO" task-peeking-mode = ${?OTOROSHI_CORE_DISPATCHER_TASK_PEEKING_MODE} } throughput = 1 throughput = ${?OTOROSHI_CORE_DISPATCHER_THROUGHPUT} } http { parsing { max-uri-length = 4k max-uri-length = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_URI_LENGTH} max-method-length = 16 max-method-length = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_METHOD_LENGTH} max-response-reason-length = 64 max-response-reason-length = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_RESPONSE_REASON_LENGTH} max-header-name-length = 128 max-header-name-length = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_HEADER_NAME_LENGTH} max-header-value-length = 16k max-header-value-length = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_HEADER_VALUE_LENGTH} max-header-count = 128 max-header-count = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_HEADER_COUNT} max-chunk-ext-length = 256 max-chunk-ext-length = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_CHUNK_EXT_LENGTH} max-chunk-size = 256m max-chunk-size = ${?AKKA_HTTP_CLIENT_MAX_CHUNK_SIZE} max-chunk-size = ${?OTOROSHI_AKKA_HTTP_CLIENT_MAX_CHUNK_SIZE} max-chunk-size = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_CHUNK_SIZE} max-content-length = infinite max-content-length = ${?AKKA_HTTP_CLIENT_MAX_CONTENT_LENGHT} max-content-length = ${?OTOROSHI_AKKA_HTTP_CLIENT_MAX_CONTENT_LENGHT} max-content-length = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_CONTENT_LENGHT} max-to-strict-bytes = infinite max-to-strict-bytes = ${?AKKA_HTTP_CLIENT_MAX_TO_STRICT_BYTES} max-to-strict-bytes = ${?OTOROSHI_AKKA_HTTP_CLIENT_MAX_TO_STRICT_BYTES} max-to-strict-bytes = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_TO_STRICT_BYTES} } } } } datastore { akka { version = ${akka.version} log-dead-letters-during-shutdown = false jvm-exit-on-fatal-error = false default-dispatcher { type = Dispatcher executor = "fork-join-executor" fork-join-executor { parallelism-factor = 4.0 parallelism-min = 4 parallelism-max = 64 task-peeking-mode = "FIFO" } throughput = 1 } } } } } otoroshi { domain = ${?app.domain} maintenanceMode = false # enable global maintenance mode maintenanceMode = ${?OTOROSHI_MAINTENANCE_MODE_ENABLED} # enable global maintenance mode secret = "verysecretvaluethatyoumustoverwrite" # the secret used to sign sessions secret = ${?OTOROSHI_SECRET} # the secret used to sign sessions admin-api-secret = ${?OTOROSHI_ADMIN_API_SECRET} # the secret for admin api elSettings { allowEnvAccess = true allowEnvAccess = ${?OTOROSHI_EL_SETTINGS_ALLOW_ENV_ACCESS} allowConfigAccess = true allowConfigAccess = ${?OTOROSHI_EL_SETTINGS_ALLOW_CONFIG_ACCESS} } open-telemetry { server-logs { enabled = false enabled = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_ENABLED} gzip = false gzip = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_GZIP} grpc = false grpc = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_GRPC} endpoint = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_ENDPOINT} timeout = 5000 timeout = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_TIMEOUT} client_cert = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_CLIENT_CERT} trusted_cert = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_TRUSTED_CERT} headers = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_HEADERS} max_batch = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_MAX_BATCH} max_duration = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_MAX_DURATION} } server-metrics { enabled = false enabled = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_ENABLED} gzip = false gzip = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_GZIP} grpc = false grpc = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_GRPC} endpoint = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_ENDPOINT} timeout = 5000 timeout = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_TIMEOUT} client_cert = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_CLIENT_CERT} trusted_cert = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_TRUSTED_CERT} headers = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_HEADERS} max_batch = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_MAX_BATCH} max_duration = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_MAX_DURATION} } } next { state-sync-interval = 10000 state-sync-interval = ${?OTOROSHI_NEXT_STATE_SYNC_INTERVAL} export-reporting = false export-reporting = ${?OTOROSHI_NEXT_EXPORT_REPORTING} monitor-proxy-state-size = false monitor-proxy-state-size = ${?OTOROSHI_NEXT_MONITOR_PROXY_STATE_SIZE} monitor-datastore-size = false monitor-datastore-size = ${?OTOROSHI_NEXT_MONITOR_DATASTORE_SIZE} plugins { merge-sync-steps = true merge-sync-steps = ${?OTOROSHI_NEXT_PLUGINS_MERGE_SYNC_STEPS} apply-legacy-checks = true apply-legacy-checks = ${?OTOROSHI_NEXT_PLUGINS_APPLY_LEGACY_CHECKS} } experimental { netty-client { wiretap = false wiretap = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_CLIENT_WIRETAP} enforce = false enforce = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_CLIENT_ENFORCE} enforce-akka = false enforce-akka = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_CLIENT_ENFORCE_AKKA} } netty-server { enabled = false enabled = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_ENABLED} new-engine-only = false new-engine-only = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_NEW_ENGINE_ONLY} host = "0.0.0.0" host = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HOST} http-port = 10049 http-port = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_PORT} exposed-http-port = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_EXPOSED_HTTP_PORT} https-port = 10048 https-port = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTPS_PORT} exposed-https-port = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_EXPOSED_HTTPS_PORT} wiretap = false wiretap = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_WIRETAP} accesslog = false accesslog = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_ACCESSLOG} threads = 0 threads = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_THREADS} parser { allowDuplicateContentLengths = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_ALLOW_DUPLICATE_CONTENT_LENGTHS} validateHeaders = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_VALIDATE_HEADERS} h2cMaxContentLength = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_H_2_C_MAX_CONTENT_LENGTH} initialBufferSize = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_INITIAL_BUFFER_SIZE} maxHeaderSize = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_MAX_HEADER_SIZE} maxInitialLineLength = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_MAX_INITIAL_LINE_LENGTH} maxChunkSize = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_MAX_CHUNK_SIZE} } http2 { enabled = true enabled = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP2_ENABLED} h2c = true h2c = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP2_H2C} } http3 { enabled = false enabled = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP3_ENABLED} port = 10048 port = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP3_PORT} exposedPort = 10048 exposedPort = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP3_EXPOSED_PORT} initialMaxStreamsBidirectional = 100000 initialMaxStreamsBidirectional = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_INITIAL_MAX_STREAMS_BIDIRECTIONAL} initialMaxStreamDataBidirectionalRemote = 1000000 initialMaxStreamDataBidirectionalRemote = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_INITIAL_MAX_STREAM_DATA_BIDIRECTIONAL_REMOTE} initialMaxStreamDataBidirectionalLocal = 1000000 initialMaxStreamDataBidirectionalLocal = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_INITIAL_MAX_STREAM_DATA_BIDIRECTIONAL_LOCAL} initialMaxData = 10000000 initialMaxData = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_INITIAL_MAX_DATA} maxRecvUdpPayloadSize = 1500 maxRecvUdpPayloadSize = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_MAX_RECV_UDP_PAYLOAD_SIZE} maxSendUdpPayloadSize = 1500 maxSendUdpPayloadSize = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_MAX_SEND_UDP_PAYLOAD_SIZE} disableQpackDynamicTable = true disableQpackDynamicTable = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_DISABLE_QPACK_DYNAMIC_TABLE} } native { enabled = true enabled = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_NATIVE_ENABLED} driver = "Auto" # possible values are Auto, Epoll, KQueue, IOUring driver = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_NATIVE_DRIVER} } } } } options { jsonPathNullReadIsJsNull = false jsonPathNullReadIsJsNull = ${?OTOROSHI_OPTIONS_JSONPATHNULLREADISJSNULL} bypassUserRightsCheck = false bypassUserRightsCheck = ${?OTOROSHI_OPTIONS_BYPASSUSERRIGHTSCHECK} emptyContentLengthIsChunked = true emptyContentLengthIsChunked = ${?OTOROSHI_OPTIONS_EMPTYCONTENTLENGTHISCHUNKED} detectApiKeySooner = true detectApiKeySooner = ${?OTOROSHI_OPTIONS_DETECTAPIKEYSOONER} sendClientChainAsPem = false sendClientChainAsPem = ${?OTOROSHI_OPTIONS_SENDCLIENTCHAINASPEM} useOldHeadersComposition = false useOldHeadersComposition = ${?OTOROSHI_OPTIONS_USEOLDHEADERSCOMPOSITION} manualDnsResolve = true manualDnsResolve = ${?OTOROSHI_OPTIONS_MANUALDNSRESOLVE} useEventStreamForScriptEvents = true useEventStreamForScriptEvents = ${?OTOROSHI_OPTIONS_USEEVENTSTREAMFORSCRIPTEVENTS} trustXForwarded = true trustXForwarded = ${?OTOROSHI_OPTIONS_TRUST_XFORWARDED} disableFunnyLogos = false disableFunnyLogos = ${?OTOROSHI_OPTIONS_DISABLE_FUNNY_LOGOS} staticExposedDomain = ${?OTOROSHI_OPTIONS_STATIC_EXPOSED_DOMAIN} enable-json-media-type-with-open-charset = false # allow application/json media type with charset even if its not standard enable-json-media-type-with-open-charset = ${?OTOROSHI_OPTIONS_ENABLE_JSON_MEDIA_TYPE_WITH_OPEN_CHARSET} dynamicBodySizeCompute = true dynamicBodySizeCompute = ${?OTOROSHI_OPTIONS_DYNAMIC_BODY_SIZE_COMPUTE} } wasm { cache { ttl = 10000 ttl = ${?OTOROSHI_WASM_CACHE_TTL} size = 100 size = ${?OTOROSHI_WASM_CACHE_SIZE} } queue { buffer { size = 2048 size = ${?OTOROSHI_WASM_QUEUE_BUFFER_SIZE} } } } anonymous-reporting { enabled = true enabled = ${?OTOROSHI_ANONYMOUS_REPORTING_ENABLED} redirect = false url = ${?OTOROSHI_ANONYMOUS_REPORTING_REDIRECT} url = "https://reporting.otoroshi.io/ingest" url = ${?OTOROSHI_ANONYMOUS_REPORTING_URL} timeout = 60000 timeout = ${?OTOROSHI_ANONYMOUS_REPORTING_TIMEOUT} tls { # certs = [] # trustedCerts = [] enabled = false # enable mtls enabled = ${?OTOROSHI_ANONYMOUS_REPORTING_TLS_ENABLED} # enable mtls loose = false # loose verification loose = ${?OTOROSHI_ANONYMOUS_REPORTING_TLS_LOOSE} # loose verification trustAll = false # trust any CA trustAll = ${?OTOROSHI_ANONYMOUS_REPORTING_TLS_ALL} # trust any CA } proxy { enabled = false # enable proxy enabled = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_ENABLED} # enable proxy host = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_HOST}, port = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_PORT}, principal = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_PRINCIPAL}, password = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_PASSWORD}, ntlmDomain = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_DOMAIN}, encoding = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_ENCODING}, } } backoffice { flags { useAkkaHttpClient = false useAkkaHttpClient = ${?OTOROSHI_BACKOFFICE_FLAGS_USE_AKKA_HTTP_CLIENT} logUrl = false logUrl = ${?OTOROSHI_BACKOFFICE_FLAGS_LOG_URL} requestTimeout = 60000 requestTimeout = ${?OTOROSHI_BACKOFFICE_FLAGS_REQUEST_TIMEOUT} } } sessions { secret = ${otoroshi.secret} secret = ${?OTOROSHI_SESSIONS_SECRET} } cache { enabled = false enabled = ${?USE_CACHE} enabled = ${?OTOROSHI_USE_CACHE} enabled = ${?OTOROSHI_ENTITIES_CACHE_ENABLED} ttl = 2000 ttl = ${?OTOROSHI_ENTITIES_CACHE_TTL} } metrics { enabled = true enabled = ${?OTOROSHI_METRICS_ENABLED} every = 30000 every = ${?OTOROSHI_METRICS_EVERY} accessKey = ${?app.health.accessKey} accessKey = ${?OTOROSHI_app.health.accessKey} accessKey = ${?OTOROSHI_METRICS_ACCESS_KEY} } plugins { packages = [] packagesStr = ${?OTOROSHI_PLUGINS_SCAN_PACKAGES} print = false print = ${?OTOROSHI_PLUGINS_PRINT} blacklisted = [] blacklistedStr = ${?OTOROSHI_PLUGINS_BACKLISTED} } scripts { enabled = true # enable scripts enabled = ${?OTOROSHI_SCRIPTS_ENABLED} # enable scripts static { # settings for statically enabled script/plugins enabled = false enabled = ${?OTOROSHI_SCRIPTS_STATIC_ENABLED} transformersRefs = [] transformersRefsStr = ${?OTOROSHI_SCRIPTS_STATIC_TRANSFORMER_REFS} transformersConfig = {} transformersConfigStr= ${?OTOROSHI_SCRIPTS_STATIC_TRANSFORMER_CONFIG} validatorRefs = [] validatorRefsStr = ${?OTOROSHI_SCRIPTS_STATIC_VALIDATOR_REFS} validatorConfig = {} validatorConfigStr = ${?OTOROSHI_SCRIPTS_STATIC_VALIDATOR_CONFIG} preRouteRefs = [] preRouteRefsStr = ${?OTOROSHI_SCRIPTS_STATIC_PRE_ROUTE_REFS} preRouteConfig = {} preRouteConfigStr = ${?OTOROSHI_SCRIPTS_STATIC_PRE_ROUTE_CONFIG} sinkRefs = [] sinkRefsStr = ${?OTOROSHI_SCRIPTS_STATIC_SINK_REFS} sinkConfig = {} sinkConfigStr = ${?OTOROSHI_SCRIPTS_STATIC_SINK_CONFIG} jobsRefs = [] jobsRefsStr = ${?OTOROSHI_SCRIPTS_STATIC_JOBS_REFS} jobsConfig = {} jobsConfigStr = ${?OTOROSHI_SCRIPTS_STATIC_JOBS_CONFIG} } } tls = ${otoroshi.ssl} ssl { # the cipher suites used by otoroshi TLS termination cipherSuitesJDK11Plus = ["TLS_AES_256_GCM_SHA384", "TLS_AES_128_GCM_SHA256", "TLS_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_256_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"] cipherSuitesJDK11 = ["TLS_AES_256_GCM_SHA384", "TLS_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_256_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"] cipherSuitesJDK8 = ["TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLS_RSA_WITH_AES_256_CBC_SHA256", "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"] # cipherSuites = ["TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384"] cipherSuites = ${otoroshi.ssl.cipherSuitesJDK11} # the protocols used by otoroshi TLS termination protocolsJDK11 = ["TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1"] protocolsJDK8 = ["SSLv2Hello", "TLSv1", "TLSv1.1", "TLSv1.2"] modernProtocols = ["TLSv1.3", "TLSv1.2"] protocols = ${otoroshi.ssl.modernProtocols} # the JDK cacert access cacert { path = "$JAVA_HOME/lib/security/cacerts" password = "changeit" } # the mtls mode fromOutside { clientAuth = "None" clientAuth = ${?SSL_OUTSIDE_CLIENT_AUTH} clientAuth = ${?OTOROSHI_SSL_OUTSIDE_CLIENT_AUTH} netty { clientAuth = ${?OTOROSHI_SSL_OUTSIDE_NETTY_CLIENT_AUTH} } } # the default trust mode trust { all = false all = ${?OTOROSHI_SSL_TRUST_ALL} } rootCa { ca = ${?OTOROSHI_SSL_ROOTCA_CA} cert = ${?OTOROSHI_SSL_ROOTCA_CERT} key = ${?OTOROSHI_SSL_ROOTCA_KEY} importCa = false importCa = ${?OTOROSHI_SSL_ROOTCA_IMPORTCA} } # some initial cacert access, useful to include non standard CA when starting initialCacert = ${?CLUSTER_WORKER_INITIAL_CACERT} initialCacert = ${?OTOROSHI_CLUSTER_WORKER_INITIAL_CACERT} initialCacert = ${?INITIAL_CACERT} initialCacert = ${?OTOROSHI_INITIAL_CACERT} initialCert = ${?CLUSTER_WORKER_INITIAL_CERT} initialCert = ${?OTOROSHI_CLUSTER_WORKER_INITIAL_CERT} initialCert = ${?INITIAL_CERT} initialCert = ${?OTOROSHI_INITIAL_CERT} initialCertKey = ${?CLUSTER_WORKER_INITIAL_CERT_KEY} initialCertKey = ${?OTOROSHI_CLUSTER_WORKER_INITIAL_CERT_KEY} initialCertKey = ${?INITIAL_CERT_KEY} initialCertKey = ${?OTOROSHI_INITIAL_CERT_KEY} initialCertImportCa = ${?OTOROSHI_INITIAL_CERT_IMPORTCA} # initialCerts = [] } cluster { mode = "off" # can be "off", "leader", "worker" mode = ${?CLUSTER_MODE} # can be "off", "leader", "worker" mode = ${?OTOROSHI_CLUSTER_MODE} # can be "off", "leader", "worker" compression = -1 # compression of the data sent between leader cluster and worker cluster. From -1 (disabled) to 9 compression = ${?CLUSTER_COMPRESSION} # compression of the data sent between leader cluster and worker cluster. From -1 (disabled) to 9 compression = ${?OTOROSHI_CLUSTER_COMPRESSION} # compression of the data sent between leader cluster and worker cluster. From -1 (disabled) to 9 retryDelay = 300 # the delay before retrying a request to leader retryDelay = ${?CLUSTER_RETRY_DELAY} # the delay before retrying a request to leader retryDelay = ${?OTOROSHI_CLUSTER_RETRY_DELAY} # the delay before retrying a request to leader retryFactor = 2 # the retry factor to avoid high load on failing nodes retryFactor = ${?CLUSTER_RETRY_FACTOR} # the retry factor to avoid high load on failing nodes retryFactor = ${?OTOROSHI_CLUSTER_RETRY_FACTOR} # the retry factor to avoid high load on failing nodes selfAddress = ${?CLUSTER_SELF_ADDRESS} # the instance ip address selfAddress = ${?OTOROSHI_CLUSTER_SELF_ADDRESS} # the instance ip address autoUpdateState = true # auto update cluster state with a job (more efficient) autoUpdateState = ${?CLUSTER_AUTO_UPDATE_STATE} # auto update cluster state with a job (more efficient autoUpdateState = ${?OTOROSHI_CLUSTER_AUTO_UPDATE_STATE} # auto update cluster state with a job (more efficient backup { enabled = false enabled = ${?OTOROSHI_CLUSTER_BACKUP_ENABLED} kind = "S3" kind = ${?OTOROSHI_CLUSTER_BACKUP_KIND} instance { can-write = false can-write = ${?OTOROSHI_CLUSTER_BACKUP_INSTANCE_CAN_WRITE} can-read = false can-read = ${?OTOROSHI_CLUSTER_BACKUP_INSTANCE_CAN_READ} } s3 { bucket = ${?OTOROSHI_CLUSTER_BACKUP_S3_BUCKET} endpoint = ${?OTOROSHI_CLUSTER_BACKUP_S3_ENDPOINT} region = ${?OTOROSHI_CLUSTER_BACKUP_S3_REGION} access = ${?OTOROSHI_CLUSTER_BACKUP_S3_ACCESSKEY} secret = ${?OTOROSHI_CLUSTER_BACKUP_S3_SECRET} path = ${?OTOROSHI_CLUSTER_BACKUP_S3_PATH} chunk-size = ${?OTOROSHI_CLUSTER_BACKUP_S3_CHUNK_SIZE} v4auth = ${?OTOROSHI_CLUSTER_BACKUP_S3_V4AUTH} acl = ${?OTOROSHI_CLUSTER_BACKUP_S3_ACL} } } relay { # relay routing settings enabled = false # enable relay routing enabled = ${?OTOROSHI_CLUSTER_RELAY_ENABLED} # enable relay routing leaderOnly = false leaderOnly = ${?OTOROSHI_CLUSTER_RELAY_LEADER_ONLY} # workers always pass through leader for relay routing location { provider = ${?otoroshi.instance.provider} provider = ${?OTOROSHI_CLUSTER_RELAY_LOCATION_PROVIDER} provider = ${?app.instance.provider} zone = ${?otoroshi.instance.zone} zone = ${?OTOROSHI_CLUSTER_RELAY_LOCATION_ZONE} zone = ${?app.instance.zone} region = ${?otoroshi.instance.region} region = ${?OTOROSHI_CLUSTER_RELAY_LOCATION_REGION} region = ${?app.instance.region} datacenter = ${?otoroshi.instance.dc} datacenter = ${?OTOROSHI_CLUSTER_RELAY_LOCATION_DATACENTER} datacenter = ${?app.instance.dc} rack = ${?otoroshi.instance.rack} rack = ${?OTOROSHI_CLUSTER_RELAY_LOCATION_RACK} rack = ${?app.instance.rack} } exposition { url = ${?OTOROSHI_CLUSTER_RELAY_EXPOSITION_URL} urls = [] urlsStr = ${?OTOROSHI_CLUSTER_RELAY_EXPOSITION_URLS} hostname = "otoroshi-api.oto.tools" hostname = ${?OTOROSHI_CLUSTER_RELAY_EXPOSITION_HOSTNAME} clientId = ${?OTOROSHI_CLUSTER_RELAY_EXPOSITION_CLIENT_ID} clientSecret = ${?OTOROSHI_CLUSTER_RELAY_EXPOSITION_CLIENT_SECRET} ipAddress = ${?OTOROSHI_CLUSTER_RELAY_EXPOSITION_IP_ADDRESS} } } mtls { # certs = [] # trustedCerts = [] enabled = false # enable mtls enabled = ${?CLUSTER_MTLS_ENABLED} # enable mtls enabled = ${?OTOROSHI_CLUSTER_MTLS_ENABLED} # enable mtls loose = false # loose verification loose = ${?CLUSTER_MTLS_LOOSE} # loose verification loose = ${?OTOROSHI_CLUSTER_MTLS_LOOSE} # loose verification trustAll = false # trust any CA trustAll = ${?CLUSTER_MTLS_TRUST_ALL} # trust any CA trustAll = ${?OTOROSHI_CLUSTER_MTLS_TRUST_ALL} # trust any CA } proxy { enabled = false # enable proxy enabled = ${?CLUSTER_PROXY_ENABLED} # enable proxy host = ${?CLUSTER_PROXY_HOST}, port = ${?CLUSTER_PROXY_PORT}, principal = ${?CLUSTER_PROXY_PRINCIPAL}, password = ${?CLUSTER_PROXY_PASSWORD}, ntlmDomain = ${?CLUSTER_PROXY_NTLM_DOMAIN}, encoding = ${?CLUSTER_PROXY_ENCODING}, } leader { name = ${?CLUSTER_LEADER_NAME} # the leader name name = ${?OTOROSHI_CLUSTER_LEADER_NAME} # the leader name urls = ["http://127.0.0.1:8080"] # the leader urls urlsStr = ${?CLUSTER_LEADER_URLS} # the leader urls urlsStr = ${?OTOROSHI_CLUSTER_LEADER_URLS} # the leader urls url = ${?CLUSTER_LEADER_URL} # the leader url url = ${?OTOROSHI_CLUSTER_LEADER_URL} # the leader url host = "otoroshi-api.oto.tools" # the leaders api hostname host = ${?CLUSTER_LEADER_HOST} # the leaders api hostname host = ${?OTOROSHI_CLUSTER_LEADER_HOST} # the leaders api hostname clientId = "admin-api-apikey-id" # the leaders apikey id to access otoroshi admin api clientId = ${?CLUSTER_LEADER_CLIENT_ID} # the leaders apikey id to access otoroshi admin api clientId = ${?OTOROSHI_CLUSTER_LEADER_CLIENT_ID} # the leaders apikey id to access otoroshi admin api clientSecret = "admin-api-apikey-secret" # the leaders apikey secret to access otoroshi admin api clientSecret = ${?CLUSTER_LEADER_CLIENT_SECRET} # the leaders apikey secret to access otoroshi admin api clientSecret = ${?OTOROSHI_CLUSTER_LEADER_CLIENT_SECRET} # the leaders apikey secret to access otoroshi admin api groupingBy = 50 # items grouping when streaming state groupingBy = ${?CLUSTER_LEADER_GROUP_BY} # items grouping when streaming state groupingBy = ${?OTOROSHI_CLUSTER_LEADER_GROUP_BY} # items grouping when streaming state cacheStateFor = 10000 # the ttl for local state cache cacheStateFor = ${?CLUSTER_LEADER_CACHE_STATE_FOR} # the ttl for local state cache cacheStateFor = ${?OTOROSHI_CLUSTER_LEADER_CACHE_STATE_FOR} # the ttl for local state cache stateDumpPath = ${?CLUSTER_LEADER_DUMP_PATH} # eventually a dump state path for debugging purpose stateDumpPath = ${?OTOROSHI_CLUSTER_LEADER_DUMP_PATH} # eventually a dump state path for debugging purpose } worker { name = ${?CLUSTER_WORKER_NAME} # the workers name name = ${?OTOROSHI_CLUSTER_WORKER_NAME} # the workers name retries = 3 # the number of retries when pushing quotas/pulling state retries = ${?CLUSTER_WORKER_RETRIES} # the number of retries when pushing quotas/pulling state retries = ${?OTOROSHI_CLUSTER_WORKER_RETRIES} # the number of retries when pushing quotas/pulling state timeout = 10000 # the workers timeout when interacting with leaders timeout = ${?CLUSTER_WORKER_TIMEOUT} # the workers timeout when interacting with leaders timeout = ${?OTOROSHI_CLUSTER_WORKER_TIMEOUT} # the workers timeout when interacting with leaders tenants = [] # the list of organization served by this worker. If none, it's all tenantsStr = ${?CLUSTER_WORKER_TENANTS} # the list (coma separated) of organization served by this worker. If none, it's all tenantsStr = ${?OTOROSHI_CLUSTER_WORKER_TENANTS} # the list (coma separated) of organization served by this worker. If none, it's all dbpath = ${?CLUSTER_WORKER_DB_PATH} # state dump path for debugging purpose dbpath = ${?OTOROSHI_CLUSTER_WORKER_DB_PATH} # state dump path for debugging purpose dataStaleAfter = 600000 # the amount of time needed to consider state is stale dataStaleAfter = ${?CLUSTER_WORKER_DATA_STALE_AFTER} # the amount of time needed to consider state is stale dataStaleAfter = ${?OTOROSHI_CLUSTER_WORKER_DATA_STALE_AFTER} # the amount of time needed to consider state is stale swapStrategy = "Merge" # the internal memory store strategy, can be Replace or Merge swapStrategy = ${?CLUSTER_WORKER_SWAP_STRATEGY} # the internal memory store strategy, can be Replace or Merge swapStrategy = ${?OTOROSHI_CLUSTER_WORKER_SWAP_STRATEGY} # the internal memory store strategy, can be Replace or Merge modern = false # use a modern store implementation modern = ${?CLUSTER_WORKER_STORE_MODERN} modern = ${?OTOROSHI_CLUSTER_WORKER_STORE_MODERN} useWs = false useWs = ${?CLUSTER_WORKER_USE_WS} useWs = ${?OTOROSHI_CLUSTER_WORKER_USE_WS} state { retries = ${otoroshi.cluster.worker.retries} # the number of retries when pulling state retries = ${?CLUSTER_WORKER_STATE_RETRIES} # the number of retries when pulling state retries = ${?OTOROSHI_CLUSTER_WORKER_STATE_RETRIES} # the number of retries when pulling state pollEvery = 10000 # polling interval pollEvery = ${?CLUSTER_WORKER_POLL_EVERY} # polling interval pollEvery = ${?OTOROSHI_CLUSTER_WORKER_POLL_EVERY} # polling interval timeout = ${otoroshi.cluster.worker.timeout} # the workers timeout when polling state timeout = ${?CLUSTER_WORKER_POLL_TIMEOUT} # the workers timeout when polling state timeout = ${?OTOROSHI_CLUSTER_WORKER_POLL_TIMEOUT} # the workers timeout when polling state } quotas { retries = ${otoroshi.cluster.worker.retries} # the number of retries when pushing quotas retries = ${?CLUSTER_WORKER_QUOTAS_RETRIES} # the number of retries when pushing quotas retries = ${?OTOROSHI_CLUSTER_WORKER_QUOTAS_RETRIES} # the number of retries when pushing quotas pushEvery = 10000 # pushing interval pushEvery = ${?CLUSTER_WORKER_PUSH_EVERY} # pushing interval pushEvery = ${?OTOROSHI_CLUSTER_WORKER_PUSH_EVERY} # pushing interval timeout = ${otoroshi.cluster.worker.timeout} # the workers timeout when pushing quotas timeout = ${?CLUSTER_WORKER_PUSH_TIMEOUT} # the workers timeout when pushing quotas timeout = ${?OTOROSHI_CLUSTER_WORKER_PUSH_TIMEOUT} # the workers timeout when pushing quotas } } analytics { # settings for the analytics actor system which is separated from otoroshi default one for performance reasons pressure { enabled = true enabled = ${?OTOROSHI_ANALYTICS_PRESSURE_ENABLED} } actorsystem { akka { version = ${akka.version} log-dead-letters-during-shutdown = false jvm-exit-on-fatal-error = false default-dispatcher { type = Dispatcher executor = "fork-join-executor" fork-join-executor { parallelism-factor = 4.0 parallelism-min = 4 parallelism-max = 64 task-peeking-mode = "FIFO" } throughput = 1 } # http { # parsing { # max-uri-length = 4k # max-method-length = 16 # max-response-reason-length = 64 # max-header-name-length = 128 # max-header-value-length = 16k # max-header-count = 128 # max-chunk-ext-length = 256 # max-chunk-size = 256m # max-chunk-size = ${?AKKA_HTTP_CLIENT_ANALYTICS_MAX_CHUNK_SIZE} # max-chunk-size = ${?OTOROSHI_AKKA_HTTP_CLIENT_ANALYTICS_MAX_CHUNK_SIZE} # max-content-length = infinite # max-content-length = ${?AKKA_HTTP_CLIENT_ANALYTICS_MAX_CONTENT_LENGHT} # max-content-length = ${?OTOROSHI_AKKA_HTTP_CLIENT_ANALYTICS_MAX_CONTENT_LENGHT} # max-to-strict-bytes = infinite # max-to-strict-bytes = ${?AKKA_HTTP_CLIENT_ANALYTICS_MAX_TO_STRICT_BYTES} # max-to-strict-bytes = ${?OTOROSHI_AKKA_HTTP_CLIENT_ANALYTICS_MAX_TO_STRICT_BYTES} # } # } } } } } headers { # the default headers value for specific otoroshi headers trace.label = "Otoroshi-Viz-From-Label" trace.from = "Otoroshi-Viz-From" trace.parent = "Otoroshi-Parent-Request" request.adminprofile = "Otoroshi-Admin-Profile" request.simpleapiclientid = "x-api-key" request.clientid = "Otoroshi-Client-Id" request.clientsecret = "Otoroshi-Client-Secret" request.id = "Otoroshi-Request-Id" request.timestamp = "Otoroshi-Request-Timestamp" request.bearer = "Otoroshi-Token" request.authorization = "Otoroshi-Authorization" response.proxyhost = "Otoroshi-Proxied-Host" response.error = "Otoroshi-Error" response.errormsg = "Otoroshi-Error-Msg" response.errorcause = "Otoroshi-Error-Cause" response.proxylatency = "Otoroshi-Proxy-Latency" response.upstreamlatency = "Otoroshi-Upstream-Latency" response.dailyquota = "Otoroshi-Daily-Calls-Remaining" response.monthlyquota = "Otoroshi-Monthly-Calls-Remaining" comm.state = "Otoroshi-State" comm.stateresp = "Otoroshi-State-Resp" comm.claim = "Otoroshi-Claim" healthcheck.test = "Otoroshi-Health-Check-Logic-Test" healthcheck.testresult = "Otoroshi-Health-Check-Logic-Test-Result" jwt.issuer = "Otoroshi" canary.tracker = "Otoroshi-Canary-Id" client.cert.chain = "Otoroshi-Client-Cert-Chain" request.jwtAuthorization = "access_token" request.bearerAuthorization = "bearer_auth" request.basicAuthorization = "basic_auth" } requests { validate = true validate = ${?OTOROSHI_REQUESTS_VALIDATE} maxUrlLength = ${akka.http.parsing.max-uri-length} maxCookieLength = ${akka.http.parsing.max-header-value-length} maxHeaderNameLength = ${akka.http.parsing.max-header-name-length} maxHeaderValueLength = ${akka.http.parsing.max-header-value-length} } jmx { enabled = false enabled = ${?OTOROSHI_JMX_ENABLED} port = 16000 port = ${?OTOROSHI_JMX_PORT} } loggers { } provider { dashboardUrl = ${?OTOROSHI_PROVIDER_DASHBOARD_URL} jsUrl = ${?OTOROSHI_PROVIDER_JS_URL} cssUrl = ${?OTOROSHI_PROVIDER_CSS_URL} secret = "secret" secret = ${?OTOROSHI_PROVIDER_SECRET} title = "Provider's dashboard" title = ${?OTOROSHI_PROVIDER_TITLE} } healthcheck { workers = 4 workers = ${?OTOROSHI_HEALTHCHECK_WORKERS} block-on-red = false block-on-red = ${?OTOROSHI_HEALTHCHECK_BLOCK_ON_RED} block-on-red = ${?OTOROSHI_HEALTHCHECK_BLOCK_ON_500} ttl = 60000 ttl = ${?OTOROSHI_HEALTHCHECK_TTL} ttl-only = true ttl-only = ${?OTOROSHI_HEALTHCHECK_TTL_ONLY} } vaults { enabled = false enabled = ${?OTOROSHI_VAULTS_ENABLED} secrets-ttl = 300000 # 5 minutes between each secret read secrets-ttl = ${?OTOROSHI_VAULTS_SECRETS_TTL} secrets-error-ttl = 20000 # wait 20000 before retrying on error secrets-error-ttl = ${?OTOROSHI_VAULTS_SECRETS_ERROR_TTL} cached-secrets = 10000 cached-secrets = ${?OTOROSHI_VAULTS_CACHED_SECRETS} read-ttl = 10000 # 10 seconds read-timeout = ${?otoroshi.vaults.read-ttl} read-timeout = ${?OTOROSHI_VAULTS_READ_TTL} read-timeout = ${?OTOROSHI_VAULTS_READ_TIMEOUT} parallel-fetchs = 4 parallel-fetchs = ${?OTOROSHI_VAULTS_PARALLEL_FETCHS} # if enabled, only leader nodes fetches the secrets. # entities with secret values filled are then sent to workers when they poll the cluster state. # only works if `otoroshi.cluster.autoUpdateState=true` leader-fetch-only = false leader-fetch-only = ${?OTOROSHI_VAULTS_LEADER_FETCH_ONLY} env { type = "env" prefix = ${?OTOROSHI_VAULTS_ENV_PREFIX} } local { type = "local" root = ${?OTOROSHI_VAULTS_LOCAL_ROOT} } # hashicorpvault { # type = "hashicorp-vault" # url = "http://127.0.0.1:8200" # mount = "kv" # kv = "v2" # token = "root" # } } tunnels { enabled = true enabled = ${?OTOROSHI_TUNNELS_ENABLED} worker-ws = true worker-ws = ${?OTOROSHI_TUNNELS_WORKER_WS} worker-use-internal-ports = false worker-use-internal-ports = ${?OTOROSHI_TUNNELS_WORKER_USE_INTERNAL_PORTS} worker-use-loadbalancing = false worker-use-loadbalancing = ${?OTOROSHI_TUNNELS_WORKER_USE_LOADBALANCING} default { enabled = false enabled = ${?OTOROSHI_TUNNELS_DEFAULT_ENABLED} id = "default" id = ${?OTOROSHI_TUNNELS_DEFAULT_ID} name = "default" name = ${?OTOROSHI_TUNNELS_DEFAULT_NAME} url = "http://127.0.0.1:8080" url = ${?OTOROSHI_TUNNELS_DEFAULT_URL} host = "otoroshi-api.oto.tools" host = ${?OTOROSHI_TUNNELS_DEFAULT_HOST} clientId = "admin-api-apikey-id" clientId = ${?OTOROSHI_TUNNELS_DEFAULT_CLIENT_ID} clientSecret = "admin-api-apikey-secret" clientSecret = ${?OTOROSHI_TUNNELS_DEFAULT_CLIENT_SECRET} export-routes = true # send routes information to remote otoroshi instance to facilitate remote route exposition export-routes = ${?OTOROSHI_TUNNELS_DEFAULT_EXPORT_ROUTES} # send routes information to remote otoroshi instance to facilitate remote route exposition export-routes-tag = ${?OTOROSHI_TUNNELS_DEFAULT_EXPORT_TAG} # only send routes information if the route has this tag proxy { enabled = false host = none port = none principal = none password = none nonProxyHosts = [] } } } admin-extensions { enabled = true enabled = ${?OTOROSHI_ADMIN_EXTENSIONS_ENABLED} configurations { otoroshi_extensions_foo { enabled = false } otoroshi_extensions_greenscore { enabled = false enabled = ${?OTOROSHI_ADMIN_EXTENSIONS_GREENSCORE_ENABLED} } } } } http.port = 8080 # the main http port for the otoroshi server http.port = ${?otoroshi.http.port} # the main http port for the otoroshi server http.port = ${?PORT} # the main http port for the otoroshi server http.port = ${?OTOROSHI_PORT} # the main http port for the otoroshi server http.port = ${?OTOROSHI_HTTP_PORT} # the main http port for the otoroshi server play.server.http.port = ${http.port} # the main http port for the otoroshi server play.server.http.port = ${?PORT} # the main http port for the otoroshi server play.server.http.port = ${?OTOROSHI_PORT} # the main http port for the otoroshi server play.server.http.port = ${?OTOROSHI_HTTP_PORT} # the main http port for the otoroshi server https.port = 8443 # the main https port for the otoroshi server https.port = ${?otoroshi.https.port} # the main https port for the otoroshi server https.port = ${?HTTPS_PORT} # the main https port for the otoroshi server https.port = ${?OTOROSHI_HTTPS_PORT} # the main https port for the otoroshi server play.server.https.engineProvider = "otoroshi.ssl.DynamicSSLEngineProvider" # the module to handle TLS connections dynamically play.server.https.keyStoreDumpPath = ${?HTTPS_KEYSTORE_DUMP_PATH} # the file path where the TLSContext will be dumped (for debugging purposes only) play.server.https.keyStoreDumpPath = ${?OTOROSHI_HTTPS_KEYSTORE_DUMP_PATH} # the file path where the TLSContext will be dumped (for debugging purposes only) play.http.secret.key = ${otoroshi.secret} # the secret used to signed session cookies play.http.secret.key = ${?PLAY_CRYPTO_SECRET} # the secret used to signed session cookies play.http.secret.key = ${?OTOROSHI_CRYPTO_SECRET} # the secret used to signed session cookies play.server.http.idleTimeout = 3600s # the default server idle timeout play.server.http.idleTimeout = ${?PLAY_SERVER_IDLE_TIMEOUT} # the default server idle timeout play.server.http.idleTimeout = ${?OTOROSHI_SERVER_IDLE_TIMEOUT} # the default server idle timeout play.server.akka.requestTimeout = 3600s # the default server idle timeout (for akka server specifically) play.server.akka.requestTimeout = ${?PLAY_SERVER_REQUEST_TIMEOUT} # the default server idle timeout (for akka server specifically) play.server.akka.requestTimeout = ${?OTOROSHI_SERVER_REQUEST_TIMEOUT} # the default server idle timeout (for akka server specifically) http2.enabled = true # enable HTTP2 support http2.enabled = ${?otoroshi.http2.enabled} http2.enabled = ${?HTTP2_ENABLED} # enable HTTP2 support http2.enabled = ${?OTOROSHI_HTTP2_ENABLED} # enable HTTP2 support play.server.https.keyStore.path=${?HTTPS_KEYSTORE_PATH} # settings for the default server keystore play.server.https.keyStore.path=${?OTOROSHI_HTTPS_KEYSTORE_PATH} # settings for the default server keystore play.server.https.keyStore.type=${?HTTPS_KEYSTORE_TYPE} # settings for the default server keystore play.server.https.keyStore.type=${?OTOROSHI_HTTPS_KEYSTORE_TYPE} # settings for the default server keystore play.server.https.keyStore.password=${?HTTPS_KEYSTORE_PASSWORD} # settings for the default server keystore play.server.https.keyStore.password=${?OTOROSHI_HTTPS_KEYSTORE_PASSWORD} # settings for the default server keystore play.server.https.keyStore.algorithm=${?HTTPS_KEYSTORE_ALGO} # settings for the default server keystore play.server.https.keyStore.algorithm=${?OTOROSHI_HTTPS_KEYSTORE_ALGO} # settings for the default server keystore play.server.websocket.frame.maxLength = 1024k play.server.websocket.frame.maxLength = ${?OTOROSHI_WEBSOCKET_FRAME_MAX_LENGTH} play.application.loader = "otoroshi.loader.OtoroshiLoader" # the loader used to launch otoroshi play.http { session { secure = false # the cookie for otoroshi backoffice should be exhanged over https only secure = ${?SESSION_SECURE_ONLY} # the cookie for otoroshi backoffice should be exhanged over https only secure = ${?OTOROSHI_SESSION_SECURE_ONLY} # the cookie for otoroshi backoffice should be exhanged over https only httpOnly = true # the cookie for otoroshi backoffice is not accessible from javascript maxAge = 259200000 # the cookie for otoroshi backoffice max age maxAge = ${?SESSION_MAX_AGE} # the cookie for otoroshi backoffice max age maxAge = ${?OTOROSHI_SESSION_MAX_AGE} # the cookie for otoroshi backoffice max age # domain = "."${?app.domain} # the cookie for otoroshi backoffice domain domain = "."${otoroshi.domain} # the cookie for otoroshi backoffice domain domain = ${?SESSION_DOMAIN} # the cookie for otoroshi backoffice domain domain = ${?OTOROSHI_SESSION_DOMAIN} # the cookie for otoroshi backoffice domain cookieName = "otoroshi-session" # the cookie for otoroshi backoffice name cookieName = ${?SESSION_NAME} # the cookie for otoroshi backoffice name cookieName = ${?OTOROSHI_SESSION_NAME} # the cookie for otoroshi backoffice name } } akka { # akka specific configuration version = "2.6.20" loglevel = ERROR logger-startup-timeout = 60s log-dead-letters-during-shutdown = false jvm-exit-on-fatal-error = false actor { default-dispatcher { type = Dispatcher executor = "fork-join-executor" fork-join-executor { parallelism-factor = 4.0 parallelism-factor = ${?OTOROSHI_AKKA_DISPATCHER_PARALLELISM_FACTOR} parallelism-min = 8 parallelism-min = ${?OTOROSHI_AKKA_DISPATCHER_PARALLELISM_MIN} parallelism-max = 64 parallelism-max = ${?OTOROSHI_AKKA_DISPATCHER_PARALLELISM_MAX} task-peeking-mode = "FIFO" task-peeking-mode = ${?OTOROSHI_AKKA_DISPATCHER_TASK_PEEKING_MODE} } throughput = 1 throughput = ${?OTOROSHI_AKKA_DISPATCHER_THROUGHPUT} } } http { server { server-header = otoroshi max-connections = 2048 max-connections = ${?OTOROSHI_AKKA_HTTP_SERVER_MAX_CONNECTIONS} remote-address-header = on raw-request-uri-header = on pipelining-limit = 64 pipelining-limit = ${?OTOROSHI_AKKA_HTTP_SERVER_PIPELINING_LIMIT} backlog = 512 backlog = ${?OTOROSHI_AKKA_HTTP_SERVER_BACKLOG} socket-options { so-receive-buffer-size = undefined so-send-buffer-size = undefined so-reuse-address = undefined so-traffic-class = undefined tcp-keep-alive = true tcp-oob-inline = undefined tcp-no-delay = undefined } http2 { request-entity-chunk-size = 65536 b incoming-connection-level-buffer-size = 10 MB incoming-stream-level-buffer-size = 512kB } } client { user-agent-header = Otoroshi-akka socket-options { so-receive-buffer-size = undefined so-send-buffer-size = undefined so-reuse-address = undefined so-traffic-class = undefined tcp-keep-alive = true tcp-oob-inline = undefined tcp-no-delay = undefined } } host-connection-pool { max-connections = 512 max-connections = ${?OTOROSHI_AKKA_HTTP_SERVER_HOST_CONNECTION_POOL_MAX_CONNECTIONS} max-open-requests = 2048 max-open-requests = ${?OTOROSHI_AKKA_HTTP_SERVER_HOST_CONNECTION_POOL_MAX_OPEN_REQUESTS} pipelining-limit = 32 pipelining-limit = ${?OTOROSHI_AKKA_HTTP_SERVER_HOST_CONNECTION_POOL_PIPELINING_LIMIT} client { user-agent-header = otoroshi socket-options { so-receive-buffer-size = undefined so-send-buffer-size = undefined so-reuse-address = undefined so-traffic-class = undefined tcp-keep-alive = true tcp-oob-inline = undefined tcp-no-delay = undefined } } } parsing { max-uri-length = 4k max-uri-length = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_URI_LENGTH} max-method-length = 16 max-method-length = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_METHOD_LENGTH} max-response-reason-length = 128 max-response-reason-length = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_RESPONSE_REASON_LENGTH} max-header-name-length = 128 max-header-name-length = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_HEADER_NAME_LENGTH} max-header-value-length = 16k max-header-value-length = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_HEADER_VALUE_LENGTH} max-header-count = 128 max-header-count = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_HEADER_COUNT} max-chunk-ext-length = 256 max-chunk-ext-length = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_CHUNK_EXT_LENGTH} max-chunk-size = 256m max-chunk-size = ${?AKKA_HTTP_SERVER_MAX_CHUNK_SIZE} max-chunk-size = ${?OTOROSHI_AKKA_HTTP_SERVER_MAX_CHUNK_SIZE} max-chunk-size = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_CHUNK_SIZE} max-content-length = infinite max-content-length = ${?AKKA_HTTP_SERVER_MAX_CONTENT_LENGHT} max-content-length = ${?OTOROSHI_AKKA_HTTP_SERVER_MAX_CONTENT_LENGHT} max-content-length = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_CONTENT_LENGHT} uri-parsing-mode = strict uri-parsing-mode = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_URI_PARSING_MODE} } } }

More config. options

See default configuration at

Configuration with env. variables

Eevery property in the configuration file can be overriden by an environment variable if it has env variable override written like ${?ENV_VARIABLE}).

Reference configuration for env. variables

app {
  storage = ${?APP_STORAGE} # the storage used by otoroshi. possible values are lettuce (for redis), inmemory, file, http, s3, cassandra, postgresql
  storage = ${?OTOROSHI_STORAGE} # the storage used by otoroshi. possible values are lettuce (for redis), inmemory, file, http, s3, cassandra, postgresql
  storageRoot = ${?APP_STORAGE_ROOT} # the prefix used for storage keys
  storageRoot = ${?OTOROSHI_STORAGE_ROOT} # the prefix used for storage keys
  eventsName = ${?APP_EVENTS_NAME} # the name of the event producer
  eventsName = ${?OTOROSHI_EVENTS_NAME} # the name of the event producer
  importFrom = ${?APP_IMPORT_FROM} # file path to import otoroshi initial configuration
  importFrom = ${?OTOROSHI_IMPORT_FROM} # file path to import otoroshi initial configuration
  env = ${?APP_ENV} # env name, should always be prod except in dev mode
  env = ${?OTOROSHI_ENV} # env name, should always be prod except in dev mode
  domain = ${?APP_DOMAIN} # default domain for basic otoroshi services
  domain = ${?OTOROSHI_DOMAIN} # default domain for basic otoroshi services
  commitId = ${?COMMIT_ID}
  commitId = ${?OTOROSHI_COMMIT_ID}
  rootScheme = ${?APP_ROOT_SCHEME} # default root scheme when composing urls
  rootScheme = ${?OTOROSHI_ROOT_SCHEME} # default root scheme when composing urls
  throttlingWindow = ${?THROTTLING_WINDOW} # the number of second used to compute throttling number
  throttlingWindow = ${?OTOROSHI_THROTTLING_WINDOW} # the number of second used to compute throttling number
  checkForUpdates = ${?CHECK_FOR_UPDATES} # enable automatic version update checks
  checkForUpdates = ${?OTOROSHI_CHECK_FOR_UPDATES} # enable automatic version update checks
  overheadThreshold = ${?OVERHEAD_THRESHOLD} # the value threshold (in milliseconds) used to send HighOverheadAlert
  overheadThreshold = ${?OTOROSHI_OVERHEAD_THRESHOLD} # the value threshold (in milliseconds) used to send HighOverheadAlert
  adminLogin = ${?OTOROSHI_INITIAL_ADMIN_LOGIN} # the initial admin login
  adminPassword = ${?OTOROSHI_INITIAL_ADMIN_PASSWORD} # the initial admin password
  initialCustomization = ${?OTOROSHI_INITIAL_CUSTOMIZATION} # otoroshi inital configuration that will be merged with a new confguration. Shaped like an otoroshi export
  boot {
  	failOnTimeout = ${?OTOROSHI_BOOT_FAIL_ON_TIMEOUT} # otoroshi will exit if a subsystem failed its init
    globalWait = ${?OTOROSHI_BOOT_GLOBAL_WAIT} # should we wait until everything is setup to accept http requests
    globalWaitTimeout = ${?OTOROSHI_BOOT_GLOBAL_WAIT_TIMEOUT} # max wait before accepting requests
    waitForPluginsSearch = ${?OTOROSHI_BOOT_WAIT_FOR_PLUGINS_SEARCH} # should we wait for classpath plugins search before accepting http requests
    waitForPluginsSearchTimeout = ${?OTOROSHI_BOOT_WAIT_FOR_PLUGINS_SEARCH_TIMEOUT} # max wait for classpath plugins search before accepting http requests
    waitForScriptsCompilation = ${?OTOROSHI_BOOT_WAIT_FOR_SCRIPTS_COMPILATION} # should we wait for plugins compilation before accepting http requests
    waitForScriptsCompilationTimeout = ${?OTOROSHI_BOOT_WAIT_FOR_SCRIPTS_COMPILATION_TIMEOUT} # max wait for plugins compilation before accepting http requests 
    waitForTlsInit = ${?OTOROSHI_BOOT_WAIT_FOR_TLS_INIT} # should we wait for first TLS context initialization before accepting http requests
    waitForTlsInitTimeout = ${?OTOROSHI_BOOT_WAIT_FOR_TLS_INIT_TIMEOUT} # max wait for first TLS context initialization before accepting http requests
    waitForFirstClusterFetch = ${?OTOROSHI_BOOT_WAIT_FOR_FIRST_CLUSTER_FETCH} # should we wait for first cluster initialization before accepting http requests
    waitForFirstClusterFetchTimeout = ${?OTOROSHI_BOOT_WAIT_FOR_FIRST_CLUSTER_TIMEOUT} # max wait for first cluster initialization before accepting http requests
    waitForFirstClusterStateCache = ${?OTOROSHI_BOOT_WAIT_FOR_FIRST_CLUSTER_STATE_CACHE} # should we wait for first cluster initialization before accepting http requests
    waitForFirstClusterStateCacheTimeout =  ${?OTOROSHI_BOOT_WAIT_FOR_FIRST_CLUSTER_STATE_CACHE_TIMEOUT} # max wait for first cluster initialization before accepting http requests
  }
  instance {
    instanceId = ${?OTOROSHI_INSTANCE_ID} # the instance id
    number =  ${?OTOROSHI_INSTANCE_NUMBER} # the instance number. Can be found in otoroshi events
    number =  ${?INSTANCE_NUMBER} # the instance number. Can be found in otoroshi events
    name = ${?OTOROSHI_INSTANCE_NAME} # instance name
		logo = ${?OTOROSHI_INSTANCE_LOGO} # instance logo
    zone = ${?OTOROSHI_INSTANCE_ZONE} # instance zone (optional)
    region = ${?OTOROSHI_INSTANCE_REGION} # instance region (optional)
    dc = ${?OTOROSHI_INSTANCE_DATACENTER} # instance dc (optional)
    provider = ${?OTOROSHI_INSTANCE_PROVIDER} # instance provider (optional)
    rack = ${?OTOROSHI_INSTANCE_RACK} # instance rack (optional)
    title = ${?OTOROSHI_INSTANCE_TITLE} # the title displayed in UI top left
  }
    longRequestTimeout = ${?OTOROSHI_PROXY_LONG_REQUEST_TIMEOUT}
  }
  health {
    limit = ${?HEALTH_LIMIT} # the value threshold (in milliseconds) used to indicate if an otoroshi instance is healthy or not
    limit = ${?OTOROSHI_HEALTH_LIMIT} # the value threshold (in milliseconds) used to indicate if an otoroshi instance is healthy or not
    accessKey = ${?HEALTH_ACCESS_KEY} # the key to access /health edpoint
    accessKey = ${?OTOROSHI_HEALTH_ACCESS_KEY} # the key to access /health edpoint
  }
  snowflake {
    seed = ${?INSTANCE_NUMBER} # the seed number used to generate unique ids. Should be different for every instances
    seed = ${?OTOROSHI_INSTANCE_NUMBER} # the seed number used to generate unique ids. Should be different for every instances
    seed = ${?SNOWFLAKE_SEED} # the seed number used to generate unique ids. Should be different for every instances
    seed = ${?OTOROSHI_SNOWFLAKE_SEED} # the seed number used to generate unique ids. Should be different for every instances
  }
  events {
    maxSize = ${?MAX_EVENTS_SIZE} # the amount of event kept in the datastore
    maxSize = ${?OTOROSHI_MAX_EVENTS_SIZE} # the amount of event kept in the datastore
  }
  exposed-ports {
    http = ${?APP_EXPOSED_PORTS_HTTP} # the exposed http port for otoroshi (when in a container or behind a proxy)
    http = ${?OTOROSHI_EXPOSED_PORTS_HTTP} # the exposed http port for otoroshi (when in a container or behind a proxy)
    https = ${?APP_EXPOSED_PORTS_HTTPS} # the exposed https port for otoroshi (when in a container or behind a proxy
    https = ${?OTOROSHI_EXPOSED_PORTS_HTTPS} # the exposed https port for otoroshi (when in a container or behind a proxy
  }
  backoffice {
    exposed = ${?APP_BACKOFFICE_EXPOSED} # expose the backoffice ui
    exposed = ${?OTOROSHI_BACKOFFICE_EXPOSED} # expose the backoffice ui
    subdomain = ${?APP_BACKOFFICE_SUBDOMAIN} # the backoffice subdomain
    subdomain = ${?OTOROSHI_BACKOFFICE_SUBDOMAIN} # the backoffice subdomain
    domainsStr = ${?APP_BACKOFFICE_DOMAINS} # the backoffice domains
    domainsStr = ${?OTOROSHI_BACKOFFICE_DOMAINS} # the backoffice domains
    # useNewEngine = ${?OTOROSHI_BACKOFFICE_USE_NEW_ENGINE} # avoid backoffice admin api proxy
    usePlay = ${?OTOROSHI_BACKOFFICE_USE_PLAY} # avoid backoffice http call for admin api
    session {
      exp = ${?APP_BACKOFFICE_SESSION_EXP} # the backoffice cookie expiration
      exp = ${?OTOROSHI_BACKOFFICE_SESSION_EXP} # the backoffice cookie expiration
    }
  }
  privateapps {
    subdomain = ${?APP_PRIVATEAPPS_SUBDOMAIN} # privateapps (proxy sso) domain
    subdomain = ${?OTOROSHI_PRIVATEAPPS_SUBDOMAIN} # privateapps (proxy sso) domain
    domainsStr = ${?APP_PRIVATEAPPS_DOMAINS}
    domainsStr = ${?OTOROSHI_PRIVATEAPPS_DOMAINS}
    session {
      exp = ${?APP_PRIVATEAPPS_SESSION_EXP} # the privateapps cookie expiration
      exp = ${?OTOROSHI_PRIVATEAPPS_SESSION_EXP} # the privateapps cookie expiration
    }
  }
  adminapi {
    exposed = ${?ADMIN_API_EXPOSED} # expose the admin api
    exposed = ${?OTOROSHI_ADMIN_API_EXPOSED} # expose the admin api
    targetSubdomain = ${?ADMIN_API_TARGET_SUBDOMAIN} # admin api target subdomain as targeted by otoroshi service
    targetSubdomain = ${?OTOROSHI_ADMIN_API_TARGET_SUBDOMAIN} # admin api target subdomain as targeted by otoroshi service
    exposedSubdomain = ${?ADMIN_API_EXPOSED_SUBDOMAIN} # admin api exposed subdomain as exposed by otoroshi service
    exposedSubdomain = ${?OTOROSHI_ADMIN_API_EXPOSED_SUBDOMAIN} # admin api exposed subdomain as exposed by otoroshi service
    additionalExposedDomain = ${?ADMIN_API_ADDITIONAL_EXPOSED_DOMAIN} # admin api additional exposed subdomain as exposed by otoroshi service
    additionalExposedDomain = ${?OTOROSHI_ADMIN_API_ADDITIONAL_EXPOSED_DOMAIN} # admin api additional exposed subdomain as exposed by otoroshi service
    domainsStr = ${?ADMIN_API_DOMAINS}
    domainsStr = ${?OTOROSHI_ADMIN_API_DOMAINS}
    exposedDomainsStr = ${?ADMIN_API_EXPOSED_DOMAINS}
    exposedDomainsStr = ${?OTOROSHI_ADMIN_API_EXPOSED_DOMAINS}
    defaultValues {
      backOfficeGroupId = ${?ADMIN_API_GROUP} # default value for admin api service group
      backOfficeGroupId = ${?OTOROSHI_ADMIN_API_GROUP} # default value for admin api service group
      backOfficeApiKeyClientId = ${?ADMIN_API_CLIENT_ID}  # default value for admin api apikey id
      backOfficeApiKeyClientId = ${?OTOROSHI_ADMIN_API_CLIENT_ID}  # default value for admin api apikey id
      backOfficeApiKeyClientSecret = ${?otoroshi.admin-api-secret} # default value for admin api apikey secret
      backOfficeApiKeyClientSecret = ${?OTOROSHI_otoroshi.admin-api-secret} # default value for admin api apikey secret
      backOfficeApiKeyClientSecret = ${?ADMIN_API_CLIENT_SECRET} # default value for admin api apikey secret
      backOfficeApiKeyClientSecret = ${?OTOROSHI_ADMIN_API_CLIENT_SECRET} # default value for admin api apikey secret
      backOfficeServiceId = ${?ADMIN_API_SERVICE_ID} # default value for admin api service id
      backOfficeServiceId = ${?OTOROSHI_ADMIN_API_SERVICE_ID} # default value for admin api service id
    }
    proxy {
      https = ${?ADMIN_API_HTTPS} # backoffice proxy admin api over https
      https = ${?OTOROSHI_ADMIN_API_HTTPS} # backoffice proxy admin api over https
      local = ${?ADMIN_API_LOCAL} # backoffice proxy admin api on localhost
      local = ${?OTOROSHI_ADMIN_API_LOCAL} # backoffice proxy admin api on localhost
    }
  }
  claim {
    sharedKey = ${?CLAIM_SHAREDKEY} # the default secret used to sign otoroshi exchange protocol tokens
    sharedKey = ${?OTOROSHI_CLAIM_SHAREDKEY} # the default secret used to sign otoroshi exchange protocol tokens
  }
  webhooks {
  }
  redis { # configuration to fetch/store otoroshi state from a redis datastore using rediscala
    host = ${?REDIS_HOST}
    host = ${?OTOROSHI_REDIS_HOST}
    port = ${?REDIS_PORT}
    port = ${?OTOROSHI_REDIS_PORT}
    password = ${?REDIS_PASSWORD}
    password = ${?OTOROSHI_REDIS_PASSWORD}
    windowSize = ${?REDIS_WINDOW_SIZE}
    windowSize = ${?OTOROSHI_REDIS_WINDOW_SIZE}
    slavesStr = ${?REDIS_SLAVES}
    slavesStr = ${?OTOROSHI_REDIS_SLAVES}
    slavesStr = ${?REDIS_MEMBERS}
    slavesStr = ${?OTOROSHI_REDIS_MEMBERS}
    useScan =  ${?REDIS_USE_SCAN}
    useScan =  ${?OTOROSHI_REDIS_USE_SCAN}
    pool {
      members = ${?REDIS_POOL_MEMBERS}
      members = ${?OTOROSHI_REDIS_POOL_MEMBERS}
    }
    mpool {
      membersStr = ${?REDIS_MPOOL_MEMBERS}
      membersStr = ${?OTOROSHI_REDIS_MPOOL_MEMBERS}
    }
    lf {
      master {
        host = ${?REDIS_LF_HOST}
        host = ${?OTOROSHI_REDIS_LF_HOST}
        port = ${?REDIS_LF_PORT}
        port = ${?OTOROSHI_REDIS_LF_PORT}
        password = ${?REDIS_LF_PASSWORD}
        password = ${?OTOROSHI_REDIS_LF_PASSWORD}
      }
      slavesStr = ${?REDIS_LF_SLAVES}
      slavesStr = ${?OTOROSHI_REDIS_LF_SLAVES}
      slavesStr = ${?REDIS_LF_MEMBERS}
      slavesStr = ${?OTOROSHI_REDIS_LF_MEMBERS}
    }
    sentinels {
      master = ${?REDIS_SENTINELS_MASTER}
      master = ${?OTOROSHI_REDIS_SENTINELS_MASTER}
      password = ${?REDIS_SENTINELS_PASSWORD}
      password = ${?OTOROSHI_REDIS_SENTINELS_PASSWORD}
      db = ${?REDIS_SENTINELS_DB}
      db = ${?OTOROSHI_REDIS_SENTINELS_DB}
      name = ${?REDIS_SENTINELS_NAME}
      name = ${?OTOROSHI_REDIS_SENTINELS_NAME}
      membersStr = ${?REDIS_SENTINELS_MEMBERS}
      membersStr = ${?OTOROSHI_REDIS_SENTINELS_MEMBERS}
      lf {
        master = ${?REDIS_SENTINELS_LF_MASTER}
        master = ${?OTOROSHI_REDIS_SENTINELS_LF_MASTER}
        membersStr = ${?REDIS_SENTINELS_LF_MEMBERS}
        membersStr = ${?OTOROSHI_REDIS_SENTINELS_LF_MEMBERS}
      }
    }
    cluster {
      membersStr = ${?REDIS_CLUSTER_MEMBERS}
      membersStr = ${?OTOROSHI_REDIS_CLUSTER_MEMBERS}
    }
    lettuce { # configuration to fetch/store otoroshi state from a redis datastore using the lettuce driver (the next default one)
      connection = ${?REDIS_LETTUCE_CONNECTION}
      connection = ${?OTOROSHI_REDIS_LETTUCE_CONNECTION}
      uri =  ${?REDIS_LETTUCE_URI}
      uri =  ${?OTOROSHI_REDIS_LETTUCE_URI}
      uri =  ${?REDIS_URL}
      uri =  ${?OTOROSHI_REDIS_URL}
      urisStr = ${?REDIS_LETTUCE_URIS}
      urisStr = ${?OTOROSHI_REDIS_LETTUCE_URIS}
      readFrom = ${?REDIS_LETTUCE_READ_FROM}
      readFrom = ${?OTOROSHI_REDIS_LETTUCE_READ_FROM}
      startTLS = ${?REDIS_LETTUCE_START_TLS}
      startTLS = ${?OTOROSHI_REDIS_LETTUCE_START_TLS}
      verifyPeers = ${?REDIS_LETTUCE_VERIFY_PEERS}
      verifyPeers = ${?OTOROSHI_REDIS_LETTUCE_VERIFY_PEERS}
    }
  }
  inmemory { # configuration to fetch/store otoroshi state in memory
    windowSize = ${?INMEMORY_WINDOW_SIZE}
    windowSize = ${?OTOROSHI_INMEMORY_WINDOW_SIZE}
    experimental = ${?INMEMORY_EXPERIMENTAL_STORE}
    experimental = ${?OTOROSHI_INMEMORY_EXPERIMENTAL_STORE}
    optimized = ${?INMEMORY_OPTIMIZED}
    optimized = ${?OTOROSHI_INMEMORY_OPTIMIZED}
    modern =  ${?INMEMORY_MODERN}
    modern =  ${?OTOROSHI_INMEMORY_MODERN}
  }
  filedb { # configuration to fetch/store otoroshi state from a file
    windowSize = ${?FILEDB_WINDOW_SIZE}
    windowSize = ${?OTOROSHI_FILEDB_WINDOW_SIZE}
    path = ${?FILEDB_PATH}
    path = ${?OTOROSHI_FILEDB_PATH}
  }
  httpdb { # configuration to fetch/store otoroshi state from an http endpoint
    headers = {}
  }
  s3db { # configuration to fetch/store otoroshi state from a S3 bucket
    bucket = ${?OTOROSHI_DB_S3_BUCKET}
    endpoint = ${?OTOROSHI_DB_S3_ENDPOINT}
    region = ${?OTOROSHI_DB_S3_REGION}
    access = ${?OTOROSHI_DB_S3_ACCESS}
    secret = ${?OTOROSHI_DB_S3_SECRET}
    key = ${?OTOROSHI_DB_S3_KEY}
    chunkSize = ${?OTOROSHI_DB_S3_CHUNK_SIZE}
    v4auth = ${?OTOROSHI_DB_S3_V4_AUTH}
    writeEvery = ${?OTOROSHI_DB_S3_WRITE_EVERY} # write interval
    acl = ${?OTOROSHI_DB_S3_ACL}
  }
  pg { # postrgesql settings. everything possible with the client
    uri = ${?PG_URI}
    uri = ${?OTOROSHI_PG_URI}
    uri = ${?POSTGRESQL_ADDON_URI}
    uri = ${?OTOROSHI_POSTGRESQL_ADDON_URI}
    poolSize = ${?PG_POOL_SIZE}
    poolSize = ${?OTOROSHI_PG_POOL_SIZE}
    port = ${?PG_PORT}
    port = ${?OTOROSHI_PG_PORT}
    host = ${?PG_HOST}
    host = ${?OTOROSHI_PG_HOST}
    database = ${?PG_DATABASE}
    database = ${?OTOROSHI_PG_DATABASE}
    user = ${?PG_USER}
    user = ${?OTOROSHI_PG_USER}
    password = ${?PG_PASSWORD}
    password = ${?OTOROSHI_PG_PASSWORD}
    logQueries = ${?PG_DEBUG_QUERIES}
    logQueries = ${?OTOROSHI_PG_DEBUG_QUERIES}
    avoidJsonPath = ${?PG_AVOID_JSON_PATH}
    avoidJsonPath = ${?OTOROSHI_PG_AVOID_JSON_PATH}
    optimized = ${?PG_OPTIMIZED}
    optimized = ${?OTOROSHI_PG_OPTIMIZED}
    connect-timeout = ${?PG_CONNECT_TIMEOUT}
    connect-timeout = ${?OTOROSHI_PG_CONNECT_TIMEOUT}
    idle-timeout = ${?PG_IDLE_TIMEOUT}
    idle-timeout = ${?OTOROSHI_PG_IDLE_TIMEOUT}
    log-activity = ${?PG_LOG_ACTIVITY}
    log-activity = ${?OTOROSHI_PG_LOG_ACTIVITY}
    pipelining-limit = ${?PG_PIPELINING_LIMIT}
    pipelining-limit = ${?OTOROSHI_PG_PIPELINING_LIMIT}
    ssl {
      enabled = ${?PG_SSL_ENABLED}
      enabled = ${?OTOROSHI_PG_SSL_ENABLED}
      mode = ${?PG_SSL_MODE}
      mode = ${?OTOROSHI_PG_SSL_MODE}
      trusted-cert-path = ${?PG_SSL_TRUSTED_CERT_PATH}
      trusted-cert-path = ${?OTOROSHI_PG_SSL_TRUSTED_CERT_PATH}
      trusted-cert = ${?PG_SSL_TRUSTED_CERT}
      trusted-cert = ${?OTOROSHI_PG_SSL_TRUSTED_CERT}
      client-cert-path = ${?PG_SSL_CLIENT_CERT_PATH}
      client-cert-path = ${?OTOROSHI_PG_SSL_CLIENT_CERT_PATH}
      client-cert = ${?PG_SSL_CLIENT_CERT}
      client-cert = ${?OTOROSHI_PG_SSL_CLIENT_CERT}
      trust-all = ${?PG_SSL_TRUST_ALL}
      trust-all = ${?OTOROSHI_PG_SSL_TRUST_ALL}
    }
  }
  cassandra { # cassandra settings. everything possible with the client
    windowSize = ${?CASSANDRA_WINDOW_SIZE}
    windowSize = ${?OTOROSHI_CASSANDRA_WINDOW_SIZE}
    host = ${?CASSANDRA_HOST}
    host = ${?OTOROSHI_CASSANDRA_HOST}
    port = ${?CASSANDRA_PORT}
    port = ${?OTOROSHI_CASSANDRA_PORT}
    replicationFactor = ${?CASSANDRA_REPLICATION_FACTOR}
    replicationFactor = ${?OTOROSHI_CASSANDRA_REPLICATION_FACTOR}
    replicationOptions = ${?CASSANDRA_REPLICATION_OPTIONS}
    replicationOptions = ${?OTOROSHI_CASSANDRA_REPLICATION_OPTIONS}
    durableWrites = ${?CASSANDRA_DURABLE_WRITES}
    durableWrites = ${?OTOROSHI_CASSANDRA_DURABLE_WRITES}
    basic.contact-points = [ ${app.cassandra.host}":"${app.cassandra.port} ]
    basic.session-name = ${?OTOROSHI_CASSANDRA_SESSION_NAME}
    basic.session-keyspace = ${?OTOROSHI_CASSANDRA_SESSION_KEYSPACE}
    basic.request {
      consistency = ${?OTOROSHI_CASSANDRA_CONSISTENCY}
      page-size = ${?OTOROSHI_CASSANDRA_PAGE_SIZE}
      serial-consistency = ${?OTOROSHI_CASSANDRA_SERIAL_CONSISTENCY}
      default-idempotence = ${?OTOROSHI_CASSANDRA_DEFAULT_IDEMPOTENCE}
    }
    basic.load-balancing-policy {
      local-datacenter = ${?OTOROSHI_CASSANDRA_LOCAL_DATACENTER}
    }
    basic.cloud {
    }
    basic.application {
    }
    basic.graph {
    }
    advanced.connection {
      set-keyspace-timeout = ${datastax-java-driver.advanced.connection.init-query-timeout}
      pool {
        local {
        }
        remote {
        }
      }
    }
    advanced.reconnection-policy {
    }
    advanced.retry-policy {
    }
    advanced.speculative-execution-policy {
    }
    advanced.auth-provider {
      username = ${?CASSANDRA_USERNAME}
      username = ${?OTOROSHI_CASSANDRA_USERNAME}
      password = ${?CASSANDRA_PASSWORD}
      password = ${?OTOROSHI_CASSANDRA_PASSWORD}
      authorization-id = ${?OTOROSHI_CASSANDRA_AUTHORIZATION_ID}
      # login-configuration {
      # }
      # sasl-properties {
      # }
    }
    advanced.ssl-engine-factory {
    }
    advanced.timestamp-generator {
      drift-warning {
      }
    }
    advanced.request-tracker {
      logs {
        slow {
        }
      }
    }
    advanced.throttler {
    }
    advanced.address-translator {
    }
    advanced.protocol {
      version = ${?OTOROSHI_CASSANDRA_PROTOCOL_VERSION}
      compression = ${?OTOROSHI_CASSANDRA_PROTOCOL_COMPRESSION}
    }
    advanced.request {
      trace {
      }
    }
    advanced.graph {
      paging-options {
        page-size = ${datastax-java-driver.advanced.continuous-paging.page-size}
        max-pages = ${datastax-java-driver.advanced.continuous-paging.max-pages}
        max-pages-per-second = ${datastax-java-driver.advanced.continuous-paging.max-pages-per-second}
        max-enqueued-pages = ${datastax-java-driver.advanced.continuous-paging.max-enqueued-pages}
      }
    }
    advanced.continuous-paging {
      page-size = ${datastax-java-driver.basic.request.page-size}
      timeout {
      }
    }
    advanced.monitor-reporting {
    }
    advanced.metrics {
      session {
        cql-requests {
        }
        throttling.delay {
        }
        continuous-cql-requests {
        }
        graph-requests {
        }
      }
      node {
        cql-messages {
        }
        graph-messages {
        }
      }
    }
    advanced.socket {
    }
    advanced.heartbeat {
      timeout = ${datastax-java-driver.advanced.connection.init-query-timeout}
    }
    advanced.metadata {
      topology-event-debouncer {
      }
      schema {
        request-timeout = ${datastax-java-driver.basic.request.timeout}
        request-page-size = ${datastax-java-driver.basic.request.page-size}
        debouncer {
        }
      }
    }
    advanced.control-connection {
      timeout = ${datastax-java-driver.advanced.connection.init-query-timeout}
      schema-agreement {
      }
    }
    advanced.prepared-statements {
      reprepare-on-up {
        timeout = ${datastax-java-driver.advanced.connection.init-query-timeout}
      }
    }
    advanced.netty {
      io-group {
        shutdown {quiet-period = 2, timeout = 15, unit = SECONDS}
      }
      admin-group {
        shutdown {quiet-period = 2, timeout = 15, unit = SECONDS}
      }
      timer {
      }
    }
    advanced.coalescer {
    }
  }
  actorsystems {
    otoroshi {
      akka { # otoroshi actorsystem configuration
        version = ${akka.version}
        default-dispatcher {
          fork-join-executor {
            parallelism-factor = ${?OTOROSHI_CORE_DISPATCHER_PARALLELISM_FACTOR}
            parallelism-min = ${?OTOROSHI_CORE_DISPATCHER_PARALLELISM_MIN}
            parallelism-max = ${?OTOROSHI_CORE_DISPATCHER_PARALLELISM_MAX}
            task-peeking-mode = ${?OTOROSHI_CORE_DISPATCHER_TASK_PEEKING_MODE}
          }
          throughput = ${?OTOROSHI_CORE_DISPATCHER_THROUGHPUT}
        }
        http {
          parsing {
            max-uri-length             = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_URI_LENGTH}
            max-method-length          = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_METHOD_LENGTH}
            max-response-reason-length = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_RESPONSE_REASON_LENGTH}
            max-header-name-length     = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_HEADER_NAME_LENGTH}
            max-header-value-length    = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_HEADER_VALUE_LENGTH}
            max-header-count           = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_HEADER_COUNT}
            max-chunk-ext-length       = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_CHUNK_EXT_LENGTH}
            max-chunk-size             = ${?AKKA_HTTP_CLIENT_MAX_CHUNK_SIZE}
            max-chunk-size             = ${?OTOROSHI_AKKA_HTTP_CLIENT_MAX_CHUNK_SIZE}
            max-chunk-size             = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_CHUNK_SIZE}
            max-content-length         = ${?AKKA_HTTP_CLIENT_MAX_CONTENT_LENGHT}
            max-content-length         = ${?OTOROSHI_AKKA_HTTP_CLIENT_MAX_CONTENT_LENGHT}
            max-content-length         = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_CONTENT_LENGHT}
            max-to-strict-bytes        = ${?AKKA_HTTP_CLIENT_MAX_TO_STRICT_BYTES}
            max-to-strict-bytes        = ${?OTOROSHI_AKKA_HTTP_CLIENT_MAX_TO_STRICT_BYTES}
            max-to-strict-bytes        = ${?OTOROSHI_AKKA_HTTP_CLIENT_PARSING_MAX_TO_STRICT_BYTES}
          }
        }
      }
    }
    datastore {
      akka {
        version = ${akka.version}
        default-dispatcher {
          fork-join-executor {
          }
        }
      }
    }
  }
}
otoroshi {
  domain = ${?app.domain}
  maintenanceMode = ${?OTOROSHI_MAINTENANCE_MODE_ENABLED} # enable global maintenance mode
  secret = ${?OTOROSHI_SECRET}  # the secret used to sign sessions
  admin-api-secret = ${?OTOROSHI_ADMIN_API_SECRET}  # the secret for admin api
  elSettings {
    allowEnvAccess = ${?OTOROSHI_EL_SETTINGS_ALLOW_ENV_ACCESS}
    allowConfigAccess = ${?OTOROSHI_EL_SETTINGS_ALLOW_CONFIG_ACCESS}
  }
  open-telemetry {
  	server-logs {
      enabled = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_ENABLED}
      gzip = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_GZIP}
      grpc = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_GRPC}
      endpoint = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_ENDPOINT}
      timeout = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_TIMEOUT}
      client_cert = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_CLIENT_CERT}
      trusted_cert = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_TRUSTED_CERT}
      headers = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_HEADERS}
      max_batch = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_MAX_BATCH}
      max_duration = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_LOGS_MAX_DURATION}
  	}
  	server-metrics {
      enabled = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_ENABLED}
      gzip = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_GZIP}
      grpc = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_GRPC}
      endpoint = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_ENDPOINT}
      timeout = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_TIMEOUT}
      client_cert = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_CLIENT_CERT}
      trusted_cert = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_TRUSTED_CERT}
      headers = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_HEADERS}
      max_batch = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_MAX_BATCH}
      max_duration = ${?OTOROSHI_OPEN_TELEMETRY_SERVER_METRICS_MAX_DURATION}
    }
  }
  next {
    state-sync-interval = ${?OTOROSHI_NEXT_STATE_SYNC_INTERVAL}
    export-reporting = ${?OTOROSHI_NEXT_EXPORT_REPORTING}
    monitor-proxy-state-size = ${?OTOROSHI_NEXT_MONITOR_PROXY_STATE_SIZE}
    monitor-datastore-size = ${?OTOROSHI_NEXT_MONITOR_DATASTORE_SIZE}
    plugins {
      merge-sync-steps = ${?OTOROSHI_NEXT_PLUGINS_MERGE_SYNC_STEPS}
      apply-legacy-checks = ${?OTOROSHI_NEXT_PLUGINS_APPLY_LEGACY_CHECKS}
    }
    experimental {
    	netty-client {
    		wiretap = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_CLIENT_WIRETAP}
    		enforce = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_CLIENT_ENFORCE}
				enforce-akka = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_CLIENT_ENFORCE_AKKA}
    	}
   		netty-server {
   			enabled = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_ENABLED}
   			new-engine-only = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_NEW_ENGINE_ONLY}
   			host = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HOST}
   			http-port = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_PORT}
   			exposed-http-port = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_EXPOSED_HTTP_PORT}
   			https-port = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTPS_PORT}
				exposed-https-port = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_EXPOSED_HTTPS_PORT}
   			wiretap = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_WIRETAP}
   			accesslog = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_ACCESSLOG}
        threads = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_THREADS}
   			parser {
   				allowDuplicateContentLengths = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_ALLOW_DUPLICATE_CONTENT_LENGTHS}
          validateHeaders = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_VALIDATE_HEADERS}
          h2cMaxContentLength = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_H_2_C_MAX_CONTENT_LENGTH}
          initialBufferSize = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_INITIAL_BUFFER_SIZE}
          maxHeaderSize = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_MAX_HEADER_SIZE}
          maxInitialLineLength = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_MAX_INITIAL_LINE_LENGTH}
          maxChunkSize = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_PARSER_MAX_CHUNK_SIZE}
   			}
   			http2 {
					enabled = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP2_ENABLED}
					h2c = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP2_H2C}
				}
   			http3 {
   				enabled = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP3_ENABLED}
   				port = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP3_PORT}
   				exposedPort = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP3_EXPOSED_PORT}
          initialMaxStreamsBidirectional = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_INITIAL_MAX_STREAMS_BIDIRECTIONAL}
          initialMaxStreamDataBidirectionalRemote = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_INITIAL_MAX_STREAM_DATA_BIDIRECTIONAL_REMOTE}
          initialMaxStreamDataBidirectionalLocal = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_INITIAL_MAX_STREAM_DATA_BIDIRECTIONAL_LOCAL}
          initialMaxData = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_INITIAL_MAX_DATA}
          maxRecvUdpPayloadSize = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_MAX_RECV_UDP_PAYLOAD_SIZE}
          maxSendUdpPayloadSize = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_MAX_SEND_UDP_PAYLOAD_SIZE}
          disableQpackDynamicTable = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_HTTP_3_DISABLE_QPACK_DYNAMIC_TABLE}
   			}
   			native {
   				enabled = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_NATIVE_ENABLED}
   				driver = ${?OTOROSHI_NEXT_EXPERIMENTAL_NETTY_SERVER_NATIVE_DRIVER}
   			}
   		}
    }
  }
  options {
    jsonPathNullReadIsJsNull = ${?OTOROSHI_OPTIONS_JSONPATHNULLREADISJSNULL}
    bypassUserRightsCheck = ${?OTOROSHI_OPTIONS_BYPASSUSERRIGHTSCHECK}
    emptyContentLengthIsChunked = ${?OTOROSHI_OPTIONS_EMPTYCONTENTLENGTHISCHUNKED}
    detectApiKeySooner = ${?OTOROSHI_OPTIONS_DETECTAPIKEYSOONER}
    sendClientChainAsPem = ${?OTOROSHI_OPTIONS_SENDCLIENTCHAINASPEM}
    useOldHeadersComposition = ${?OTOROSHI_OPTIONS_USEOLDHEADERSCOMPOSITION}
    manualDnsResolve = ${?OTOROSHI_OPTIONS_MANUALDNSRESOLVE}
    useEventStreamForScriptEvents = ${?OTOROSHI_OPTIONS_USEEVENTSTREAMFORSCRIPTEVENTS}
    trustXForwarded = ${?OTOROSHI_OPTIONS_TRUST_XFORWARDED}
    disableFunnyLogos = ${?OTOROSHI_OPTIONS_DISABLE_FUNNY_LOGOS}
    staticExposedDomain = ${?OTOROSHI_OPTIONS_STATIC_EXPOSED_DOMAIN}
    enable-json-media-type-with-open-charset = ${?OTOROSHI_OPTIONS_ENABLE_JSON_MEDIA_TYPE_WITH_OPEN_CHARSET}
    dynamicBodySizeCompute = ${?OTOROSHI_OPTIONS_DYNAMIC_BODY_SIZE_COMPUTE}
  }
  wasm {
  	cache {
  		ttl = ${?OTOROSHI_WASM_CACHE_TTL}
  		size = ${?OTOROSHI_WASM_CACHE_SIZE}
  	}
  	queue {
  		buffer {
  			size = ${?OTOROSHI_WASM_QUEUE_BUFFER_SIZE}
  		}
  	}
  }
  anonymous-reporting {
		enabled = ${?OTOROSHI_ANONYMOUS_REPORTING_ENABLED}
		url = ${?OTOROSHI_ANONYMOUS_REPORTING_REDIRECT}
  	url = ${?OTOROSHI_ANONYMOUS_REPORTING_URL}
  	timeout = ${?OTOROSHI_ANONYMOUS_REPORTING_TIMEOUT}
  	tls {
			enabled = ${?OTOROSHI_ANONYMOUS_REPORTING_TLS_ENABLED}  # enable mtls
			loose = ${?OTOROSHI_ANONYMOUS_REPORTING_TLS_LOOSE}  # loose verification
			trustAll = ${?OTOROSHI_ANONYMOUS_REPORTING_TLS_ALL} # trust any CA
		}
		proxy {
			enabled = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_ENABLED}  # enable proxy
			host = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_HOST},
			port = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_PORT},
			principal = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_PRINCIPAL},
			password = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_PASSWORD},
			ntlmDomain = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_DOMAIN},
			encoding = ${?OTOROSHI_ANONYMOUS_REPORTING_PROXY_ENCODING},
		}
  }
  backoffice {
    flags {
      useAkkaHttpClient = ${?OTOROSHI_BACKOFFICE_FLAGS_USE_AKKA_HTTP_CLIENT}
      logUrl = ${?OTOROSHI_BACKOFFICE_FLAGS_LOG_URL}
      requestTimeout = ${?OTOROSHI_BACKOFFICE_FLAGS_REQUEST_TIMEOUT}
    }
  }
  sessions {
    secret = ${otoroshi.secret}
    secret = ${?OTOROSHI_SESSIONS_SECRET}
  }
  cache {
    enabled = ${?USE_CACHE}
    enabled = ${?OTOROSHI_USE_CACHE}
    enabled = ${?OTOROSHI_ENTITIES_CACHE_ENABLED}
    ttl = ${?OTOROSHI_ENTITIES_CACHE_TTL}
  }
  metrics {
    enabled = ${?OTOROSHI_METRICS_ENABLED}
    every = ${?OTOROSHI_METRICS_EVERY}
    accessKey = ${?app.health.accessKey}
    accessKey = ${?OTOROSHI_app.health.accessKey}
    accessKey = ${?OTOROSHI_METRICS_ACCESS_KEY}
  }
  plugins {
    packagesStr = ${?OTOROSHI_PLUGINS_SCAN_PACKAGES}
    print = ${?OTOROSHI_PLUGINS_PRINT}
    blacklistedStr = ${?OTOROSHI_PLUGINS_BACKLISTED}
  }
  scripts {
    enabled = ${?OTOROSHI_SCRIPTS_ENABLED} # enable scripts
    static { # settings for statically enabled script/plugins
      enabled = ${?OTOROSHI_SCRIPTS_STATIC_ENABLED}
      transformersRefsStr = ${?OTOROSHI_SCRIPTS_STATIC_TRANSFORMER_REFS}
      transformersConfig = {}
      transformersConfigStr= ${?OTOROSHI_SCRIPTS_STATIC_TRANSFORMER_CONFIG}
      validatorRefsStr = ${?OTOROSHI_SCRIPTS_STATIC_VALIDATOR_REFS}
      validatorConfig = {}
      validatorConfigStr = ${?OTOROSHI_SCRIPTS_STATIC_VALIDATOR_CONFIG}
      preRouteRefsStr = ${?OTOROSHI_SCRIPTS_STATIC_PRE_ROUTE_REFS}
      preRouteConfig = {}
      preRouteConfigStr = ${?OTOROSHI_SCRIPTS_STATIC_PRE_ROUTE_CONFIG}
      sinkRefsStr = ${?OTOROSHI_SCRIPTS_STATIC_SINK_REFS}
      sinkConfig = {}
      sinkConfigStr = ${?OTOROSHI_SCRIPTS_STATIC_SINK_CONFIG}
      jobsRefsStr = ${?OTOROSHI_SCRIPTS_STATIC_JOBS_REFS}
      jobsConfig = {}
      jobsConfigStr = ${?OTOROSHI_SCRIPTS_STATIC_JOBS_CONFIG}
    }
  }
  tls = ${otoroshi.ssl}
  ssl {
    cipherSuites = ${otoroshi.ssl.cipherSuitesJDK11}
    protocols = ${otoroshi.ssl.modernProtocols}
    cacert {
    }
    fromOutside {
      clientAuth = ${?SSL_OUTSIDE_CLIENT_AUTH}
      clientAuth = ${?OTOROSHI_SSL_OUTSIDE_CLIENT_AUTH}
      netty {
        clientAuth = ${?OTOROSHI_SSL_OUTSIDE_NETTY_CLIENT_AUTH}
      }
    }
    trust {
      all = ${?OTOROSHI_SSL_TRUST_ALL}
    }
    rootCa {
    	ca = ${?OTOROSHI_SSL_ROOTCA_CA}
    	cert = ${?OTOROSHI_SSL_ROOTCA_CERT}
    	key = ${?OTOROSHI_SSL_ROOTCA_KEY}
			importCa = ${?OTOROSHI_SSL_ROOTCA_IMPORTCA}
    }
    initialCacert = ${?CLUSTER_WORKER_INITIAL_CACERT}
    initialCacert = ${?OTOROSHI_CLUSTER_WORKER_INITIAL_CACERT}
    initialCacert = ${?INITIAL_CACERT}
    initialCacert = ${?OTOROSHI_INITIAL_CACERT}
    initialCert = ${?CLUSTER_WORKER_INITIAL_CERT}
    initialCert = ${?OTOROSHI_CLUSTER_WORKER_INITIAL_CERT}
    initialCert = ${?INITIAL_CERT}
    initialCert = ${?OTOROSHI_INITIAL_CERT}
    initialCertKey = ${?CLUSTER_WORKER_INITIAL_CERT_KEY}
    initialCertKey = ${?OTOROSHI_CLUSTER_WORKER_INITIAL_CERT_KEY}
    initialCertKey = ${?INITIAL_CERT_KEY}
    initialCertKey = ${?OTOROSHI_INITIAL_CERT_KEY}
    initialCertImportCa = ${?OTOROSHI_INITIAL_CERT_IMPORTCA}
  }
  cluster {
    mode = ${?CLUSTER_MODE} # can be "off", "leader", "worker"
    mode = ${?OTOROSHI_CLUSTER_MODE} # can be "off", "leader", "worker"
    compression = ${?CLUSTER_COMPRESSION} # compression of the data sent between leader cluster and worker cluster. From -1 (disabled) to 9
    compression = ${?OTOROSHI_CLUSTER_COMPRESSION} # compression of the data sent between leader cluster and worker cluster. From -1 (disabled) to 9
    retryDelay = ${?CLUSTER_RETRY_DELAY} # the delay before retrying a request to leader
    retryDelay = ${?OTOROSHI_CLUSTER_RETRY_DELAY} # the delay before retrying a request to leader
    retryFactor = ${?CLUSTER_RETRY_FACTOR} # the retry factor to avoid high load on failing nodes
    retryFactor = ${?OTOROSHI_CLUSTER_RETRY_FACTOR} # the retry factor to avoid high load on failing nodes
    selfAddress = ${?CLUSTER_SELF_ADDRESS} # the instance ip address
    selfAddress = ${?OTOROSHI_CLUSTER_SELF_ADDRESS} # the instance ip address
    autoUpdateState = ${?CLUSTER_AUTO_UPDATE_STATE} # auto update cluster state with a job (more efficient
    autoUpdateState = ${?OTOROSHI_CLUSTER_AUTO_UPDATE_STATE} # auto update cluster state with a job (more efficient
    backup {
      enabled = ${?OTOROSHI_CLUSTER_BACKUP_ENABLED}
			kind = ${?OTOROSHI_CLUSTER_BACKUP_KIND}
			instance {
				can-write = ${?OTOROSHI_CLUSTER_BACKUP_INSTANCE_CAN_WRITE}
				can-read = ${?OTOROSHI_CLUSTER_BACKUP_INSTANCE_CAN_READ}
			}
			s3 {
				bucket = ${?OTOROSHI_CLUSTER_BACKUP_S3_BUCKET}
        endpoint = ${?OTOROSHI_CLUSTER_BACKUP_S3_ENDPOINT}
        region = ${?OTOROSHI_CLUSTER_BACKUP_S3_REGION}
        access = ${?OTOROSHI_CLUSTER_BACKUP_S3_ACCESSKEY}
        secret = ${?OTOROSHI_CLUSTER_BACKUP_S3_SECRET}
        path = ${?OTOROSHI_CLUSTER_BACKUP_S3_PATH}
        chunk-size = ${?OTOROSHI_CLUSTER_BACKUP_S3_CHUNK_SIZE}
        v4auth = ${?OTOROSHI_CLUSTER_BACKUP_S3_V4AUTH}
        acl = ${?OTOROSHI_CLUSTER_BACKUP_S3_ACL}
			}
    }
    relay { # relay routing settings
      enabled = ${?OTOROSHI_CLUSTER_RELAY_ENABLED} # enable relay routing
      leaderOnly = ${?OTOROSHI_CLUSTER_RELAY_LEADER_ONLY} # workers always pass through leader for relay routing
      location {
        provider = ${?otoroshi.instance.provider}
        provider = ${?OTOROSHI_CLUSTER_RELAY_LOCATION_PROVIDER}
        provider = ${?app.instance.provider}
        zone = ${?otoroshi.instance.zone}
        zone = ${?OTOROSHI_CLUSTER_RELAY_LOCATION_ZONE}
        zone = ${?app.instance.zone}
        region = ${?otoroshi.instance.region}
        region = ${?OTOROSHI_CLUSTER_RELAY_LOCATION_REGION}
        region = ${?app.instance.region}
        datacenter = ${?otoroshi.instance.dc}
        datacenter = ${?OTOROSHI_CLUSTER_RELAY_LOCATION_DATACENTER}
        datacenter = ${?app.instance.dc}
        rack = ${?otoroshi.instance.rack}
        rack = ${?OTOROSHI_CLUSTER_RELAY_LOCATION_RACK}
        rack = ${?app.instance.rack}
      }
      exposition {
        url = ${?OTOROSHI_CLUSTER_RELAY_EXPOSITION_URL}
        urlsStr = ${?OTOROSHI_CLUSTER_RELAY_EXPOSITION_URLS}
        hostname = ${?OTOROSHI_CLUSTER_RELAY_EXPOSITION_HOSTNAME}
        clientId = ${?OTOROSHI_CLUSTER_RELAY_EXPOSITION_CLIENT_ID}
        clientSecret = ${?OTOROSHI_CLUSTER_RELAY_EXPOSITION_CLIENT_SECRET}
        ipAddress = ${?OTOROSHI_CLUSTER_RELAY_EXPOSITION_IP_ADDRESS}
      }
    }
    mtls {
      enabled = ${?CLUSTER_MTLS_ENABLED}  # enable mtls
      enabled = ${?OTOROSHI_CLUSTER_MTLS_ENABLED}  # enable mtls
      loose = ${?CLUSTER_MTLS_LOOSE}  # loose verification
      loose = ${?OTOROSHI_CLUSTER_MTLS_LOOSE}  # loose verification
      trustAll = ${?CLUSTER_MTLS_TRUST_ALL} # trust any CA
      trustAll = ${?OTOROSHI_CLUSTER_MTLS_TRUST_ALL} # trust any CA
    }
    proxy {
			enabled = ${?CLUSTER_PROXY_ENABLED}  # enable proxy
			host = ${?CLUSTER_PROXY_HOST},
			port = ${?CLUSTER_PROXY_PORT},
			principal = ${?CLUSTER_PROXY_PRINCIPAL},
			password = ${?CLUSTER_PROXY_PASSWORD},
			ntlmDomain = ${?CLUSTER_PROXY_NTLM_DOMAIN},
			encoding = ${?CLUSTER_PROXY_ENCODING},
    }
    leader {
      name = ${?CLUSTER_LEADER_NAME} # the leader name
      name = ${?OTOROSHI_CLUSTER_LEADER_NAME} # the leader name
      urlsStr = ${?CLUSTER_LEADER_URLS} # the leader urls
      urlsStr = ${?OTOROSHI_CLUSTER_LEADER_URLS} # the leader urls
      url = ${?CLUSTER_LEADER_URL} # the leader url
      url = ${?OTOROSHI_CLUSTER_LEADER_URL} # the leader url
      host = ${?CLUSTER_LEADER_HOST} # the leaders api hostname
      host = ${?OTOROSHI_CLUSTER_LEADER_HOST} # the leaders api hostname
      clientId = ${?CLUSTER_LEADER_CLIENT_ID} # the leaders apikey id to access otoroshi admin api
      clientId = ${?OTOROSHI_CLUSTER_LEADER_CLIENT_ID} # the leaders apikey id to access otoroshi admin api
      clientSecret = ${?CLUSTER_LEADER_CLIENT_SECRET} # the leaders apikey secret to access otoroshi admin api
      clientSecret = ${?OTOROSHI_CLUSTER_LEADER_CLIENT_SECRET} # the leaders apikey secret to access otoroshi admin api
      groupingBy = ${?CLUSTER_LEADER_GROUP_BY} # items grouping when streaming state
      groupingBy = ${?OTOROSHI_CLUSTER_LEADER_GROUP_BY} # items grouping when streaming state
      cacheStateFor = ${?CLUSTER_LEADER_CACHE_STATE_FOR} # the ttl for local state cache
      cacheStateFor = ${?OTOROSHI_CLUSTER_LEADER_CACHE_STATE_FOR} # the ttl for local state cache
      stateDumpPath = ${?CLUSTER_LEADER_DUMP_PATH} # eventually a dump state path for debugging purpose
      stateDumpPath = ${?OTOROSHI_CLUSTER_LEADER_DUMP_PATH} # eventually a dump state path for debugging purpose
    }
    worker {
      name = ${?CLUSTER_WORKER_NAME} # the workers name
      name = ${?OTOROSHI_CLUSTER_WORKER_NAME} # the workers name
      retries = ${?CLUSTER_WORKER_RETRIES} # the number of retries when pushing quotas/pulling state
      retries = ${?OTOROSHI_CLUSTER_WORKER_RETRIES} # the number of retries when pushing quotas/pulling state
      timeout = ${?CLUSTER_WORKER_TIMEOUT} # the workers timeout when interacting with leaders
      timeout = ${?OTOROSHI_CLUSTER_WORKER_TIMEOUT} # the workers timeout when interacting with leaders
      tenantsStr = ${?CLUSTER_WORKER_TENANTS} # the list (coma separated) of organization served by this worker. If none, it's all
      tenantsStr = ${?OTOROSHI_CLUSTER_WORKER_TENANTS} # the list (coma separated) of organization served by this worker. If none, it's all
      dbpath = ${?CLUSTER_WORKER_DB_PATH} # state dump path for debugging purpose
      dbpath = ${?OTOROSHI_CLUSTER_WORKER_DB_PATH} # state dump path for debugging purpose
      dataStaleAfter = ${?CLUSTER_WORKER_DATA_STALE_AFTER} # the amount of time needed to consider state is stale
      dataStaleAfter = ${?OTOROSHI_CLUSTER_WORKER_DATA_STALE_AFTER} # the amount of time needed to consider state is stale
      swapStrategy = ${?CLUSTER_WORKER_SWAP_STRATEGY} # the internal memory store strategy, can be Replace or Merge
      swapStrategy = ${?OTOROSHI_CLUSTER_WORKER_SWAP_STRATEGY} # the internal memory store strategy, can be Replace or Merge
      modern = ${?CLUSTER_WORKER_STORE_MODERN}
      modern = ${?OTOROSHI_CLUSTER_WORKER_STORE_MODERN}
      useWs = ${?CLUSTER_WORKER_USE_WS}
      useWs = ${?OTOROSHI_CLUSTER_WORKER_USE_WS}
      state {
        retries = ${otoroshi.cluster.worker.retries} # the number of retries when pulling state
        retries = ${?CLUSTER_WORKER_STATE_RETRIES} # the number of retries when pulling state
        retries = ${?OTOROSHI_CLUSTER_WORKER_STATE_RETRIES} # the number of retries when pulling state
        pollEvery = ${?CLUSTER_WORKER_POLL_EVERY} # polling interval
        pollEvery = ${?OTOROSHI_CLUSTER_WORKER_POLL_EVERY} # polling interval
        timeout = ${otoroshi.cluster.worker.timeout} # the workers timeout when polling state
        timeout = ${?CLUSTER_WORKER_POLL_TIMEOUT} # the workers timeout when polling state
        timeout = ${?OTOROSHI_CLUSTER_WORKER_POLL_TIMEOUT} # the workers timeout when polling state
      }
      quotas {
        retries = ${otoroshi.cluster.worker.retries} # the number of retries when pushing quotas
        retries = ${?CLUSTER_WORKER_QUOTAS_RETRIES} # the number of retries when pushing quotas
        retries = ${?OTOROSHI_CLUSTER_WORKER_QUOTAS_RETRIES} # the number of retries when pushing quotas
        pushEvery = ${?CLUSTER_WORKER_PUSH_EVERY} # pushing interval
        pushEvery = ${?OTOROSHI_CLUSTER_WORKER_PUSH_EVERY} # pushing interval
        timeout = ${otoroshi.cluster.worker.timeout} # the workers timeout when pushing quotas
        timeout = ${?CLUSTER_WORKER_PUSH_TIMEOUT} # the workers timeout when pushing quotas
        timeout = ${?OTOROSHI_CLUSTER_WORKER_PUSH_TIMEOUT} # the workers timeout when pushing quotas
      }
    }
    analytics { # settings for the analytics actor system which is separated from otoroshi default one for performance reasons
      pressure {
        enabled = ${?OTOROSHI_ANALYTICS_PRESSURE_ENABLED}
      }
      actorsystem {
        akka {
          version = ${akka.version}
          default-dispatcher {
            fork-join-executor {
            }
          }
          # http {
          #   parsing {
          #     max-chunk-size             = ${?AKKA_HTTP_CLIENT_ANALYTICS_MAX_CHUNK_SIZE}
          #     max-chunk-size             = ${?OTOROSHI_AKKA_HTTP_CLIENT_ANALYTICS_MAX_CHUNK_SIZE}
          #     max-content-length         = ${?AKKA_HTTP_CLIENT_ANALYTICS_MAX_CONTENT_LENGHT}
          #     max-content-length         = ${?OTOROSHI_AKKA_HTTP_CLIENT_ANALYTICS_MAX_CONTENT_LENGHT}
          #     max-to-strict-bytes        = ${?AKKA_HTTP_CLIENT_ANALYTICS_MAX_TO_STRICT_BYTES}
          #     max-to-strict-bytes        = ${?OTOROSHI_AKKA_HTTP_CLIENT_ANALYTICS_MAX_TO_STRICT_BYTES}
          #   }
          # }
        }
      }
    }
  }
  headers { # the default headers value for specific otoroshi headers
  }
  requests {
    validate = ${?OTOROSHI_REQUESTS_VALIDATE}
    maxUrlLength = ${akka.http.parsing.max-uri-length}
    maxCookieLength = ${akka.http.parsing.max-header-value-length}
    maxHeaderNameLength = ${akka.http.parsing.max-header-name-length}
    maxHeaderValueLength = ${akka.http.parsing.max-header-value-length}
  }
  jmx {
    enabled = ${?OTOROSHI_JMX_ENABLED}
    port = ${?OTOROSHI_JMX_PORT}
  }
  loggers {
  }
  provider {
    dashboardUrl = ${?OTOROSHI_PROVIDER_DASHBOARD_URL}
    jsUrl = ${?OTOROSHI_PROVIDER_JS_URL}
    cssUrl = ${?OTOROSHI_PROVIDER_CSS_URL}
    secret = ${?OTOROSHI_PROVIDER_SECRET}
    title = ${?OTOROSHI_PROVIDER_TITLE}
  }
  healthcheck {
    workers = ${?OTOROSHI_HEALTHCHECK_WORKERS}
    block-on-red = ${?OTOROSHI_HEALTHCHECK_BLOCK_ON_RED}
    block-on-red = ${?OTOROSHI_HEALTHCHECK_BLOCK_ON_500}
    ttl = ${?OTOROSHI_HEALTHCHECK_TTL}
    ttl-only = ${?OTOROSHI_HEALTHCHECK_TTL_ONLY}
  }
  vaults {
    enabled = ${?OTOROSHI_VAULTS_ENABLED}
    secrets-ttl = ${?OTOROSHI_VAULTS_SECRETS_TTL}
    secrets-error-ttl = ${?OTOROSHI_VAULTS_SECRETS_ERROR_TTL}
    cached-secrets = ${?OTOROSHI_VAULTS_CACHED_SECRETS}
    read-timeout = ${?otoroshi.vaults.read-ttl}
		read-timeout = ${?OTOROSHI_VAULTS_READ_TTL}
		read-timeout = ${?OTOROSHI_VAULTS_READ_TIMEOUT}
    parallel-fetchs = ${?OTOROSHI_VAULTS_PARALLEL_FETCHS}
    leader-fetch-only = ${?OTOROSHI_VAULTS_LEADER_FETCH_ONLY}
    env {
      prefix = ${?OTOROSHI_VAULTS_ENV_PREFIX}
    }
    local {
    	root = ${?OTOROSHI_VAULTS_LOCAL_ROOT}
    }
    # hashicorpvault {
    # }
  }
  tunnels {
    enabled = ${?OTOROSHI_TUNNELS_ENABLED}
    worker-ws = ${?OTOROSHI_TUNNELS_WORKER_WS}
    worker-use-internal-ports = ${?OTOROSHI_TUNNELS_WORKER_USE_INTERNAL_PORTS}
    worker-use-loadbalancing = ${?OTOROSHI_TUNNELS_WORKER_USE_LOADBALANCING}
    default {
      enabled = ${?OTOROSHI_TUNNELS_DEFAULT_ENABLED}
      id = ${?OTOROSHI_TUNNELS_DEFAULT_ID}
      name = ${?OTOROSHI_TUNNELS_DEFAULT_NAME}
			url = ${?OTOROSHI_TUNNELS_DEFAULT_URL}
			host = ${?OTOROSHI_TUNNELS_DEFAULT_HOST}
			clientId = ${?OTOROSHI_TUNNELS_DEFAULT_CLIENT_ID}
			clientSecret = ${?OTOROSHI_TUNNELS_DEFAULT_CLIENT_SECRET}
			export-routes = ${?OTOROSHI_TUNNELS_DEFAULT_EXPORT_ROUTES} # send routes information to remote otoroshi instance to facilitate remote route exposition
			export-routes-tag = ${?OTOROSHI_TUNNELS_DEFAULT_EXPORT_TAG} # only send routes information if the route has this tag
      proxy {
      }
    }
  }
  admin-extensions {
  	enabled = ${?OTOROSHI_ADMIN_EXTENSIONS_ENABLED}
  	configurations {
  		otoroshi_extensions_foo {
  		}
      otoroshi_extensions_greenscore {
        enabled = ${?OTOROSHI_ADMIN_EXTENSIONS_GREENSCORE_ENABLED}
      }
  	}
  }
}
http.port = ${?otoroshi.http.port}     # the main http port for the otoroshi server
http.port = ${?PORT}                   # the main http port for the otoroshi server
http.port = ${?OTOROSHI_PORT}                   # the main http port for the otoroshi server
http.port = ${?OTOROSHI_HTTP_PORT}                   # the main http port for the otoroshi server
play.server.http.port = ${http.port}   # the main http port for the otoroshi server
play.server.http.port = ${?PORT}       # the main http port for the otoroshi server
play.server.http.port = ${?OTOROSHI_PORT}       # the main http port for the otoroshi server
play.server.http.port = ${?OTOROSHI_HTTP_PORT}       # the main http port for the otoroshi server
https.port = ${?otoroshi.https.port}   # the main https port for the otoroshi server
https.port = ${?HTTPS_PORT}            # the main https port for the otoroshi server
https.port = ${?OTOROSHI_HTTPS_PORT}            # the main https port for the otoroshi server
play.server.https.keyStoreDumpPath = ${?HTTPS_KEYSTORE_DUMP_PATH}           # the file path where the TLSContext will be dumped (for debugging purposes only)
play.server.https.keyStoreDumpPath = ${?OTOROSHI_HTTPS_KEYSTORE_DUMP_PATH}           # the file path where the TLSContext will be dumped (for debugging purposes only)
play.http.secret.key = ${otoroshi.secret}       # the secret used to signed session cookies                       
play.http.secret.key = ${?PLAY_CRYPTO_SECRET}   # the secret used to signed session cookies
play.http.secret.key = ${?OTOROSHI_CRYPTO_SECRET}   # the secret used to signed session cookies
play.server.http.idleTimeout = ${?PLAY_SERVER_IDLE_TIMEOUT}       # the default server idle timeout
play.server.http.idleTimeout = ${?OTOROSHI_SERVER_IDLE_TIMEOUT}       # the default server idle timeout
play.server.akka.requestTimeout = ${?PLAY_SERVER_REQUEST_TIMEOUT} # the default server idle timeout (for akka server specifically)
play.server.akka.requestTimeout = ${?OTOROSHI_SERVER_REQUEST_TIMEOUT} # the default server idle timeout (for akka server specifically)
http2.enabled = ${?otoroshi.http2.enabled}
http2.enabled = ${?HTTP2_ENABLED}  # enable HTTP2 support
http2.enabled = ${?OTOROSHI_HTTP2_ENABLED}  # enable HTTP2 support
play.server.https.keyStore.path=${?HTTPS_KEYSTORE_PATH}         # settings for the default server keystore
play.server.https.keyStore.path=${?OTOROSHI_HTTPS_KEYSTORE_PATH}         # settings for the default server keystore
play.server.https.keyStore.type=${?HTTPS_KEYSTORE_TYPE}         # settings for the default server keystore
play.server.https.keyStore.type=${?OTOROSHI_HTTPS_KEYSTORE_TYPE}         # settings for the default server keystore
play.server.https.keyStore.password=${?HTTPS_KEYSTORE_PASSWORD} # settings for the default server keystore
play.server.https.keyStore.password=${?OTOROSHI_HTTPS_KEYSTORE_PASSWORD} # settings for the default server keystore
play.server.https.keyStore.algorithm=${?HTTPS_KEYSTORE_ALGO}    # settings for the default server keystore
play.server.https.keyStore.algorithm=${?OTOROSHI_HTTPS_KEYSTORE_ALGO}    # settings for the default server keystore
play.server.websocket.frame.maxLength = ${?OTOROSHI_WEBSOCKET_FRAME_MAX_LENGTH}
play.http {
  session {
    secure = ${?SESSION_SECURE_ONLY}  # the cookie for otoroshi backoffice should be exhanged over https only
    secure = ${?OTOROSHI_SESSION_SECURE_ONLY}  # the cookie for otoroshi backoffice should be exhanged over https only
    maxAge = ${?SESSION_MAX_AGE}      # the cookie for otoroshi backoffice max age
    maxAge = ${?OTOROSHI_SESSION_MAX_AGE}      # the cookie for otoroshi backoffice max age
    # domain = "."${?app.domain}         # the cookie for otoroshi backoffice domain
    domain = "."${otoroshi.domain}    # the cookie for otoroshi backoffice domain
    domain = ${?SESSION_DOMAIN}       # the cookie for otoroshi backoffice domain
    domain = ${?OTOROSHI_SESSION_DOMAIN}       # the cookie for otoroshi backoffice domain
    cookieName = ${?SESSION_NAME}     # the cookie for otoroshi backoffice name
    cookieName = ${?OTOROSHI_SESSION_NAME}     # the cookie for otoroshi backoffice name
  }
}
akka { # akka specific configuration
  actor {
    default-dispatcher {
      fork-join-executor {     
        parallelism-factor = ${?OTOROSHI_AKKA_DISPATCHER_PARALLELISM_FACTOR}
        parallelism-min = ${?OTOROSHI_AKKA_DISPATCHER_PARALLELISM_MIN}
        parallelism-max = ${?OTOROSHI_AKKA_DISPATCHER_PARALLELISM_MAX}
        task-peeking-mode = ${?OTOROSHI_AKKA_DISPATCHER_TASK_PEEKING_MODE}
      }
      throughput = ${?OTOROSHI_AKKA_DISPATCHER_THROUGHPUT}
    }
  }
  http {
    server {
      max-connections = ${?OTOROSHI_AKKA_HTTP_SERVER_MAX_CONNECTIONS}
      pipelining-limit = ${?OTOROSHI_AKKA_HTTP_SERVER_PIPELINING_LIMIT}
      backlog = ${?OTOROSHI_AKKA_HTTP_SERVER_BACKLOG}
      socket-options {
      }
      http2 {
      }
    }
    client {
      socket-options {
      }
    }
    host-connection-pool {
      max-connections = ${?OTOROSHI_AKKA_HTTP_SERVER_HOST_CONNECTION_POOL_MAX_CONNECTIONS}
      max-open-requests = ${?OTOROSHI_AKKA_HTTP_SERVER_HOST_CONNECTION_POOL_MAX_OPEN_REQUESTS}
      pipelining-limit = ${?OTOROSHI_AKKA_HTTP_SERVER_HOST_CONNECTION_POOL_PIPELINING_LIMIT}
      client {
        socket-options {
        }
      }
    }
    parsing {
      max-uri-length             = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_URI_LENGTH}
      max-method-length          = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_METHOD_LENGTH}
      max-response-reason-length = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_RESPONSE_REASON_LENGTH}
      max-header-name-length     = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_HEADER_NAME_LENGTH}
      max-header-value-length    = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_HEADER_VALUE_LENGTH}
      max-header-count           = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_HEADER_COUNT}
      max-chunk-ext-length       = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_CHUNK_EXT_LENGTH}
      max-chunk-size             = ${?AKKA_HTTP_SERVER_MAX_CHUNK_SIZE}
      max-chunk-size             = ${?OTOROSHI_AKKA_HTTP_SERVER_MAX_CHUNK_SIZE}
      max-chunk-size             = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_CHUNK_SIZE}
      max-content-length         = ${?AKKA_HTTP_SERVER_MAX_CONTENT_LENGHT}
      max-content-length         = ${?OTOROSHI_AKKA_HTTP_SERVER_MAX_CONTENT_LENGHT}
      max-content-length         = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_MAX_CONTENT_LENGHT}
      uri-parsing-mode           = ${?OTOROSHI_AKKA_HTTP_SERVER_PARSING_URI_PARSING_MODE} 
    }
  }
}