CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-alibaba-nacos--nacos-api

Nacos API package providing interfaces and common classes for dynamic service discovery, configuration management, and service management in cloud native applications and microservices

Pending
Overview
Eval results
Files

configuration.mddocs/

Configuration Management

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.

Capabilities

ConfigService

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

/**
 * Main interface for configuration operations
 */
interface ConfigService {
    /**
     * Get configuration content
     * @param dataId Configuration identifier
     * @param group Configuration group name
     * @param timeoutMs Timeout in milliseconds
     * @return Configuration content as string
     * @throws NacosException If retrieval fails
     */
    String getConfig(String dataId, String group, long timeoutMs) throws NacosException;
    
    /**
     * Get configuration content and register listener atomically
     * @param dataId Configuration identifier
     * @param group Configuration group name
     * @param timeoutMs Timeout in milliseconds
     * @param listener Change listener to register
     * @return Configuration content as string
     * @throws NacosException If operation fails
     */
    String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener) throws NacosException;
    
    /**
     * Publish configuration content
     * @param dataId Configuration identifier
     * @param group Configuration group name
     * @param content Configuration content
     * @return true if published successfully
     * @throws NacosException If publishing fails
     */
    boolean publishConfig(String dataId, String group, String content) throws NacosException;
    
    /**
     * Publish configuration with specific content type
     * @param dataId Configuration identifier
     * @param group Configuration group name
     * @param content Configuration content
     * @param type Content type (JSON, YAML, XML, etc.)
     * @return true if published successfully
     * @throws NacosException If publishing fails
     */
    boolean publishConfig(String dataId, String group, String content, String type) throws NacosException;
    
    /**
     * Publish configuration with CAS (Compare and Swap) operation
     * @param dataId Configuration identifier
     * @param group Configuration group name
     * @param content New configuration content
     * @param casMd5 Expected MD5 hash of current content
     * @return true if CAS operation succeeded
     * @throws NacosException If operation fails
     */
    boolean publishConfigCas(String dataId, String group, String content, String casMd5) throws NacosException;
    
    /**
     * Remove configuration
     * @param dataId Configuration identifier
     * @param group Configuration group name
     * @return true if removed successfully
     * @throws NacosException If removal fails
     */
    boolean removeConfig(String dataId, String group) throws NacosException;
    
    /**
     * Add configuration change listener
     * @param dataId Configuration identifier
     * @param group Configuration group name
     * @param listener Change listener
     * @throws NacosException If listener registration fails
     */
    void addListener(String dataId, String group, Listener listener) throws NacosException;
    
    /**
     * Remove configuration change listener
     * @param dataId Configuration identifier
     * @param group Configuration group name
     * @param listener Change listener to remove
     */
    void removeListener(String dataId, String group, Listener listener);
    
    /**
     * Watch multiple configurations with group pattern (3.0+)
     * @param groupNamePattern Group name pattern (supports wildcards)
     * @param watcher Event watcher for fuzzy matches
     * @throws NacosException If watch setup fails
     */
    void fuzzyWatch(String groupNamePattern, FuzzyWatchEventWatcher watcher) throws NacosException;
    
    /**
     * Watch multiple configurations with data ID and group patterns (3.0+)
     * @param dataIdPattern Data ID pattern (supports wildcards)
     * @param groupNamePattern Group name pattern (supports wildcards)
     * @param watcher Event watcher for fuzzy matches
     * @throws NacosException If watch setup fails
     */
    void fuzzyWatch(String dataIdPattern, String groupNamePattern, FuzzyWatchEventWatcher watcher) throws NacosException;
    
    /**
     * Watch with group pattern and return matched keys (3.0+)
     * @param groupNamePattern Group name pattern
     * @param watcher Event watcher
     * @return Future containing matched configuration keys
     * @throws NacosException If operation fails
     */
    Future<Set<String>> fuzzyWatchWithGroupKeys(String groupNamePattern, FuzzyWatchEventWatcher watcher) throws NacosException;
    
    /**
     * Get server status
     * @return Server status string
     */
    String getServerStatus();
    
    /**
     * Add configuration filter for preprocessing
     * @param configFilter Filter to add
     */
    void addConfigFilter(IConfigFilter configFilter);
    
    /**
     * Shutdown configuration service
     * @throws NacosException If shutdown fails
     */
    void shutDown() throws NacosException;
}

Configuration Listeners

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

/**
 * Base interface for configuration listeners
 */
interface Listener {
    /**
     * Get executor for handling configuration changes
     * @return Executor for async processing, null for synchronous
     */
    Executor getExecutor();
    
    /**
     * Receive configuration change notification
     * @param configInfo New configuration content
     */
    void receiveConfigInfo(String configInfo);
}

/**
 * Abstract base class for configuration listeners
 */
abstract class AbstractListener implements Listener {
    /**
     * Default implementation returns null for synchronous processing
     */
    @Override
    public Executor getExecutor() {
        return null;
    }
    
    /**
     * Abstract method to be implemented by subclasses
     */
    @Override
    public abstract void receiveConfigInfo(String configInfo);
}

/**
 * Configuration change listener with detailed change information
 */
abstract class AbstractSharedListener implements Listener {
    /**
     * Receive detailed configuration change information
     * @param dataId Configuration identifier
     * @param group Configuration group
     * @param configInfo New configuration content
     */
    public abstract void innerReceive(String dataId, String group, String configInfo);
    
    /**
     * Get filters for configuration content
     * @return Array of config filters
     */
    public ConfigFilter[] getConfigFilters() {
        return new ConfigFilter[0];
    }
}

/**
 * Fuzzy watch event watcher for pattern-based configuration monitoring (3.0+)
 */
interface FuzzyWatchEventWatcher {
    /**
     * Handle fuzzy watch events
     * @param event Configuration change event
     */
    void onEvent(FuzzyWatchEvent event);
    
    /**
     * Get executor for event processing
     * @return Executor for async processing
     */
    default Executor getExecutor() {
        return null;
    }
}

Configuration Events and Change Tracking

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

/**
 * Configuration change event containing detailed change information
 */
class ConfigChangeEvent {
    /** Configuration data ID */
    private final String dataId;
    
    /** Configuration group */
    private final String group;
    
    /** Namespace */
    private final String namespace;
    
    /** Map of changed configuration items */
    private final Map<String, ConfigChangeItem> data;
    
    /**
     * Constructor for configuration change event
     */
    public ConfigChangeEvent(String dataId, String group, String namespace, Map<String, ConfigChangeItem> data);
    
    /**
     * Get configuration identifier
     */
    public String getDataId();
    
    /**
     * Get configuration group
     */
    public String getGroup();
    
    /**
     * Get namespace
     */
    public String getNamespace();
    
    /**
     * Get all changed items
     */
    public Map<String, ConfigChangeItem> getData();
    
    /**
     * Get specific changed item
     */
    public ConfigChangeItem getChangeItem(String key);
}

/**
 * Individual configuration change item
 */
class ConfigChangeItem {
    /** Property key */
    private final String key;
    
    /** Old value */
    private final String oldValue;
    
    /** New value */
    private final String newValue;
    
    /** Type of change */
    private final PropertyChangeType type;
    
    /**
     * Constructor for change item
     */
    public ConfigChangeItem(String key, String oldValue, String newValue);
    
    /**
     * Get property key
     */
    public String getKey();
    
    /**
     * Get old value
     */
    public String getOldValue();
    
    /**
     * Get new value
     */
    public String getNewValue();
    
    /**
     * Get change type
     */
    public PropertyChangeType getType();
}

/**
 * Types of property changes
 */
enum PropertyChangeType {
    /** Property was added */
    ADDED,
    
    /** Property was modified */
    MODIFIED,
    
    /** Property was deleted */
    DELETED
}

Configuration Types and Filters

Support for different configuration file types and content filtering.

/**
 * Supported configuration file types
 */
enum ConfigType {
    /** Unspecified type */
    UNSET,
    
    /** Plain text */
    TEXT,
    
    /** JSON format */
    JSON,
    
    /** XML format */
    XML,
    
    /** YAML format */
    YAML,
    
    /** HTML format */
    HTML,
    
    /** Properties format */
    PROPERTIES;
    
    /**
     * Get config type from string
     */
    public static ConfigType getType(String type);
}

/**
 * Configuration filter interface for preprocessing content
 */
interface IConfigFilter {
    /**
     * Initialize filter
     * @param filterConfig Filter configuration
     */
    void init(IFilterConfig filterConfig);
    
    /**
     * Filter configuration content
     * @param configRequest Configuration request
     * @param configResponse Configuration response
     * @throws NacosException If filtering fails
     */
    void doFilter(IConfigRequest configRequest, IConfigResponse configResponse) throws NacosException;
    
    /**
     * Get filter name
     */
    String getFilterName();
}

Usage Examples

Basic Configuration Operations

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import java.util.Properties;
import java.util.concurrent.Executor;

// Create configuration service
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848");
properties.setProperty(PropertyKeyConst.NAMESPACE, "development");
ConfigService configService = NacosFactory.createConfigService(properties);

// Get configuration
String dataId = "application.properties";
String group = "DEFAULT_GROUP";
String config = configService.getConfig(dataId, group, 5000);
System.out.println("Current config: " + config);

// Publish configuration
String content = "app.name=MyApplication\napp.version=1.0.0\ndatabase.url=jdbc:mysql://localhost:3306/mydb";
boolean result = configService.publishConfig(dataId, group, content);
System.out.println("Published: " + result);

// Publish with specific type
boolean jsonResult = configService.publishConfig(
    "app-config.json", 
    group, 
    "{\"name\":\"MyApp\",\"version\":\"1.0\"}", 
    ConfigType.JSON.name()
);

Configuration Change Listeners

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

// Simple configuration listener
Listener simpleListener = new AbstractListener() {
    @Override
    public void receiveConfigInfo(String configInfo) {
        System.out.println("Configuration changed: " + configInfo);
        // Parse and apply new configuration
        applyConfiguration(configInfo);
    }
    
    @Override
    public Executor getExecutor() {
        // Return custom executor for async processing
        return Executors.newSingleThreadExecutor();
    }
};

// Add listener
configService.addListener(dataId, group, simpleListener);

// Shared listener with detailed change information
AbstractSharedListener detailedListener = new AbstractSharedListener() {
    @Override
    public void innerReceive(String dataId, String group, String configInfo) {
        System.out.printf("Config changed - DataId: %s, Group: %s%n", dataId, group);
        System.out.println("New content: " + configInfo);
        
        // Handle different data IDs differently
        if ("database.properties".equals(dataId)) {
            reconfigureDatabase(configInfo);
        } else if ("logging.properties".equals(dataId)) {
            reconfigureLogging(configInfo);
        }
    }
};

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

Advanced Configuration Management

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

// Configuration change event handling
public class ConfigChangeHandler {
    
    public void handleConfigChange(ConfigChangeEvent event) {
        System.out.printf("Configuration change in %s:%s%n", 
            event.getGroup(), event.getDataId());
        
        for (Map.Entry<String, ConfigChangeItem> entry : event.getData().entrySet()) {
            ConfigChangeItem item = entry.getValue();
            
            switch (item.getType()) {
                case ADDED:
                    System.out.printf("Added: %s = %s%n", 
                        item.getKey(), item.getNewValue());
                    break;
                case MODIFIED:
                    System.out.printf("Modified: %s = %s (was: %s)%n", 
                        item.getKey(), item.getNewValue(), item.getOldValue());
                    break;
                case DELETED:
                    System.out.printf("Deleted: %s (was: %s)%n", 
                        item.getKey(), item.getOldValue());
                    break;
            }
        }
    }
}

// CAS (Compare and Swap) operations for atomic updates
public boolean atomicConfigUpdate(ConfigService configService, 
                                String dataId, String group, 
                                String expectedContent, String newContent) {
    try {
        // Get current config with MD5
        String currentConfig = configService.getConfig(dataId, group, 3000);
        
        if (!expectedContent.equals(currentConfig)) {
            return false; // Content has changed
        }
        
        // Calculate MD5 of expected content
        String expectedMd5 = calculateMD5(expectedContent);
        
        // Perform atomic update
        return configService.publishConfigCas(dataId, group, newContent, expectedMd5);
        
    } catch (NacosException e) {
        System.err.println("Failed to perform atomic update: " + e.getMessage());
        return false;
    }
}

Fuzzy Watch (3.0+ Feature)

import com.alibaba.nacos.api.config.listener.FuzzyWatchEventWatcher;
import java.util.concurrent.Future;
import java.util.Set;

// Watch all configurations in a group pattern
FuzzyWatchEventWatcher groupWatcher = new FuzzyWatchEventWatcher() {
    @Override
    public void onEvent(FuzzyWatchEvent event) {
        System.out.printf("Fuzzy watch event: %s in group %s%n", 
            event.getDataId(), event.getGroup());
        System.out.println("Content: " + event.getContent());
    }
    
    @Override
    public Executor getExecutor() {
        return Executors.newFixedThreadPool(4);
    }
};

// Watch all configurations in groups matching pattern
configService.fuzzyWatch("app-*", groupWatcher);

// Watch specific data ID pattern in specific group pattern
configService.fuzzyWatch("*.properties", "DEFAULT_GROUP", groupWatcher);

// Watch with key retrieval
Future<Set<String>> future = configService.fuzzyWatchWithGroupKeys("microservice-*", groupWatcher);
Set<String> matchedKeys = future.get();
System.out.println("Matched configuration keys: " + matchedKeys);

Configuration Filtering

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

// Custom configuration filter for decryption
public class DecryptionFilter implements IConfigFilter {
    
    @Override
    public void init(IFilterConfig filterConfig) {
        // Initialize decryption keys, etc.
    }
    
    @Override
    public void doFilter(IConfigRequest request, IConfigResponse response) throws NacosException {
        String content = response.getContent();
        
        // Decrypt sensitive configuration values
        if (content != null && content.contains("encrypted:")) {
            String decryptedContent = decryptContent(content);
            response.setContent(decryptedContent);
        }
    }
    
    @Override
    public String getFilterName() {
        return "decryption-filter";
    }
    
    private String decryptContent(String encryptedContent) {
        // Implement decryption logic
        return encryptedContent.replaceAll("encrypted:(\\w+)", "decrypted_value");
    }
}

// Add filter to configuration service
configService.addConfigFilter(new DecryptionFilter());

Error Handling and Best Practices

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

public class ConfigurationManager {
    
    private final ConfigService configService;
    private final Map<String, String> configCache = new ConcurrentHashMap<>();
    
    public ConfigurationManager(ConfigService configService) {
        this.configService = configService;
    }
    
    public String getConfigSafely(String dataId, String group, String defaultValue) {
        try {
            String config = configService.getConfig(dataId, group, 3000);
            
            if (config != null) {
                configCache.put(dataId + ":" + group, config);
                return config;
            }
            
            // Return cached value if available
            String cached = configCache.get(dataId + ":" + group);
            return cached != null ? cached : defaultValue;
            
        } catch (NacosException e) {
            System.err.printf("Failed to get config %s:%s - %s%n", 
                group, dataId, e.getMessage());
                
            // Return cached value or default
            String cached = configCache.get(dataId + ":" + group);
            return cached != null ? cached : defaultValue;
        }
    }
    
    public boolean publishConfigSafely(String dataId, String group, String content) {
        for (int retry = 0; retry < 3; retry++) {
            try {
                boolean result = configService.publishConfig(dataId, group, content);
                if (result) {
                    configCache.put(dataId + ":" + group, content);
                    return true;
                }
            } catch (NacosException e) {
                System.err.printf("Attempt %d failed to publish config %s:%s - %s%n", 
                    retry + 1, group, dataId, e.getMessage());
                
                if (retry == 2) {
                    return false; // Final attempt failed
                }
                
                try {
                    Thread.sleep(1000 * (retry + 1)); // Exponential backoff
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    return false;
                }
            }
        }
        return false;
    }
    
    public void setupResillientListener(String dataId, String group, 
                                      Consumer<String> configHandler) {
        Listener resilientListener = new AbstractListener() {
            @Override
            public void receiveConfigInfo(String configInfo) {
                try {
                    configHandler.accept(configInfo);
                    configCache.put(dataId + ":" + group, configInfo);
                } catch (Exception e) {
                    System.err.printf("Error processing config change for %s:%s - %s%n", 
                        group, dataId, e.getMessage());
                }
            }
            
            @Override
            public Executor getExecutor() {
                // Use dedicated thread pool for configuration processing
                return Executors.newSingleThreadExecutor(r -> {
                    Thread t = new Thread(r, "config-processor-" + dataId);
                    t.setDaemon(true);
                    return t;
                });
            }
        };
        
        try {
            configService.addListener(dataId, group, resilientListener);
        } catch (NacosException e) {
            System.err.printf("Failed to add listener for %s:%s - %s%n", 
                group, dataId, e.getMessage());
        }
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-com-alibaba-nacos--nacos-api

docs

ai-mcp.md

configuration.md

core-api.md

exceptions.md

index.md

naming.md

remote.md

tile.json