or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ai-mcp.mdconfiguration.mdcore-api.mdexceptions.mdindex.mdnaming.mdremote.md

configuration.mddocs/

0

# Configuration Management

1

2

Dynamic configuration management with real-time updates, listeners, and fuzzy watching capabilities. Perfect for application settings, feature flags, environment-specific configurations, and any data that needs to be updated without application restarts.

3

4

## Capabilities

5

6

### ConfigService

7

8

Main interface for all configuration operations including retrieving, publishing, and managing configuration data with real-time change notifications.

9

10

```java { .api }

11

/**

12

* Main interface for configuration operations

13

*/

14

interface ConfigService {

15

/**

16

* Get configuration content

17

* @param dataId Configuration identifier

18

* @param group Configuration group name

19

* @param timeoutMs Timeout in milliseconds

20

* @return Configuration content as string

21

* @throws NacosException If retrieval fails

22

*/

23

String getConfig(String dataId, String group, long timeoutMs) throws NacosException;

24

25

/**

26

* Get configuration content and register listener atomically

27

* @param dataId Configuration identifier

28

* @param group Configuration group name

29

* @param timeoutMs Timeout in milliseconds

30

* @param listener Change listener to register

31

* @return Configuration content as string

32

* @throws NacosException If operation fails

33

*/

34

String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener) throws NacosException;

35

36

/**

37

* Publish configuration content

38

* @param dataId Configuration identifier

39

* @param group Configuration group name

40

* @param content Configuration content

41

* @return true if published successfully

42

* @throws NacosException If publishing fails

43

*/

44

boolean publishConfig(String dataId, String group, String content) throws NacosException;

45

46

/**

47

* Publish configuration with specific content type

48

* @param dataId Configuration identifier

49

* @param group Configuration group name

50

* @param content Configuration content

51

* @param type Content type (JSON, YAML, XML, etc.)

52

* @return true if published successfully

53

* @throws NacosException If publishing fails

54

*/

55

boolean publishConfig(String dataId, String group, String content, String type) throws NacosException;

56

57

/**

58

* Publish configuration with CAS (Compare and Swap) operation

59

* @param dataId Configuration identifier

60

* @param group Configuration group name

61

* @param content New configuration content

62

* @param casMd5 Expected MD5 hash of current content

63

* @return true if CAS operation succeeded

64

* @throws NacosException If operation fails

65

*/

66

boolean publishConfigCas(String dataId, String group, String content, String casMd5) throws NacosException;

67

68

/**

69

* Remove configuration

70

* @param dataId Configuration identifier

71

* @param group Configuration group name

72

* @return true if removed successfully

73

* @throws NacosException If removal fails

74

*/

75

boolean removeConfig(String dataId, String group) throws NacosException;

76

77

/**

78

* Add configuration change listener

79

* @param dataId Configuration identifier

80

* @param group Configuration group name

81

* @param listener Change listener

82

* @throws NacosException If listener registration fails

83

*/

84

void addListener(String dataId, String group, Listener listener) throws NacosException;

85

86

/**

87

* Remove configuration change listener

88

* @param dataId Configuration identifier

89

* @param group Configuration group name

90

* @param listener Change listener to remove

91

*/

92

void removeListener(String dataId, String group, Listener listener);

93

94

/**

95

* Watch multiple configurations with group pattern (3.0+)

96

* @param groupNamePattern Group name pattern (supports wildcards)

97

* @param watcher Event watcher for fuzzy matches

98

* @throws NacosException If watch setup fails

99

*/

100

void fuzzyWatch(String groupNamePattern, FuzzyWatchEventWatcher watcher) throws NacosException;

101

102

/**

103

* Watch multiple configurations with data ID and group patterns (3.0+)

104

* @param dataIdPattern Data ID pattern (supports wildcards)

105

* @param groupNamePattern Group name pattern (supports wildcards)

106

* @param watcher Event watcher for fuzzy matches

107

* @throws NacosException If watch setup fails

108

*/

109

void fuzzyWatch(String dataIdPattern, String groupNamePattern, FuzzyWatchEventWatcher watcher) throws NacosException;

110

111

/**

112

* Watch with group pattern and return matched keys (3.0+)

113

* @param groupNamePattern Group name pattern

114

* @param watcher Event watcher

115

* @return Future containing matched configuration keys

116

* @throws NacosException If operation fails

117

*/

118

Future<Set<String>> fuzzyWatchWithGroupKeys(String groupNamePattern, FuzzyWatchEventWatcher watcher) throws NacosException;

119

120

/**

121

* Get server status

122

* @return Server status string

123

*/

124

String getServerStatus();

125

126

/**

127

* Add configuration filter for preprocessing

128

* @param configFilter Filter to add

129

*/

130

void addConfigFilter(IConfigFilter configFilter);

131

132

/**

133

* Shutdown configuration service

134

* @throws NacosException If shutdown fails

135

*/

136

void shutDown() throws NacosException;

137

}

138

```

139

140

### Configuration Listeners

141

142

Event-driven configuration change handling with different listener implementations for various use cases.

143

144

```java { .api }

145

/**

146

* Base interface for configuration listeners

147

*/

148

interface Listener {

149

/**

150

* Get executor for handling configuration changes

151

* @return Executor for async processing, null for synchronous

152

*/

153

Executor getExecutor();

154

155

/**

156

* Receive configuration change notification

157

* @param configInfo New configuration content

158

*/

159

void receiveConfigInfo(String configInfo);

160

}

161

162

/**

163

* Abstract base class for configuration listeners

164

*/

165

abstract class AbstractListener implements Listener {

166

/**

167

* Default implementation returns null for synchronous processing

168

*/

169

@Override

170

public Executor getExecutor() {

171

return null;

172

}

173

174

/**

175

* Abstract method to be implemented by subclasses

176

*/

177

@Override

178

public abstract void receiveConfigInfo(String configInfo);

179

}

180

181

/**

182

* Configuration change listener with detailed change information

183

*/

184

abstract class AbstractSharedListener implements Listener {

185

/**

186

* Receive detailed configuration change information

187

* @param dataId Configuration identifier

188

* @param group Configuration group

189

* @param configInfo New configuration content

190

*/

191

public abstract void innerReceive(String dataId, String group, String configInfo);

192

193

/**

194

* Get filters for configuration content

195

* @return Array of config filters

196

*/

197

public ConfigFilter[] getConfigFilters() {

198

return new ConfigFilter[0];

199

}

200

}

201

202

/**

203

* Fuzzy watch event watcher for pattern-based configuration monitoring (3.0+)

204

*/

205

interface FuzzyWatchEventWatcher {

206

/**

207

* Handle fuzzy watch events

208

* @param event Configuration change event

209

*/

210

void onEvent(FuzzyWatchEvent event);

211

212

/**

213

* Get executor for event processing

214

* @return Executor for async processing

215

*/

216

default Executor getExecutor() {

217

return null;

218

}

219

}

220

```

221

222

### Configuration Events and Change Tracking

223

224

Event classes for tracking configuration changes with detailed information about what changed.

225

226

```java { .api }

227

/**

228

* Configuration change event containing detailed change information

229

*/

230

class ConfigChangeEvent {

231

/** Configuration data ID */

232

private final String dataId;

233

234

/** Configuration group */

235

private final String group;

236

237

/** Namespace */

238

private final String namespace;

239

240

/** Map of changed configuration items */

241

private final Map<String, ConfigChangeItem> data;

242

243

/**

244

* Constructor for configuration change event

245

*/

246

public ConfigChangeEvent(String dataId, String group, String namespace, Map<String, ConfigChangeItem> data);

247

248

/**

249

* Get configuration identifier

250

*/

251

public String getDataId();

252

253

/**

254

* Get configuration group

255

*/

256

public String getGroup();

257

258

/**

259

* Get namespace

260

*/

261

public String getNamespace();

262

263

/**

264

* Get all changed items

265

*/

266

public Map<String, ConfigChangeItem> getData();

267

268

/**

269

* Get specific changed item

270

*/

271

public ConfigChangeItem getChangeItem(String key);

272

}

273

274

/**

275

* Individual configuration change item

276

*/

277

class ConfigChangeItem {

278

/** Property key */

279

private final String key;

280

281

/** Old value */

282

private final String oldValue;

283

284

/** New value */

285

private final String newValue;

286

287

/** Type of change */

288

private final PropertyChangeType type;

289

290

/**

291

* Constructor for change item

292

*/

293

public ConfigChangeItem(String key, String oldValue, String newValue);

294

295

/**

296

* Get property key

297

*/

298

public String getKey();

299

300

/**

301

* Get old value

302

*/

303

public String getOldValue();

304

305

/**

306

* Get new value

307

*/

308

public String getNewValue();

309

310

/**

311

* Get change type

312

*/

313

public PropertyChangeType getType();

314

}

315

316

/**

317

* Types of property changes

318

*/

319

enum PropertyChangeType {

320

/** Property was added */

321

ADDED,

322

323

/** Property was modified */

324

MODIFIED,

325

326

/** Property was deleted */

327

DELETED

328

}

329

```

330

331

### Configuration Types and Filters

332

333

Support for different configuration file types and content filtering.

334

335

```java { .api }

336

/**

337

* Supported configuration file types

338

*/

339

enum ConfigType {

340

/** Unspecified type */

341

UNSET,

342

343

/** Plain text */

344

TEXT,

345

346

/** JSON format */

347

JSON,

348

349

/** XML format */

350

XML,

351

352

/** YAML format */

353

YAML,

354

355

/** HTML format */

356

HTML,

357

358

/** Properties format */

359

PROPERTIES;

360

361

/**

362

* Get config type from string

363

*/

364

public static ConfigType getType(String type);

365

}

366

367

/**

368

* Configuration filter interface for preprocessing content

369

*/

370

interface IConfigFilter {

371

/**

372

* Initialize filter

373

* @param filterConfig Filter configuration

374

*/

375

void init(IFilterConfig filterConfig);

376

377

/**

378

* Filter configuration content

379

* @param configRequest Configuration request

380

* @param configResponse Configuration response

381

* @throws NacosException If filtering fails

382

*/

383

void doFilter(IConfigRequest configRequest, IConfigResponse configResponse) throws NacosException;

384

385

/**

386

* Get filter name

387

*/

388

String getFilterName();

389

}

390

```

391

392

## Usage Examples

393

394

### Basic Configuration Operations

395

396

```java

397

import com.alibaba.nacos.api.NacosFactory;

398

import com.alibaba.nacos.api.PropertyKeyConst;

399

import com.alibaba.nacos.api.config.ConfigService;

400

import com.alibaba.nacos.api.config.listener.Listener;

401

import java.util.Properties;

402

import java.util.concurrent.Executor;

403

404

// Create configuration service

405

Properties properties = new Properties();

406

properties.setProperty(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848");

407

properties.setProperty(PropertyKeyConst.NAMESPACE, "development");

408

ConfigService configService = NacosFactory.createConfigService(properties);

409

410

// Get configuration

411

String dataId = "application.properties";

412

String group = "DEFAULT_GROUP";

413

String config = configService.getConfig(dataId, group, 5000);

414

System.out.println("Current config: " + config);

415

416

// Publish configuration

417

String content = "app.name=MyApplication\napp.version=1.0.0\ndatabase.url=jdbc:mysql://localhost:3306/mydb";

418

boolean result = configService.publishConfig(dataId, group, content);

419

System.out.println("Published: " + result);

420

421

// Publish with specific type

422

boolean jsonResult = configService.publishConfig(

423

"app-config.json",

424

group,

425

"{\"name\":\"MyApp\",\"version\":\"1.0\"}",

426

ConfigType.JSON.name()

427

);

428

```

429

430

### Configuration Change Listeners

431

432

```java

433

import com.alibaba.nacos.api.config.listener.AbstractListener;

434

import com.alibaba.nacos.api.config.listener.AbstractSharedListener;

435

436

// Simple configuration listener

437

Listener simpleListener = new AbstractListener() {

438

@Override

439

public void receiveConfigInfo(String configInfo) {

440

System.out.println("Configuration changed: " + configInfo);

441

// Parse and apply new configuration

442

applyConfiguration(configInfo);

443

}

444

445

@Override

446

public Executor getExecutor() {

447

// Return custom executor for async processing

448

return Executors.newSingleThreadExecutor();

449

}

450

};

451

452

// Add listener

453

configService.addListener(dataId, group, simpleListener);

454

455

// Shared listener with detailed change information

456

AbstractSharedListener detailedListener = new AbstractSharedListener() {

457

@Override

458

public void innerReceive(String dataId, String group, String configInfo) {

459

System.out.printf("Config changed - DataId: %s, Group: %s%n", dataId, group);

460

System.out.println("New content: " + configInfo);

461

462

// Handle different data IDs differently

463

if ("database.properties".equals(dataId)) {

464

reconfigureDatabase(configInfo);

465

} else if ("logging.properties".equals(dataId)) {

466

reconfigureLogging(configInfo);

467

}

468

}

469

};

470

471

configService.addListener("database.properties", group, detailedListener);

472

configService.addListener("logging.properties", group, detailedListener);

473

```

474

475

### Advanced Configuration Management

476

477

```java

478

import com.alibaba.nacos.api.config.ConfigChangeEvent;

479

import com.alibaba.nacos.api.config.ConfigChangeItem;

480

import com.alibaba.nacos.api.config.PropertyChangeType;

481

482

// Configuration change event handling

483

public class ConfigChangeHandler {

484

485

public void handleConfigChange(ConfigChangeEvent event) {

486

System.out.printf("Configuration change in %s:%s%n",

487

event.getGroup(), event.getDataId());

488

489

for (Map.Entry<String, ConfigChangeItem> entry : event.getData().entrySet()) {

490

ConfigChangeItem item = entry.getValue();

491

492

switch (item.getType()) {

493

case ADDED:

494

System.out.printf("Added: %s = %s%n",

495

item.getKey(), item.getNewValue());

496

break;

497

case MODIFIED:

498

System.out.printf("Modified: %s = %s (was: %s)%n",

499

item.getKey(), item.getNewValue(), item.getOldValue());

500

break;

501

case DELETED:

502

System.out.printf("Deleted: %s (was: %s)%n",

503

item.getKey(), item.getOldValue());

504

break;

505

}

506

}

507

}

508

}

509

510

// CAS (Compare and Swap) operations for atomic updates

511

public boolean atomicConfigUpdate(ConfigService configService,

512

String dataId, String group,

513

String expectedContent, String newContent) {

514

try {

515

// Get current config with MD5

516

String currentConfig = configService.getConfig(dataId, group, 3000);

517

518

if (!expectedContent.equals(currentConfig)) {

519

return false; // Content has changed

520

}

521

522

// Calculate MD5 of expected content

523

String expectedMd5 = calculateMD5(expectedContent);

524

525

// Perform atomic update

526

return configService.publishConfigCas(dataId, group, newContent, expectedMd5);

527

528

} catch (NacosException e) {

529

System.err.println("Failed to perform atomic update: " + e.getMessage());

530

return false;

531

}

532

}

533

```

534

535

### Fuzzy Watch (3.0+ Feature)

536

537

```java

538

import com.alibaba.nacos.api.config.listener.FuzzyWatchEventWatcher;

539

import java.util.concurrent.Future;

540

import java.util.Set;

541

542

// Watch all configurations in a group pattern

543

FuzzyWatchEventWatcher groupWatcher = new FuzzyWatchEventWatcher() {

544

@Override

545

public void onEvent(FuzzyWatchEvent event) {

546

System.out.printf("Fuzzy watch event: %s in group %s%n",

547

event.getDataId(), event.getGroup());

548

System.out.println("Content: " + event.getContent());

549

}

550

551

@Override

552

public Executor getExecutor() {

553

return Executors.newFixedThreadPool(4);

554

}

555

};

556

557

// Watch all configurations in groups matching pattern

558

configService.fuzzyWatch("app-*", groupWatcher);

559

560

// Watch specific data ID pattern in specific group pattern

561

configService.fuzzyWatch("*.properties", "DEFAULT_GROUP", groupWatcher);

562

563

// Watch with key retrieval

564

Future<Set<String>> future = configService.fuzzyWatchWithGroupKeys("microservice-*", groupWatcher);

565

Set<String> matchedKeys = future.get();

566

System.out.println("Matched configuration keys: " + matchedKeys);

567

```

568

569

### Configuration Filtering

570

571

```java

572

import com.alibaba.nacos.api.config.filter.IConfigFilter;

573

import com.alibaba.nacos.api.config.filter.IConfigRequest;

574

import com.alibaba.nacos.api.config.filter.IConfigResponse;

575

576

// Custom configuration filter for decryption

577

public class DecryptionFilter implements IConfigFilter {

578

579

@Override

580

public void init(IFilterConfig filterConfig) {

581

// Initialize decryption keys, etc.

582

}

583

584

@Override

585

public void doFilter(IConfigRequest request, IConfigResponse response) throws NacosException {

586

String content = response.getContent();

587

588

// Decrypt sensitive configuration values

589

if (content != null && content.contains("encrypted:")) {

590

String decryptedContent = decryptContent(content);

591

response.setContent(decryptedContent);

592

}

593

}

594

595

@Override

596

public String getFilterName() {

597

return "decryption-filter";

598

}

599

600

private String decryptContent(String encryptedContent) {

601

// Implement decryption logic

602

return encryptedContent.replaceAll("encrypted:(\\w+)", "decrypted_value");

603

}

604

}

605

606

// Add filter to configuration service

607

configService.addConfigFilter(new DecryptionFilter());

608

```

609

610

### Error Handling and Best Practices

611

612

```java

613

import com.alibaba.nacos.api.exception.NacosException;

614

615

public class ConfigurationManager {

616

617

private final ConfigService configService;

618

private final Map<String, String> configCache = new ConcurrentHashMap<>();

619

620

public ConfigurationManager(ConfigService configService) {

621

this.configService = configService;

622

}

623

624

public String getConfigSafely(String dataId, String group, String defaultValue) {

625

try {

626

String config = configService.getConfig(dataId, group, 3000);

627

628

if (config != null) {

629

configCache.put(dataId + ":" + group, config);

630

return config;

631

}

632

633

// Return cached value if available

634

String cached = configCache.get(dataId + ":" + group);

635

return cached != null ? cached : defaultValue;

636

637

} catch (NacosException e) {

638

System.err.printf("Failed to get config %s:%s - %s%n",

639

group, dataId, e.getMessage());

640

641

// Return cached value or default

642

String cached = configCache.get(dataId + ":" + group);

643

return cached != null ? cached : defaultValue;

644

}

645

}

646

647

public boolean publishConfigSafely(String dataId, String group, String content) {

648

for (int retry = 0; retry < 3; retry++) {

649

try {

650

boolean result = configService.publishConfig(dataId, group, content);

651

if (result) {

652

configCache.put(dataId + ":" + group, content);

653

return true;

654

}

655

} catch (NacosException e) {

656

System.err.printf("Attempt %d failed to publish config %s:%s - %s%n",

657

retry + 1, group, dataId, e.getMessage());

658

659

if (retry == 2) {

660

return false; // Final attempt failed

661

}

662

663

try {

664

Thread.sleep(1000 * (retry + 1)); // Exponential backoff

665

} catch (InterruptedException ie) {

666

Thread.currentThread().interrupt();

667

return false;

668

}

669

}

670

}

671

return false;

672

}

673

674

public void setupResillientListener(String dataId, String group,

675

Consumer<String> configHandler) {

676

Listener resilientListener = new AbstractListener() {

677

@Override

678

public void receiveConfigInfo(String configInfo) {

679

try {

680

configHandler.accept(configInfo);

681

configCache.put(dataId + ":" + group, configInfo);

682

} catch (Exception e) {

683

System.err.printf("Error processing config change for %s:%s - %s%n",

684

group, dataId, e.getMessage());

685

}

686

}

687

688

@Override

689

public Executor getExecutor() {

690

// Use dedicated thread pool for configuration processing

691

return Executors.newSingleThreadExecutor(r -> {

692

Thread t = new Thread(r, "config-processor-" + dataId);

693

t.setDaemon(true);

694

return t;

695

});

696

}

697

};

698

699

try {

700

configService.addListener(dataId, group, resilientListener);

701

} catch (NacosException e) {

702

System.err.printf("Failed to add listener for %s:%s - %s%n",

703

group, dataId, e.getMessage());

704

}

705

}

706

}