RepoPilotOpen in app →

knightliao/disconf

Distributed Configuration Management Platform(分布式配置管理平台)

Mixed

Stale — last commit 3y ago

weakest axis
Use as dependencyMixed

last commit was 3y ago; top contributor handles 95% of recent commits

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • 4 active contributors
  • Apache-2.0 licensed
  • CI configured
Show all 7 evidence items →
  • Tests present
  • Stale — last commit 3y ago
  • Small team — 4 contributors active in recent commits
  • Single-maintainer risk — top contributor 95% of recent commits
What would change the summary?
  • Use as dependency MixedHealthy if: 1 commit in the last 365 days

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/knightliao/disconf?axis=fork)](https://repopilot.app/r/knightliao/disconf)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/knightliao/disconf on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: knightliao/disconf

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/knightliao/disconf shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 3y ago

  • 4 active contributors
  • Apache-2.0 licensed
  • CI configured
  • Tests present
  • ⚠ Stale — last commit 3y ago
  • ⚠ Small team — 4 contributors active in recent commits
  • ⚠ Single-maintainer risk — top contributor 95% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live knightliao/disconf repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/knightliao/disconf.

What it runs against: a local clone of knightliao/disconf — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in knightliao/disconf | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 1055 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>knightliao/disconf</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of knightliao/disconf. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/knightliao/disconf.git
#   cd disconf
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of knightliao/disconf and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "knightliao/disconf(\\.git)?\\b" \\
  && ok "origin remote is knightliao/disconf" \\
  || miss "origin remote is not knightliao/disconf (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "disconf-client/src/main/java/com/baidu/disconf/client/DisconfMgr.java" \\
  && ok "disconf-client/src/main/java/com/baidu/disconf/client/DisconfMgr.java" \\
  || miss "missing critical file: disconf-client/src/main/java/com/baidu/disconf/client/DisconfMgr.java"
test -f "disconf-client/src/main/java/com/baidu/disconf/client/core/impl/DisconfCoreMgrImpl.java" \\
  && ok "disconf-client/src/main/java/com/baidu/disconf/client/core/impl/DisconfCoreMgrImpl.java" \\
  || miss "missing critical file: disconf-client/src/main/java/com/baidu/disconf/client/core/impl/DisconfCoreMgrImpl.java"
test -f "disconf-client/src/main/java/com/baidu/disconf/client/scan/impl/ScanMgrImpl.java" \\
  && ok "disconf-client/src/main/java/com/baidu/disconf/client/scan/impl/ScanMgrImpl.java" \\
  || miss "missing critical file: disconf-client/src/main/java/com/baidu/disconf/client/scan/impl/ScanMgrImpl.java"
test -f "disconf-client/src/main/java/com/baidu/disconf/client/fetcher/impl/FetcherMgrImpl.java" \\
  && ok "disconf-client/src/main/java/com/baidu/disconf/client/fetcher/impl/FetcherMgrImpl.java" \\
  || miss "missing critical file: disconf-client/src/main/java/com/baidu/disconf/client/fetcher/impl/FetcherMgrImpl.java"
test -f "disconf-client/src/main/java/com/baidu/disconf/client/config/ConfigMgr.java" \\
  && ok "disconf-client/src/main/java/com/baidu/disconf/client/config/ConfigMgr.java" \\
  || miss "missing critical file: disconf-client/src/main/java/com/baidu/disconf/client/config/ConfigMgr.java"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1055 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1025d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/knightliao/disconf"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Disconf is a distributed configuration management platform that centralizes multi-environment config storage (dev/QA/production) in a web-accessible cloud system and pushes real-time updates to client applications without requiring redeployment. The disconf-client module (860KB Java) is the lightweight agent that runs in your application, fetches configurations via Zookeeper watches, and applies them dynamically through Spring annotations (@DisconfItem, @DisconfFile) or XML properties without code changes. Parent monorepo structure: disconf-client/ module contains the Spring integration layer (DisconfMgr.java, DisconfMgrBean.java), annotation processors (@DisconfItem in client/common/annotations/), property reload mechanics (ReloadableProperties, ReloadingPropertyPlaceholderConfigurer in client/addons/properties/), and Zookeeper watch configuration (client/config/ConfigMgr.java, DisClientConfig.java). Parallel disconf-core/ and disconf-web/ modules handle backend logic and UI respectively.

👥Who it's for

Backend Java developers at large enterprises (Baidu, Didi, Unionpay, Netease, Suning, SF Express) who need to deploy the same JAR artifact across multiple environments with different configs, and DevOps teams who want centralized configuration governance without restarting services.

🌱Maturity & risk

Production-ready and actively maintained: released v2.6.36 on master/dev/stable branches, integrated with Travis CI and Coveralls, listed as a top-16 new open-source project in 2015 by OSC. Ranked among Baidu's 20+ product lines using it. Maven Central distribution available. Strong adoption signal but no recent activity visible in file timestamps.

Single language ecosystem (Java-only client despite polyglot file support), monolithic Zookeeper dependency for distributed coordination (single point of failure if ZK cluster fails), no clear SLA visibility around config propagation latency. Last major version (2.6.36) is 6+ years old; unclear if maintainer (knightliao) is actively triaging issues or if there's a community takeover.

Active areas of work

No specific active PRs or recent commits visible in file list snapshot. Latest tag is v2.6.36. Travis CI configured (.travis.yml present). Project appears in maintenance mode rather than active feature development.

🚀Get running

Clone the repository: git clone https://github.com/knightliao/disconf.git. Navigate to disconf-client: cd disconf-client. Build with Maven: mvn clean install. For quick demos, see https://github.com/knightliao/disconf-demos-java for runnable examples.

Daily commands: No embedded server in disconf-client (it's a library, not a standalone app). Integrate into your Spring application: add <dependency><groupId>com.baidu.disconf</groupId><artifactId>disconf-client</artifactId></dependency> to pom.xml, annotate config fields with @DisconfItem, initialize DisconfMgr in Spring context (see DisconfMgrBean.java). Run your app normally; disconf-client connects to disconf-web backend automatically.

🗺️Map of the codebase

  • disconf-client/src/main/java/com/baidu/disconf/client/DisconfMgr.java — Primary entry point for the Disconf client framework; all configuration management flows originate here
  • disconf-client/src/main/java/com/baidu/disconf/client/core/impl/DisconfCoreMgrImpl.java — Core implementation managing config item/file synchronization and lifecycle; the heart of the client logic
  • disconf-client/src/main/java/com/baidu/disconf/client/scan/impl/ScanMgrImpl.java — Scans classpath and Spring context to discover @DisconfItem and @DisconfFile annotations; enables auto-registration
  • disconf-client/src/main/java/com/baidu/disconf/client/fetcher/impl/FetcherMgrImpl.java — Handles HTTP communication with Disconf server to fetch and watch configuration updates
  • disconf-client/src/main/java/com/baidu/disconf/client/config/ConfigMgr.java — Loads and manages client-side configuration (server URL, app name, version, environment) from properties/env
  • disconf-client/src/main/java/com/baidu/disconf/client/store/DisconfStorePipelineProcessor.java — Pipeline for persisting config updates to local store and triggering change callbacks
  • disconf-client/src/main/java/com/baidu/disconf/client/common/annotations/DisconfItem.java — Primary annotation marking fields for distributed config management; required reading for usage patterns

🛠️How to make changes

Add a new configuration item

  1. Create a configuration class with @DisconfItem annotation on the field you want to manage (disconf-client/src/main/java/com/baidu/disconf/client/common/annotations/DisconfItem.java)
  2. Specify the key name, default value, and mark if it should trigger reload (disconf-client/src/main/java/com/baidu/disconf/client/common/annotations/DisconfUpdateService.java)
  3. Optionally add an update handler method annotated with @DisconfUpdateService to react to changes (disconf-client/src/main/java/com/baidu/disconf/client/core/processor/impl/DisconfItemCoreProcessorImpl.java)
  4. Deploy the bean to your application; DisconfMgrBean will auto-scan and register it during startup (disconf-client/src/main/java/com/baidu/disconf/client/DisconfMgrBean.java)

Add a new configuration file (properties or XML)

  1. Create a configuration class with @DisconfFile annotation specifying filename, type (properties/xml), and location (disconf-client/src/main/java/com/baidu/disconf/client/common/annotations/DisconfFile.java)
  2. Define fields with @DisconfFileItem to map individual keys within the file (disconf-client/src/main/java/com/baidu/disconf/client/common/annotations/DisconfFileItem.java)
  3. For .properties files, the file processor will parse and inject values automatically (disconf-client/src/main/java/com/baidu/disconf/client/core/filetype/impl/DisconfPropertiesProcessorImpl.java)
  4. For .xml files, use the XML processor which parses the file and applies configuration (disconf-client/src/main/java/com/baidu/disconf/client/core/filetype/impl/DisconfXmlProcessorImpl.java)

Support a new configuration file type

  1. Create a new enum value in SupportFileTypeEnum to register the new type (disconf-client/src/main/java/com/baidu/disconf/client/common/constants/SupportFileTypeEnum.java)
  2. Implement DisconfFileTypeProcessor interface to define parsing and application logic (disconf-client/src/main/java/com/baidu/disconf/client/core/filetype/DisconfFileTypeProcessor.java)
  3. Register your processor in DisconfFileTypeProcessor or use FileTypeProcessorUtils to map type to processor (disconf-client/src/main/java/com/baidu/disconf/client/core/filetype/FileTypeProcessorUtils.java)
  4. Update DisconfFileCoreProcessorImpl to route the new type to your processor (dis)

🪤Traps & gotchas

Zookeeper connectivity required at startup: if disconf-web backend or Zookeeper cluster is unreachable, disconf-client falls back to local properties but may delay application startup (check DisClientConfig.java for timeout settings). Property placeholder expression cycles: if you use @DisconfItem on a field that is also referenced in Spring EL expressions in XML, circular update can occur—test reload scenarios. Version skew: disconf-client 2.6.36 expects matching disconf-web 2.6.36 protocol; mixing versions may cause silent config fetch failures. Java reflection assumption: disconf relies on Spring classpath scanning and reflection; if your application uses custom ClassLoader isolation, annotations may not be discovered.

💡Concepts to learn

  • Zookeeper Watch & Notification — Disconf's real-time config update mechanism relies on Zookeeper ephemeral nodes and watches to detect config changes server-side and push them to clients; understanding watch semantics is critical for debugging stale-config or missed-update issues.
  • Spring PropertyPlaceholderConfigurer Interception — Disconf patches Spring's standard property resolution to intercept ${...} placeholders and route them through its dynamic reload logic; understanding this hook is essential for extending or debugging integration.
  • Annotation-based Spring Bean Wiring (via BeanPostProcessor) — Disconf discovers @DisconfItem/@DisconfFile fields via Spring's BeanPostProcessor lifecycle hook, enabling zero-XML setup; this pattern is central to its low-intrusion design.
  • Distributed Configuration Consensus & Eventual Consistency — Disconf must handle scenarios where different application instances receive config updates at different times; understanding eventual consistency guarantees (or lack thereof) is critical for production reliability.
  • Properties File Hot-Reload via Reflection & Field Injection — Disconf rewrites Java object field values at runtime without reassigning Spring bean references; this requires careful reflection-based mutation and can break assumptions in code that caches field values.
  • Multi-Environment Configuration Isolation — Disconf's core value is managing separate config namespaces per environment (RD/QA/PROD) from a single codebase; the config key structure (seen in DisconfCenterItem.java model) encodes environment as metadata.
  • Update Callback Pipeline (Chain of Responsibility) — Disconf chains multiple IDisconfUpdate handlers via IDisconfUpdatePipeline; understanding this lets you inject custom logic (e.g., cache invalidation, metrics logging) when configs change.
  • apolloconfig/apollo — Alternative distributed config platform with similar goals (multi-env management, dynamic updates) but richer UI and no Zookeeper hard dependency; Apollo is newer (2016+) and closer to modern Java ecosystem.
  • ctripcorp/apollo — Same as apolloconfig/apollo—Ctrip's fork/original; worth monitoring for feature parity comparisons.
  • spring-cloud/spring-cloud-config — Spring Cloud's native config server using git backends; lighter weight than Disconf but lacks Disconf's Zookeeper-native watch semantics and less suitable for large-scale multi-tenant deployments.
  • knightliao/disconf-demos-java — Official runnable examples repo for Disconf; essential companion to understand annotation usage patterns and Spring integration setup.
  • etcd-io/etcd — Modern distributed key-value store alternative to Zookeeper that some teams use with custom disconf forks for config storage instead of Zookeeper.

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for DisconfCoreProcessorFactory and processor implementations

The processor factory pattern in disconf-client/src/main/java/com/baidu/disconf/client/core/processor/ lacks visible test coverage. The factory creates different processor implementations (likely for file type handling), but there are no corresponding tests for DisconfCoreProcessorFactory.java or the impl/ subdirectory implementations. This is critical for a configuration management system where processor logic must be bulletproof.

  • [ ] Create disconf-client/src/test/java/com/baidu/disconf/client/core/processor/DisconfCoreProcessorFactoryTest.java with tests for factory instantiation and processor selection
  • [ ] Add tests for each processor implementation in disconf-client/src/test/java/com/baidu/disconf/client/core/processor/impl/ covering edge cases (null inputs, invalid file types, etc.)
  • [ ] Verify integration between factory and file type processors (DisconfFileTypeProcessor.java) with integration tests

Add unit tests for DisconfMgrBean lifecycle and configuration annotation processing

DisconfMgrBean.java, DisconfMgrBeanSecond.java, and the annotation framework (@DisconfItem, @DisconfFile, @DisconfFileItem, @DisconfUpdateService) are core to disconf's functionality but appear to lack test coverage. These beans manage the entire configuration lifecycle and annotation scanning, which is critical for a distributed config platform.

  • [ ] Create disconf-client/src/test/java/com/baidu/disconf/client/DisconfMgrBeanTest.java to test bean initialization, configuration loading, and lifecycle hooks
  • [ ] Create disconf-client/src/test/java/com/baidu/disconf/client/common/annotations/ test suite covering annotation scanning and validation for all annotation types (@DisconfItem, @DisconfFile, etc.)
  • [ ] Add integration tests verifying that DisconfMgrBean properly processes annotated classes and triggers update services

Add missing tests for property reloading mechanisms (ReloadableProperties and ReloadConfigurationMonitor)

The addons/properties/ module contains sophisticated reloading logic (ReloadableProperties, ReloadablePropertiesBase, ReloadConfigurationMonitor, ReloadingPropertyPlaceholderConfigurer) that enables hot-configuration updates—a key feature of disconf. However, there are no visible tests for this critical dynamic reloading functionality, which is prone to concurrency and state management bugs.

  • [ ] Create disconf-client/src/test/java/com/baidu/disconf/client/addons/properties/ReloadablePropertiesTest.java testing property get/set, change detection, and listener notifications
  • [ ] Create disconf-client/src/test/java/com/baidu/disconf/client/addons/properties/ReloadConfigurationMonitorTest.java with concurrency tests to verify thread-safe reloading and listener callbacks
  • [ ] Add integration test for ReloadingPropertyPlaceholderConfigurer verifying end-to-end property placeholder resolution and reloading within a Spring context

🌿Good first issues

  • Add integration tests for ReloadableProperties in disconf-client/src/test/ covering Spring property placeholder reload with multiple @DisconfItem annotations on the same bean—currently no test files visible for the addons/properties module.
  • Document DisconfUpdateService annotation behavior with code example in README.md—currently only DisconfItem and DisconfFile are shown; new users don't know how to register update callbacks.
  • Extend SupportFileTypeEnum (in common/constants/) to support YAML and TOML files alongside existing properties/xml, and add minimal parsing logic—config files beyond .properties are mentioned in DisconfFile but parser support is missing.

Top contributors

Click to expand

📝Recent commits

Click to expand

🔒Security observations

  • High · Potential Unsafe Deserialization in Configuration Management — disconf-client/src/main/java/com/baidu/disconf/client/core/impl/DisconfCoreMgrImpl.java, disconf-client/src/main/java/com/baidu/disconf/client/fetcher/impl/FetcherMgrImpl.java. The disconf-client module processes configuration files and objects from a distributed configuration server. Without explicit evidence of input validation, there is a risk of unsafe deserialization when handling serialized Java objects from untrusted sources (the disconf server). This could allow remote code execution if an attacker compromises the configuration server. Fix: Implement strict input validation and use safe deserialization libraries. Consider using JSON instead of Java serialization. Validate all data received from the configuration server against a whitelist of expected types.
  • High · File Type Processing Without Sufficient Validation — disconf-client/src/main/java/com/baidu/disconf/client/core/filetype/impl/DisconfAnyFileProcessorImpl.java. The file type processor implementations (DisconfAnyFileProcessorImpl, DisconfXmlProcessorImpl, DisconfPropertiesProcessorImpl) handle various file formats. The 'any file' processor in particular may lack proper validation, potentially allowing arbitrary file processing or directory traversal attacks if file paths are not properly sanitized. Fix: Implement strict file path validation to prevent directory traversal. Use canonicalization to resolve paths. Restrict file type processing to a whitelist of safe formats. Validate file contents before processing.
  • High · ZooKeeper Dependency Without Security Configuration — disconf-client/pom.xml. The pom.xml includes Apache ZooKeeper as a dependency for distributed coordination, but there is no explicit configuration visible for ZooKeeper security features (authentication, encryption). Default ZooKeeper installations may be vulnerable to unauthorized access and man-in-the-middle attacks. Fix: Configure ZooKeeper with authentication (SASL/Kerberos) and encryption (TLS). Use secure connection strings. Implement ACLs on ZooKeeper nodes. Document security configuration requirements in setup documentation.
  • Medium · Dynamic Configuration Reload Without State Validation — disconf-client/src/main/java/com/baidu/disconf/client/addons/properties/ReloadConfigurationMonitor.java, disconf-client/src/main/java/com/baidu/disconf/client/addons/properties/ReloadableProperties.java. The ReloadConfigurationMonitor and ReloadableProperties classes enable dynamic configuration reloading. Without proper state validation and consistency checks, concurrent reloads could lead to inconsistent application state or injection of malicious values during reload operations. Fix: Implement atomic configuration updates using versioning. Add state consistency validation during reloads. Use immutable configuration objects. Implement rollback mechanisms for failed updates. Log all configuration changes.
  • Medium · Annotation-Based Configuration Processing May Be Vulnerable to Reflection Attacks — disconf-client/src/main/java/com/baidu/disconf/client/common/annotations/DisconfItem.java, disconf-client/src/main/java/com/baidu/disconf/client/common/annotations/DisconfFile.java. The DisconfItem, DisconfFile, and other annotations use reflection-based processing. Annotation values are processed without explicit validation, potentially allowing expression language injection or OGNL injection if user-controlled values are processed through reflection. Fix: Validate all annotation values and configuration keys against a whitelist pattern. Use parameterized reflection APIs. Disable expression language evaluation in configuration values. Implement input sanitization for all annotation-driven processing.
  • Medium · Lack of HTTPS/TLS Configuration Documentation — disconf-client/src/main/java/com/baidu/disconf/client/config/DisClientConfig.java. No visible configuration in the provided files for enforcing HTTPS/TLS communication between the client and configuration server. All configuration data could be transmitted in plaintext, exposing sensitive configuration values to network sniffing attacks. Fix: Enforce HTTPS/TLS for all client-server communications. Implement certificate pinning. Configure proper SSL/TLS validation. Document security configuration for client setup. Provide secure defaults.
  • Medium · Missing CSRF Protection in Configuration Update Mechanisms — undefined. Fix: undefined

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · knightliao/disconf — RepoPilot