Motivation

Dynamic configuration is an important feature in the production environment, the Pulsar supports this feature, see ServiceConfiguration.java, when the field has @FieldContext(dynamic = true) means it is a dynamic configuration, and then we can use the pulsar-admin to update this field.

The Pulsar has multiple pluggable plugins like authentication provider, authorization provider, and so on. In the plugin, we can get the Pulsar configurations and customized configurations, in some scenarios, we need to use the pulsar-admin to change the values of customized configuration, but the Pulsar doesn't support this operation.

Goals

In Scope

The goal of this PIP is to allow the pulsar-admin to update the values of customized configuration, and also use the listener to listen the customized configuration changes by org.apache.pulsar.broker.service.BrokerService.registerConfigurationListener.

Detailed Design

Design & Implementation Details

The org.apache.pulsar.broker.service.BrokerService.dynamicConfigurationMap holds the dynamic configurations, so we just to add the configurations that need to be dynamically configured to this map, and then we can use the pulsar-admin to update the values of these configurations.

Users can only register custom configurations and only once. If multiple registrations are performed, an exception will be thrown.

Add void registerCustomDynamicConfiguration(String key, Predicate<String> validator) to the BrokerService.java,

public void registerCustomDynamicConfiguration(String key, Predicate<String> validator) {
    if (dynamicConfigurationMap.containsKey(key)) {
        throw new IllegalArgumentException(key + " already exists in the dynamicConfigurationMap");
    }

    ConfigField configField = ConfigField.newCustomConfigField(null);
    configField.validator = validator;
    dynamicConfigurationMap.put(key, configField);
}

Example of using this feature in the plugin:

@Override
public void initialize(PulsarService pulsarService) throws Exception {
    String myAuthIdKey = "my-auth-id";
    myAuthIdValue = pulsarService.getConfiguration().getProperties().getProperty(myAuthIdKey);

    pulsarService.getBrokerService().registerCustomDynamicConfiguration(myAuthIdKey, null);
    pulsarService.getBrokerService().registerConfigurationListener(myAuthIdKey, (newValue) -> {
        // The `myAuthIdKey` value has changed
        myAuthIdValue = String.valueOf(newValue);
    });
}

Backward & Forward Compatibility

Revert

General Notes

Links