server:
  address: "${HTTP_BIND_ADDRESS:0.0.0.0}"
  port: "${HTTP_BIND_PORT:8080}"
  undertow:
    buffer-size: "${SERVER_UNDERTOW_BUFFER_SIZE:16384}"
    directBuffers: "${SERVER_UNDERTOW_DIRECT_BUFFERS:true}"
    threads:
      io: "${SERVER_UNDERTOW_THREADS_IO:4}"
      worker: "${SERVER_UNDERTOW_THREADS_WORKER:128}"
    max-http-post-size: "${SERVER_UNDERTOW_MAX_HTTP_POST_SIZE:10MB}"
    no-request-timeout: "${SERVER_UNDERTOW_NO_REQUEST_TIMEOUT:10000}"
    accesslog:
      enabled: true
      pattern: "%t %a %r %s (%D ms)"
      dir: logs/accesslog
    options:
      server:
        record-request-start-time: true
  servlet:
    encoding:
      charset: UTF-8
      force: true

spring:
  application:
    name: "${SPRING_APPLICATION_NAME:java-charge-point-server}"
  datasource:
    driver-class-name: "${SPRING_DRIVER_CLASS_NAME:org.postgresql.Driver}"
    url: "${SPRING_DATASOURCE_URL:jdbc:postgresql://postgres:5432/jcpp}"
    username: "${SPRING_DATASOURCE_USERNAME:postgres}"
    password: "${SPRING_DATASOURCE_PASSWORD:postgres}"
    hikari:
      leak-detection-threshold: "${SPRING_DATASOURCE_HIKARI_LEAK_DETECTION_THRESHOLD:0}"
      maximum-pool-size: "${SPRING_DATASOURCE_MAXIMUM_POOL_SIZE:64}"
      register-mbeans: "${SPRING_DATASOURCE_HIKARI_REGISTER_MBEANS:false}"
  servlet:
    multipart:
      max-file-size: "${SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE:50MB}"
      max-request-size: "${SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE:50MB}"
  main:
    allow-circular-references: "true"
  mvc:
    pathmatch.matching-strategy: "ANT_PATH_MATCHER"
    async.request-timeout: "${SPRING_MVC_ASYNC_REQUEST_TIMEOUT:30000}"
    cors:
      mappings:
        "[/api/**]":
          allowed-origin-patterns: "*"
          allowed-methods: "*"
          allowed-headers: "*"
          max-age: "1800"
          allow-credentials: "true"
  web:
    resources:
      chain:
        compressed: "true"
        strategy:
          content:
            enabled: "true"

security:
  jwt:
    tokenExpirationTime: "${JWT_TOKEN_EXPIRATION_TIME:9000}"
    refreshTokenExpTime: "${JWT_REFRESH_TOKEN_EXPIRATION_TIME:604800}"
    tokenIssuer: "${JWT_TOKEN_ISSUER:sanbing.io}"
    tokenSigningKey: "${JWT_TOKEN_SIGNING_KEY:NUI3T1FCSVI0MFNweFAxRjEyUUJ1QkVPc3V0T1hEdUJON0hiZ2NydzdzN0RBSVZwTE9rMFFWeDVTRnZ6djMxSw==}"
  # 安全设置配置
  settings:
    # 密码策略
    passwordPolicy:
      minimumLength: "${SECURITY_PASSWORD_POLICY_MINIMUM_LENGTH:6}"
      maximumLength: "${SECURITY_PASSWORD_POLICY_MAXIMUM_LENGTH:72}"
      minimumUppercaseLetters: "${SECURITY_PASSWORD_POLICY_MINIMUM_UPPERCASE_LETTERS:0}"
      minimumLowercaseLetters: "${SECURITY_PASSWORD_POLICY_MINIMUM_LOWERCASE_LETTERS:0}"
      minimumDigits: "${SECURITY_PASSWORD_POLICY_MINIMUM_DIGITS:0}"
      minimumSpecialCharacters: "${SECURITY_PASSWORD_POLICY_MINIMUM_SPECIAL_CHARACTERS:0}"
      allowWhitespaces: "${SECURITY_PASSWORD_POLICY_ALLOW_WHITESPACES:true}"
    # 最大登录失败次数
    maxFailedLoginAttempts: "${SECURITY_MAX_FAILED_LOGIN_ATTEMPTS:5}"

mybatis-plus:
  type-handlers-package: sanbing.jcpp.app.dal.config.ibatis.typehandlers

management:
  endpoints:
    web:
      exposure:
        include: '${METRICS_ENDPOINTS_EXPOSE:prometheus,health}'
  endpoint:
    health:
      show-details: always

metrics:
  enabled: "${METRICS_ENABLED:true}"
  timer:
    percentiles: "${METRICS_TIMER_PERCENTILES:0.5}"

# 应用程序服务注册中心配置
zk:
  enabled: "${ZOOKEEPER_ENABLED:false}"
  url: "${ZOOKEEPER_URL:zookeeper:2181}"
  retry-interval-ms: "${ZOOKEEPER_RETRY_INTERVAL_MS:3000}"
  connection-timeout-ms: "${ZOOKEEPER_CONNECTION_TIMEOUT_MS:3000}"
  session-timeout-ms: "${ZOOKEEPER_SESSION_TIMEOUT_MS:3000}"
  zk-dir: "${ZOOKEEPER_NODES_DIR:/jcpp}"
  recalculate-delay: "${ZOOKEEPER_RECALCULATE_DELAY_MS:0}"

# 队列配置
queue:
  # 可选 kafka、memory
  type: "${QUEUE_TYPE:memory}"
  partitions:
    hash_function_name: "${QUEUE_PARTITIONS_HASH_FUNCTION_NAME:murmur3_128}" # murmur3_32, murmur3_128 or sha256
  memory:
    queue-capacity: "${QUEUE_MEMORY_QUEUE_CAPACITY:100000}"
    max-pool-size: "${QUEUE_MEMORY_MAX_POOL_SIZE:999}"
    stats:
      print-interval-ms: "${QUEUE_MEMORY_STATS_PRINT_INTERVAL_MS:10000}"
  kafka:
    bootstrap-servers: "${KAFKA_SERVERS:kafka:9092}"
    ssl:
      enabled: "${KAFKA_SSL_ENABLED:false}"
      truststore-location: "${KAFKA_SSL_TRUSTSTORE_LOCATION:}"
      truststore-password: "${KAFKA_SSL_TRUSTSTORE_PASSWORD:}"
      keystore-location: "${KAFKA_SSL_KEYSTORE_LOCATION:}"
      keystore-password: "${KAFKA_SSL_KEYSTORE_PASSWORD:}"
      key-password: "${KAFKA_SSL_KEY_PASSWORD:}"
    acks: "${KAFKA_ACKS:1}"
    retries: "${KAFKA_RETRIES:1}"
    compression-type: "${KAFKA_COMPRESSION_TYPE:none}" # none, gzip, snappy, lz4, zstd
    batch-size: "${KAFKA_BATCH_SIZE:16384}"
    linger-ms: "${KAFKA_LINGER_MS:1}"
    max-request-size: "${KAFKA_MAX_REQUEST_SIZE:1048576}"
    max-in-flight-requests-per-connection: "${KAFKA_MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION:5}"
    buffer-memory: "${BUFFER_MEMORY:33554432}"
    replication-factor: "${QUEUE_KAFKA_REPLICATION_FACTOR:1}"
    max-poll-interval-ms: "${QUEUE_KAFKA_MAX_POLL_INTERVAL_MS:300000}"
    max-poll-records: "${QUEUE_KAFKA_MAX_POLL_RECORDS:8192}"
    max-partition-fetch-bytes: "${QUEUE_KAFKA_MAX_PARTITION_FETCH_BYTES:16777216}"
    fetch-max-bytes: "${QUEUE_KAFKA_FETCH_MAX_BYTES:134217728}"
    request-timeout-ms: "${QUEUE_KAFKA_REQUEST_TIMEOUT_MS:30000}"
    session-timeout-ms: "${QUEUE_KAFKA_SESSION_TIMEOUT_MS:10000}"
    auto-offset-reset: "${QUEUE_KAFKA_AUTO_OFFSET_RESET:earliest}"
    other-inline: "${QUEUE_KAFKA_OTHER_PROPERTIES:}"
    topic-properties:
      app: "${QUEUE_KAFKA_APP_TOPIC_PROPERTIES:retention.ms:86400000;segment.bytes:52428800;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}"
    consumer-stats:
      enabled: "${QUEUE_KAFKA_CONSUMER_STATS_ENABLED:true}"
      print-interval-ms: "${QUEUE_KAFKA_CONSUMER_STATS_MIN_PRINT_INTERVAL_MS:60000}"
      kafka-response-timeout-ms: "${QUEUE_KAFKA_CONSUMER_STATS_RESPONSE_TIMEOUT_MS:1000}"
  app:
    topic: "${QUEUE_APP_TOPIC:protocol_uplink}"
    poll-interval: "${QUEUE_APP_POLL_INTERVAL_MS:5}"
    pack-processing-timeout: "${QUEUE_APP_PACK_PROCESSING_TIMEOUT_MS:2000}"
    consumer-per-partition: "${QUEUE_APP_CONSUMER_PER_PARTITION:true}"
    partitions: "${QUEUE_APP_PARTITIONS:10}"
    # 可选 protobuf（推荐）、json，需要跟..forwarder.kafka.encoder保持一致
    decoder: "${QUEUE_APP_DECODER:protobuf}"
    stats:
      enabled: "${QUEUE_APP_STATS_ENABLED:true}"
      print-interval-ms: "${QUEUE_APP_STATS_PRINT_INTERVAL_MS:60000}"
      timer-top-n: "${QUEUE_APP_STATS_TIMER_TOP_N:5}"
#  rpc:
#    topic: "${QUEUE_RPC_TOPIC:app_rpc}"
#    poll-interval: "${QUEUE_RPC_POLL_INTERVAL_MS:5}"
#    pack-processing-timeout: "${QUEUE_RPC_PACK_PROCESSING_TIMEOUT_MS:2000}"
#    consumer-per-partition: "${QUEUE_RPC_CONSUMER_PER_PARTITION:true}"
#    partitions: "${QUEUE_RPC_PARTITIONS:10}"
#    decoder: "${QUEUE_RPC_DECODER:protobuf}"

# 应用程序缓存配置
cache:
  type: "${CACHE_TYPE:caffeine}" # caffeine or redis
  maximumPoolSize: "${CACHE_MAXIMUM_POOL_SIZE:16}"
  specs:
    piles:
      timeToLiveInMinutes: "${CACHE_SPECS_PILES_TTL:1440}"
      maxSize: "${CACHE_SPECS_PILES_MAX_SIZE:100000}"
    guns:
      timeToLiveInMinutes: "${CACHE_SPECS_GUNS_TTL:1440}"
      maxSize: "${CACHE_SPECS_GUNS_MAX_SIZE:1000000}"
    pileSessions:
      timeToLiveInMinutes: "${service.protocol.sessions.default-inactivity-timeout-in-sec}"
      maxSize: "${CACHE_SPECS_PILE_SESSIONS_MAX_SIZE:100000}"
    attributes:
      timeToLiveInMinutes: "${CACHE_SPECS_ATTRIBUTES_TTL:1440}"
      maxSize: "${CACHE_SPECS_ATTRIBUTES_MAX_SIZE:100000}"

redis:
  connection:
    type: "${REDIS_CONNECTION_TYPE:standalone}"
  standalone:
    host: "${REDIS_HOST:redis}"
    port: "${REDIS_PORT:6379}"
    useDefaultClientConfig: "${REDIS_USE_DEFAULT_CLIENT_CONFIG:false}"
    clientName: "${REDIS_CLIENT_NAME:standalone}"
    commandTimeout: "${REDIS_CLIENT_COMMAND_TIMEOUT:30000}"
    shutdownTimeout: "${REDIS_CLIENT_SHUTDOWN_TIMEOUT:1000}"
    usePoolConfig: "${REDIS_CLIENT_USE_POOL_CONFIG:true}"
  cluster:
    nodes: "${REDIS_NODES:redis-node-0:6379,redis-node-1:6379,redis-node-2:6379,redis-node-3:6379,redis-node-4:6379,redis-node-5:6379}"
    max-redirects: "${REDIS_MAX_REDIRECTS:12}"
    useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:false}"
  sentinel:
    master: "${REDIS_MASTER:mymaster}"
    sentinels: "${REDIS_SENTINELS:redis-sentinel:26379}"
    password: "${REDIS_SENTINEL_PASSWORD:sanbing}"
    useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:false}"
  db: "${REDIS_DB:0}"
  password: "${REDIS_PASSWORD:sanbing}"
  pool_config:
    maxTotal: "${REDIS_POOL_CONFIG_MAX_TOTAL:256}"
    maxIdle: "${REDIS_POOL_CONFIG_MAX_IDLE:128}"
    minIdle: "${REDIS_POOL_CONFIG_MIN_IDLE:64}"
    testOnBorrow: "${REDIS_POOL_CONFIG_TEST_ON_BORROW:false}"
    testOnReturn: "${REDIS_POOL_CONFIG_TEST_ON_RETURN:false}"
    testWhileIdle: "${REDIS_POOL_CONFIG_TEST_WHILE_IDLE:true}"
    minEvictableMs: "${REDIS_POOL_CONFIG_MIN_EVICTABLE_MS:60000}"
    evictionRunsMs: "${REDIS_POOL_CONFIG_EVICTION_RUNS_MS:30000}"
    maxWaitMills: "${REDIS_POOL_CONFIG_MAX_WAIT_MS:60000}"
    numberTestsPerEvictionRun: "${REDIS_POOL_CONFIG_NUMBER_TESTS_PER_EVICTION_RUN:3}"
    blockWhenExhausted: "${REDIS_POOL_CONFIG_BLOCK_WHEN_EXHAUSTED:true}"
  evictTtlInMs: "${REDIS_EVICT_TTL_MS:60000}"

# 数据库安装配置
install:
  # 安装模式：init-初始化数据库，upgrade-升级，disabled-不做任何操作
  mode: "${INSTALL_MODE:disabled}"

# SQL相关配置
sql:
  attributes:
    # 批处理大小
    batch_size: "${SQL_ATTRIBUTES_BATCH_SIZE:1000}"
    # 批处理最大延迟（毫秒）
    batch_max_delay: "${SQL_ATTRIBUTES_BATCH_MAX_DELAY:100}"
    # 统计打印间隔（毫秒）
    stats_print_interval_ms: "${SQL_ATTRIBUTES_STATS_PRINT_INTERVAL_MS:1000}"
    # 批处理线程数
    batch_threads: "${SQL_ATTRIBUTES_BATCH_THREADS:4}"
    # 值是否进行XSS验证
    value_no_xss_validation: "${SQL_ATTRIBUTES_VALUE_NO_XSS_VALIDATION:false}"
  # 批处理排序
  batch_sort: "${SQL_BATCH_SORT:true}"
  # 是否移除空字符
  remove_null_chars: "${SQL_REMOVE_NULL_CHARS:true}"

service:
  # 服务类型：纯协议解析前置 - protocol，纯应用后端 - app，单体服务(包含protocol和app) - monolith
  type: "${SERVICE_TYPE:monolith}"
  # 可自定义的服务ID，如果不指定，则默认为HOSTNAME
  id: "${SERVICE_ID:}"
  thread-pool:
    sharding:
      hash_function_name: "${SERVICE_THREAD_POOL_SHARDING_HASH_FUNCTION_NAME:murmur3_128}" # murmur3_32, murmur3_128 or sha256
      parallelism: "${SERVICE_THREAD_POOL_SHARDING_PARALLELISM:8}"
      stats-print-interval-ms: "${SERVICE_THREAD_POOL_SHARDING_STATS_PRINT_INTERVAL_MS:10000}"
  downlink:
    rpc:
      type: "${SERVICE_DOWNLINK_RPC_TYPE:grpc}" # rest or grpc
  protocol:
    sessions:
      default-inactivity-timeout-in-sec: "${SERVICE_PROTOCOLS_SESSIONS_DEFAULT_INACTIVITY_TIMEOUT_IN_SEC:600}"
      default-state-check-interval-in-sec: "${SERVICE_PROTOCOLS_SESSIONS_DEFAULT_STATE_CHECK_INTERVAL_IN_SEC:60}"
    grpc:
      port: "${SERVICE_PROTOCOL_GRPC_PORT:9090}"
      boss: "${SERVICE_PROTOCOL_GRPC_BOSS:4}"
      worker: "${SERVICE_PROTOCOL_GRPC_WORKER:64}"
      so-rcvbuf: "${SERVICE_PROTOCOL_GRPC_SO_RCVBUF:65535}"
      so-sndbuf: "${SERVICE_PROTOCOL_GRPC_SO_SNDBUF:65535}"
      no-delay: "${SERVICE_PROTOCOL_GRPC_NO_DELAY:true}"
      max-inbound-message-size: "${SERVICE_PROTOCOL_GRPC_MAX_INBOUND_MESSAGE_SIZE:33554432}"
      max-concurrent-calls-per-connection: "${SERVICE_PROTOCOL_GRPC_MAX_CONCURRENT_CALLS_PER_CONNECTION:4}"
      client-max-keep-alive-time-sec: "${SERVICE_PROTOCOL_GRPC_CLIENT_MAX_KEEP_ALIVE_TIME_SEC:30}"
  protocols:
    yunkuaichongV150:
      enabled: "${PROTOCOLS_YUNKUAICHONGV150_ENABLED:true}"
      listener:
        tcp:
          bind-address: "${PROTOCOLS_YUNKUAICHONGV150_LISTENER_TCP_BIND_ADDRESS:0.0.0.0}"
          bind-port: "${PROTOCOLS_YUNKUAICHONGV150_LISTENER_TCP_BIND_PORT:38001}"
          boss-group-thread_count: "${PROTOCOLS_YUNKUAICHONGV150_LISTENER_TCP_BOSS_GROUP_THREADS:4}"
          worker-group-thread-count: "${PROTOCOLS_YUNKUAICHONGV150_LISTENER_TCP_WORKER_GROUP_THREADS:16}"
          so-keep-alive: "${PROTOCOLS_YUNKUAICHONGV150_LISTENER_TCP_SO_KEEPALIVE:true}"
          so-backlog: "${PROTOCOLS_YUNKUAICHONGV150_LISTENER_TCP_SO_BACKLOG:128}"
          so-rcvbuf: "${PROTOCOLS_YUNKUAICHONGV150_LISTENER_TCP_SO_RCVBUF:65536}"
          so-sndbuf: "${PROTOCOLS_YUNKUAICHONGV150_LISTENER_TCP_SO_SNDBUF:65536}"
          nodelay: "${PROTOCOLS_YUNKUAICHONGV150_LISTENER_TCP_NODELAY:true}"
          handler:
            idle-timeout-seconds: "${PROTOCOLS_YUNKUAICHONGV150_LISTENER_TCP_HANDLER_IDLE_TIMEOUT_SECONDS:600}"
            max_connections: "${PROTOCOLS_YUNKUAICHONGV150_LISTENER_TCP_HANDLER_MAX_CONNECTIONS:100000}"
            # 默认为二进制类型的拆包器
            # 可选JSON类型的拆包器  "${PROTOCOLS_YUNKUAICHONGV150_NETTY_HANDLER_BINARY_CONFIGURATION:type:JSON}"
            # 可选纯文本类型的拆包器 "${PROTOCOLS_YUNKUAICHONGV150_NETTY_HANDLER_BINARY_CONFIGURATION:type:TEXT;maxFrameLength:128;stripDelimiter:true;messageSeparator:null;charsetName:UTF-8}"
            configuration: "${PROTOCOLS_YUNKUAICHONGV150_NETTY_HANDLER_BINARY_CONFIGURATION:type:BINARY;decoder:sanbing.jcpp.protocol.listener.tcp.decoder.JCPPLengthFieldBasedFrameDecoder;byteOrder:LITTLE_ENDIAN;head:68;lengthFieldOffset:1;lengthFieldLength:1;lengthAdjustment:2;initialBytesToStrip:0}"
      forwarder:
        # 如果是单体服务，可选kafka、memory，未来计划扩展RocketMQ, GRpc、REST
        type: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_TYPE:memory}"
        memory:
          topic: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_MEMORY_TOPIC:protocol_uplink}"
        kafka:
          topic: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_KAFKA_TOPIC:protocol_uplink}"
          jcpp-partition: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_KAFKA_JCPP_PARTITION:true}" # 是否利用JCPP的分片框架
          # 以下配置只有在service.type为protocol时且jcpp-partition为false时才生效
          bootstrap-servers: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_KAFKA_SERVERS:kafka:9092}"
          acks: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_KAFKA_ACKS:1}"
          # 可选 protobuf（推荐）、json
          encoder: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_KAFKA_ENCODER:protobuf}"
          retries: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_KAFKA_RETRIES:1}"
          compression-type: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_KAFKA_COMPRESSION_TYPE:none}" # none, gzip, snappy, lz4, zstd
          batch-size: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_KAFKA_BATCH_SIZE:16384}"
          linger-ms: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_KAFKA_LINGER_MS:0}"
          buffer-memory: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_BUFFER_MEMORY:33554432}"
          other-properties: "${PROTOCOLS_YUNKUAICHONGV150_FORWARD_QUEUE_KAFKA_OTHER_PROPERTIES:}"
    yunkuaichongV160:
      enabled: "${PROTOCOLS_YUNKUAICHONGV160_ENABLED:true}"
      listener:
        tcp:
          bind-address: "${PROTOCOLS_YUNKUAICHONGV160_LISTENER_TCP_BIND_ADDRESS:0.0.0.0}"
          bind-port: "${PROTOCOLS_YUNKUAICHONGV160_LISTENER_TCP_BIND_PORT:38002}"
          boss-group-thread_count: "${PROTOCOLS_YUNKUAICHONGV160_LISTENER_TCP_BOSS_GROUP_THREADS:4}"
          worker-group-thread-count: "${PROTOCOLS_YUNKUAICHONGV160_LISTENER_TCP_WORKER_GROUP_THREADS:16}"
          so-keep-alive: "${PROTOCOLS_YUNKUAICHONGV160_LISTENER_TCP_SO_KEEPALIVE:true}"
          so-backlog: "${PROTOCOLS_YUNKUAICHONGV160_LISTENER_TCP_SO_BACKLOG:128}"
          so-rcvbuf: "${PROTOCOLS_YUNKUAICHONGV160_LISTENER_TCP_SO_RCVBUF:65536}"
          so-sndbuf: "${PROTOCOLS_YUNKUAICHONGV160_LISTENER_TCP_SO_SNDBUF:65536}"
          nodelay: "${PROTOCOLS_YUNKUAICHONGV160_LISTENER_TCP_NODELAY:true}"
          handler:
            idle-timeout-seconds: "${PROTOCOLS_YUNKUAICHONGV160_LISTENER_TCP_HANDLER_IDLE_TIMEOUT_SECONDS:600}"
            max_connections: "${PROTOCOLS_YUNKUAICHONGV160_LISTENER_TCP_HANDLER_MAX_CONNECTIONS:100000}"
            # 默认为二进制类型的拆包器
            # 可选JSON类型的拆包器  "${PROTOCOLS_YUNKUAICHONGV160_NETTY_HANDLER_BINARY_CONFIGURATION:type:JSON}"
            # 可选纯文本类型的拆包器 "${PROTOCOLS_YUNKUAICHONGV160_NETTY_HANDLER_BINARY_CONFIGURATION:type:TEXT;maxFrameLength:128;stripDelimiter:true;messageSeparator:null;charsetName:UTF-8}"
            configuration: "${PROTOCOLS_YUNKUAICHONGV160_NETTY_HANDLER_BINARY_CONFIGURATION:type:BINARY;decoder:sanbing.jcpp.protocol.listener.tcp.decoder.JCPPLengthFieldBasedFrameDecoder;byteOrder:LITTLE_ENDIAN;head:68;lengthFieldOffset:1;lengthFieldLength:1;lengthAdjustment:2;initialBytesToStrip:0}"
      forwarder:
        # 如果是单体服务，可选kafka、memory，未来计划扩展RocketMQ, GRpc、REST
        type: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_TYPE:memory}"
        memory:
          topic: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_MEMORY_TOPIC:protocol_uplink}"
        kafka:
          topic: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_KAFKA_TOPIC:protocol_uplink}"
          jcpp-partition: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_KAFKA_JCPP_PARTITION:true}" # 是否利用JCPP的分片框架
          # 以下配置只有在service.type为protocol时且jcpp-partition为false时才生效
          bootstrap-servers: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_KAFKA_SERVERS:kafka:9092}"
          acks: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_KAFKA_ACKS:1}"
          # 可选 protobuf（推荐）、json
          encoder: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_KAFKA_ENCODER:protobuf}"
          retries: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_KAFKA_RETRIES:1}"
          compression-type: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_KAFKA_COMPRESSION_TYPE:none}" # none, gzip, snappy, lz4, zstd
          batch-size: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_KAFKA_BATCH_SIZE:16384}"
          linger-ms: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_KAFKA_LINGER_MS:0}"
          buffer-memory: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_BUFFER_MEMORY:33554432}"
          other-properties: "${PROTOCOLS_YUNKUAICHONGV160_FORWARD_QUEUE_KAFKA_OTHER_PROPERTIES:}"
    yunkuaichongV170:
      enabled: "${PROTOCOLS_YUNKUAICHONGV170_ENABLED:true}"
      listener:
        tcp:
          bind-address: "${PROTOCOLS_YUNKUAICHONGV170_LISTENER_TCP_BIND_ADDRESS:0.0.0.0}"
          bind-port: "${PROTOCOLS_YUNKUAICHONGV170_LISTENER_TCP_BIND_PORT:38003}"
          boss-group-thread_count: "${PROTOCOLS_YUNKUAICHONGV170_LISTENER_TCP_BOSS_GROUP_THREADS:4}"
          worker-group-thread-count: "${PROTOCOLS_YUNKUAICHONGV170_LISTENER_TCP_WORKER_GROUP_THREADS:16}"
          so-keep-alive: "${PROTOCOLS_YUNKUAICHONGV170_LISTENER_TCP_SO_KEEPALIVE:true}"
          so-backlog: "${PROTOCOLS_YUNKUAICHONGV170_LISTENER_TCP_SO_BACKLOG:128}"
          so-rcvbuf: "${PROTOCOLS_YUNKUAICHONGV170_LISTENER_TCP_SO_RCVBUF:65536}"
          so-sndbuf: "${PROTOCOLS_YUNKUAICHONGV170_LISTENER_TCP_SO_SNDBUF:65536}"
          nodelay: "${PROTOCOLS_YUNKUAICHONGV170_LISTENER_TCP_NODELAY:true}"
          handler:
            idle-timeout-seconds: "${PROTOCOLS_YUNKUAICHONGV170_LISTENER_TCP_HANDLER_IDLE_TIMEOUT_SECONDS:600}"
            max_connections: "${PROTOCOLS_YUNKUAICHONGV170_LISTENER_TCP_HANDLER_MAX_CONNECTIONS:100000}"
            # 默认为二进制类型的拆包器
            # 可选JSON类型的拆包器  "${PROTOCOLS_YUNKUAICHONGV170_NETTY_HANDLER_BINARY_CONFIGURATION:type:JSON}"
            # 可选纯文本类型的拆包器 "${PROTOCOLS_YUNKUAICHONGV170_NETTY_HANDLER_BINARY_CONFIGURATION:type:TEXT;maxFrameLength:128;stripDelimiter:true;messageSeparator:null;charsetName:UTF-8}"
            configuration: "${PROTOCOLS_YUNKUAICHONGV170_NETTY_HANDLER_BINARY_CONFIGURATION:type:BINARY;decoder:sanbing.jcpp.protocol.listener.tcp.decoder.JCPPLengthFieldBasedFrameDecoder;byteOrder:LITTLE_ENDIAN;head:68;lengthFieldOffset:1;lengthFieldLength:1;lengthAdjustment:2;initialBytesToStrip:0}"
      forwarder:
        # 如果是单体服务，可选kafka、memory，未来计划扩展RocketMQ, GRpc、REST
        type: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_TYPE:memory}"
        memory:
          topic: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_MEMORY_TOPIC:protocol_uplink}"
        kafka:
          topic: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_KAFKA_TOPIC:protocol_uplink}"
          jcpp-partition: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_KAFKA_JCPP_PARTITION:true}" # 是否利用JCPP的分片框架
          # 以下配置只有在service.type为protocol时且jcpp-partition为false时才生效
          bootstrap-servers: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_KAFKA_SERVERS:kafka:9092}"
          acks: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_KAFKA_ACKS:1}"
          # 可选 protobuf（推荐）、json
          encoder: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_KAFKA_ENCODER:protobuf}"
          retries: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_KAFKA_RETRIES:1}"
          compression-type: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_KAFKA_COMPRESSION_TYPE:none}" # none, gzip, snappy, lz4, zstd
          batch-size: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_KAFKA_BATCH_SIZE:16384}"
          linger-ms: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_KAFKA_LINGER_MS:0}"
          buffer-memory: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_BUFFER_MEMORY:33554432}"
          other-properties: "${PROTOCOLS_YUNKUAICHONGV170_FORWARD_QUEUE_KAFKA_OTHER_PROPERTIES:}"
    lvnengV340:
      enabled: "${PROTOCOLS_LVNENG340_ENABLED:true}"
      listener:
        tcp:
          bind-address: "${PROTOCOLS_LVNENG340_LISTENER_TCP_BIND_ADDRESS:0.0.0.0}"
          bind-port: "${PROTOCOLS_LVNENG340_LISTENER_TCP_BIND_PORT:38011}"
          boss-group-thread_count: "${PROTOCOLS_LVNENG340_LISTENER_TCP_BOSS_GROUP_THREADS:4}"
          worker-group-thread-count: "${PROTOCOLS_LVNENG340_LISTENER_TCP_WORKER_GROUP_THREADS:16}"
          so-keep-alive: "${PROTOCOLS_LVNENG340_LISTENER_TCP_SO_KEEPALIVE:true}"
          so-backlog: "${PROTOCOLS_LVNENG340_LISTENER_TCP_SO_BACKLOG:128}"
          so-rcvbuf: "${PROTOCOLS_LVNENG340_LISTENER_TCP_SO_RCVBUF:65536}"
          so-sndbuf: "${PROTOCOLS_LVNENG340_LISTENER_TCP_SO_SNDBUF:65536}"
          nodelay: "${PROTOCOLS_LVNENG340_LISTENER_TCP_NODELAY:true}"
          handler:
            idle-timeout-seconds: "${PROTOCOLS_LVNENG340_LISTENER_TCP_HANDLER_IDLE_TIMEOUT_SECONDS:600}"
            max_connections: "${PROTOCOLS_LVNENG340_LISTENER_TCP_HANDLER_MAX_CONNECTIONS:100000}"
            # 默认为二进制类型的拆包器
            # 可选JSON类型的拆包器  "${PROTOCOLS_LVNENG340_NETTY_HANDLER_BINARY_CONFIGURATION:type:JSON}"
            # 可选纯文本类型的拆包器 "${PROTOCOLS_LVNENG340_NETTY_HANDLER_BINARY_CONFIGURATION:type:TEXT;maxFrameLength:128;stripDelimiter:true;messageSeparator:null;charsetName:UTF-8}"
            configuration: "${PROTOCOLS_LVNENG340_NETTY_HANDLER_BINARY_CONFIGURATION:type:BINARY;decoder:sanbing.jcpp.protocol.listener.tcp.decoder.JCPPLengthFieldBasedFrameDecoder;byteOrder:LITTLE_ENDIAN;head:AAF5;lengthFieldOffset:2;lengthFieldLength:2;lengthAdjustment:-4;initialBytesToStrip:0}"
      forwarder:
        # 如果是单体服务，可选kafka、memory，未来计划扩展RocketMQ, GRpc、REST
        type: "${PROTOCOLS_LVNENG340_FORWARD_TYPE:memory}"
        memory:
          topic: "${PROTOCOLS_LVNENG340_FORWARD_MEMORY_TOPIC:protocol_uplink}"
        kafka:
          topic: "${PROTOCOLS_LVNENG340_FORWARD_KAFKA_TOPIC:protocol_uplink}"
          jcpp-partition: "${PROTOCOLS_LVNENG340_FORWARD_KAFKA_JCPP_PARTITION:true}" # 是否利用JCPP的分片框架
          # 以下配置只有在service.type为protocol时且jcpp-partition为false时才生效
          bootstrap-servers: "${PROTOCOLS_LVNENG340_FORWARD_KAFKA_SERVERS:kafka:9092}"
          acks: "${PROTOCOLS_LVNENG340_FORWARD_KAFKA_ACKS:1}"
          # 可选 protobuf（推荐）、json
          encoder: "${PROTOCOLS_LVNENG340_FORWARD_KAFKA_ENCODER:protobuf}"
          retries: "${PROTOCOLS_LVNENG340_FORWARD_KAFKA_RETRIES:1}"
          compression-type: "${PROTOCOLS_LVNENG340_FORWARD_KAFKA_COMPRESSION_TYPE:none}" # none, gzip, snappy, lz4, zstd
          batch-size: "${PROTOCOLS_LVNENG340_FORWARD_KAFKA_BATCH_SIZE:16384}"
          linger-ms: "${PROTOCOLS_LVNENG340_FORWARD_KAFKA_LINGER_MS:0}"
          buffer-memory: "${PROTOCOLS_LVNENG340_FORWARD_BUFFER_MEMORY:33554432}"
          other-properties: "${PROTOCOLS_LVNENG340_FORWARD_QUEUE_KAFKA_OTHER_PROPERTIES:}"
