Configuration Variables in System

Configuration and interactions with environment variables in the Universe product are organized as follows:

  • All string constants of the module should be located only in the ConfigurationConstants class. Each module has its own ConfigurationConstants. For example, ClassifiersConfigurationProperty is a ConfigurationProperty for classifiers.

  • Such configuration constants are prefixed with PROPERTY.

  • The constants are built by MODULE_ID + ".meaningful.name.of.the.property"

  • In the ConfigurationProperty classes of the module, which are in the same package as the constants, they MUST be described (even if the variable is for bootstrap, and you need to see its value on the UI). Example:

/**
* Enable/disable runtime profiler.
* Old:
* name: unidata.simon.enabled
* group: unidata.properties.group.simon
*/
public static final ConfigurationProperty<Boolean> SYSTEM_SIMON_ENABLED = ConfigurationProperty.bool()
    .key(SystemConfigurationConstants.PROPERTY_SIMON_ENABLED)
    .groupKey(SystemConfigurationConstants.PROPERTY_SYSTEM_GROUP)
    .moduleId(SystemModule.MODULE_ID)
    .setter(MeasurementPoint::setEnabled)
    .defaultValue(Boolean.FALSE)
    .readOnly(false)
    .required(false)
    .build();
  • Variables can be of any type but it is necessary to add serializer/deserializer (and, preferably, validator) to the string:

    /**
    * Data dump target format.
    * Old:
    * name: unidata.dump.target.format
    * group: not grouped
    */
    public static final ConfigurationProperty<DumpTargetFormat> SYSTEM_DUMP_TARGET_FORMAT = ConfigurationProperty.custom(DumpTargetFormat.class)
        .key(SystemConfigurationConstants.PROPERTY_DUMP_TARGET_FORMAT)
        .groupKey(SystemConfigurationConstants.PROPERTY_SYSTEM_GROUP)
        .moduleId(SystemModule.MODULE_ID)
        .deserializer(DumpTargetFormat::fromValue)
        .serializer(DumpTargetFormat::name)
        .defaultValue(DumpTargetFormat.PROTOSTUFF)
        .readOnly(true)
        .required(true)
        .build();
    

Example of a variable link:

/**
* The default dump target format.
*/
@ConfigurationRef(SystemConfigurationConstants.PROPERTY_DUMP_TARGET_FORMAT)
private ConfigurationValue<DumpTargetFormat> dumpTargetFormat;
  • A variable is not updated if it has .readOnly(true).

  • Nothing needs to be done to update the value of a variable.

  • If some kind of reaction/intervention is needed after the value is updated: you need to implement org.unidata.mdm.system.type.configuration.ConfigurationValueUpdatesListener.configurationValueUpdated(ConfigurationProperty<?>) with the same bin that contains the variable reference. Example:

@Override
public void configurationValueUpdated(ConfigurationProperty<?> p) {

    if (p != CoreConfigurationProperty.CORE_ASYNC_TASK_EXECUTOR_POOL_SIZE) {
        return;
    }

    threadPoolExecutor.setCorePoolSize(poolSize.getValue().intValue());
    threadPoolExecutor.setMaximumPoolSize(poolSize.getValue().intValue());
}
  • You can get values for any variable from org.unidata.mdm.system.service.RuntimePropertiesService.

  • If a variable is described as ConfigurationProperty<Long>, and you refer to it in code as ConfigurationValue<Boolean> you will get a CCE (ClassCastException) the moment you insert the value. This is important to keep in mind.