Configuração
Quando usar: sempre que um número, um texto ou um liga/desliga do serviço precisa mudar sem release nova — ou, no mínimo, sem ficar escondido no código.
Configuração não é segredo: ela é declarada, tipada, versionada no descritor e aparece nos comandos de inspeção do módulo. O que não pode ser lido por quem opera (token, chave, senha) é slot de segredo (veja Segredo).
Declarar
nns/service.yaml:
config:
- {key: scan_seconds, type: integer, default: 3}
- {key: notify_enabled, type: boolean, default: true}
keyé minúscula com underscore (^[a-z][a-z0-9_]{0,62}$), no máximo 64 chaves.typeéstring,integerouboolean— e é conferido de verdade:"abc"numa chaveintegerderruba a partida, não vira zero.defaulté opcional. Chave declarada sem valor e sem default fica ausente e o acessor devolve o zero do tipo.
De onde vem o valor, nesta ordem: NN_CONFIG_<CHAVE> no ambiente → o arquivo NN_CONFIG_FILE
(YAML/JSON, um mapa) → o default do descritor. O nome da variável é a chave em MAIÚSCULAS:
scan_seconds → NN_CONFIG_SCAN_SECONDS.
Chave que não está declarada — no ambiente (NN_CONFIG_*) ou no arquivo — é recusada na partida:
config não declarada em service.yaml: <chave>. Nada é ignorado em silêncio.
Ler
O serviço recebe o Settings pronto (bean do SDK) e lê por tipo:
public SampleService(
Db db,
NnsConfig config,
NnsModule module,
Settings settings,
ActionStore actions,
TxAuditEmitter emitter,
AuditConfig auditConfig,
RoleWatcher role,
Notifier notifier) {
// ...
// Configuração DECLARADA no service.yaml: o número não está no código.
this.scanDelay = Duration.ofSeconds(settings.integer("scan_seconds"));
this.clock = InstantSource.system();
}
Os quatro acessores:
settings.integer("scan_seconds") // long; 0 se ausente ou de outro tipo
settings.string("engine_name") // "" se ausente
settings.bool("notify_enabled") // false se ausente
settings.has("scan_seconds") // a chave tem valor (do ambiente, do arquivo ou do default)?
O validador do descritor confere o cruzamento (chave declarada no service.yaml e usada no código
você confere com um teste — veja abaixo).
Como o valor chega ao pod
No Kubernetes o valor entra pelo chart, como ambiente:
env:
- name: NN_CONFIG_SCAN_SECONDS
value: "{{ .Values.scanSeconds }}"
Em desenvolvimento, export NN_CONFIG_SCAN_SECONDS=1 no shell e pronto. Para muitas chaves, o
NN_CONFIG_FILE aceita um mapa YAML — o mesmo arquivo que o deployment target renderiza.
Como testar
O teste do descritor confere o default declarado:
@Test
void serviceDeclaresTheOutboundDependencyTheSecretAndTheConfiguration() {
var service = MODULE.service();
assertThat(service.config())
.anySatisfy(
c -> {
assertThat(c.key()).isEqualTo("scan_seconds");
assertThat(((Number) c.defaultValue()).intValue()).isEqualTo(3);
});
}
E o efeito da configuração aparece no teste de comportamento quando o valor muda:
// No teste do handler: sem espera, o teste não dorme — a configuração é o que manda.
env.put("NN_CONFIG_SCAN_SECONDS", "0");
NnsConfig config = NnsConfig.fromEnviron(env);
Erros comuns
- Número mágico no código (
Duration.ofSeconds(3)) — ninguém consegue ajustar sem release, e o valor real de produção passa a ser desconhecido. - Usar configuração para segredo — a config é lida por quem opera, aparece em inspeção e é versionada. Segredo é slot.
- Chave no ambiente e não no descritor — a partida falha com
config não declarada em service.yaml: é de propósito, para não existir configuração fantasma que ninguém declara. - Depender do default para um valor que importa — default é conveniência de desenvolvimento; o ambiente de produção deve dizer o valor.
- Trocar o tipo depois de publicado —
integerque virastringquebra o pod que ainda tem a variável antiga; trate como mudança de contrato. - Ler
System.getenv()no handler — a leitura é peloSettings/NnsConfig; assim o teste controla o valor e a chave declarada é a única fonte. - Achar que a config recarrega sozinha — ela é lida na partida. Mudar valor é mudar o pod.
Esta página ajudou?
Reportar um problema nesta páginaNão envie senhas, chaves, tokens ou dados de clientes.