Serge Huber created UNOMI-917:
---------------------------------

             Summary: Dynamic configuration changes are overridden by 
custom.system.properties because of Karaf's property override system.
                 Key: UNOMI-917
                 URL: https://issues.apache.org/jira/browse/UNOMI-917
             Project: Apache Unomi
          Issue Type: Bug
          Components: unomi(-core)
    Affects Versions: unomi-2.7.0, unomi-3.0.0, unomi-3.1.0
            Reporter: Serge Huber
             Fix For: unomi-4.0.0, unomi-3.2.0


h1. Configuration Admin Updates Not Applied Due to Karaf System Property 
Override
h2. Summary

Configuration changes made via Karaf's {{config:property-set}} and 
{{config:update}} commands are not being applied because Karaf's 
{{KarafConfigurationPlugin}} automatically overrides Configuration Admin 
properties when matching system properties or environment variables exist.
h2. Problem Description
h3. What's Happening

When administrators try to update configuration properties using Karaf's 
Configuration Admin commands:
{code:java}
config:edit org.apache.unomi.router
config:property-set kafka.host my-kafka-server
config:update
{code}
The changes are saved to the configuration file, but the actual component 
doesn't receive the updated values. Instead, it continues using the values from 
system properties or environment variables.
h3. Root Cause

Apache Karaf includes a {{KarafConfigurationPlugin}} that automatically 
overrides Configuration Admin properties when it finds matching system 
properties or environment variables. The override pattern is:

*System Property Pattern:* {{configurationPid.propertyName}}

For example:
 * Configuration PID: {{org.apache.unomi.router}}
 * Property name: {{kafka.host}}
 * Karaf looks for: {{org.apache.unomi.router.kafka.host}}

If this system property exists (either as a system property or environment 
variable), Karaf *always* uses it, completely ignoring any Configuration Admin 
updates.
h3. Why This Is a Problem

Unomi uses a large {{custom.system.properties}} file that contains many 
properties following this exact naming convention. These properties were 
originally created to allow environment variable overrides, but they now 
prevent Configuration Admin from working properly.

*Example:*
 * {{.cfg}} file has: {{{}kafka.host = 
$\{org.apache.unomi.router.kafka.host:-localhost{}}}}
 * {{custom.system.properties}} has: 
{{{}org.apache.unomi.router.kafka.host=$\{env:UNOMI_ROUTER_KAFKA_HOST:-localhost{}}}}
 * Karaf sees the system property {{org.apache.unomi.router.kafka.host}} and 
*always* overrides the Configuration Admin value
 * Result: {{config:property-set}} changes are ignored

h2. Affected Components

The following configuration components are affected (excluding 
{{org.apache.unomi.rest.authentication}} which is being fixed separately):
h3. 1. {{org.apache.unomi.migration}} (1 property)
 * *Property:* {{recoverFromHistory}}
 * *System Property:* {{org.apache.unomi.migration.recoverFromHistory}}

h3. 2. {{org.apache.unomi.router}} (13 properties)
 * *Properties:* {{{}kafka.host{}}}, {{{}kafka.port{}}}, 
{{{}kafka.import.topic{}}}, {{{}kafka.export.topic{}}}, 
{{{}kafka.import.groupId{}}}, {{{}kafka.export.groupId{}}}, 
{{{}kafka.consumerCount{}}}, {{{}kafka.autoCommit{}}}, 
{{{}import.oneshot.uploadDir{}}}, {{{}executionsHistory.size{}}}, 
{{{}executions.error.report.size{}}}, {{{}config.allowedEndpoints{}}}, 
{{configs.refresh.interval}}
 * *System Properties:* {{org.apache.unomi.router.*}} (all matching the 
property names)

h3. 3. {{org.apache.unomi.cluster}} (2 properties)
 * *Properties:* {{{}nodeId{}}}, {{nodeStatisticsUpdateFrequency}}
 * *System Properties:* {{{}org.apache.unomi.cluster.nodeId{}}}, 
{{org.apache.unomi.cluster.nodeStatisticsUpdateFrequency}}

h3. 4. {{org.apache.unomi.plugins.base}} (1 property)
 * *Property:* {{maxProfilesInOneMerge}}
 * *System Property:* {{org.apache.unomi.plugins.base.maxProfilesInOneMerge}}

h3. 5. {{org.apache.unomi.services}} (1 property)
 * *Property:* {{segment.max.retries.update.profile.segment}}
 * *System Property:* 
{{org.apache.unomi.services.segment.max.retries.update.profile.segment}}

*Total:* 18 properties across 5 components
h2. Proposed Solution
h3. Strategy: Rename Properties in {{.cfg}} Files

Rename the property names in {{.cfg}} files to use domain-specific prefixes or 
hierarchical naming. This breaks the Karaf override pattern while maintaining 
backward compatibility for variable substitution.
h3. How It Works

*Karaf Override Pattern:* {{PID.propertyName}} (exact match required)

*Example for Router:*
 * *Old:* {{.cfg}} has {{{}kafka.host{}}}, system property is 
{{org.apache.unomi.router.kafka.host}} -> *MATCH* -> Override occurs
 * *New:* {{.cfg}} has {{{}router.kafka.host{}}}, system property is 
{{org.apache.unomi.router.kafka.host}} -> Karaf looks for 
{{org.apache.unomi.router.router.kafka.host}} -> *NO MATCH* -> No override

*Key Point:* The {{{}$\{...{}}}} system property references in {{.cfg}} files 
remain unchanged. They still work for variable substitution, but they no longer 
trigger Karaf's override mechanism.
h3. Proposed Property Renames
||Component||Current Property||Proposed New Name||Rationale||
|Migration|{{recoverFromHistory}}|{{migration.recoverFromHistory}}|Domain-specific
 prefix|
|Router|{{kafka.host}}|{{router.kafka.host}}|Add {{router.}} prefix to all 
router properties|
|Router|{{kafka.port}}|{{router.kafka.port}}|Add {{router.}} prefix to all 
router properties|
|Router|{{kafka.import.topic}}|{{router.kafka.import.topic}}|Add {{router.}} 
prefix to all router properties|
|Router|{{kafka.export.topic}}|{{router.kafka.export.topic}}|Add {{router.}} 
prefix to all router properties|
|Router|{{kafka.import.groupId}}|{{router.kafka.import.groupId}}|Add 
{{router.}} prefix to all router properties|
|Router|{{kafka.export.groupId}}|{{router.kafka.export.groupId}}|Add 
{{router.}} prefix to all router properties|
|Router|{{kafka.consumerCount}}|{{router.kafka.consumerCount}}|Add {{router.}} 
prefix to all router properties|
|Router|{{kafka.autoCommit}}|{{router.kafka.autoCommit}}|Add {{router.}} prefix 
to all router properties|
|Router|{{import.oneshot.uploadDir}}|{{router.import.oneshot.uploadDir}}|Add 
{{router.}} prefix to all router properties|
|Router|{{executionsHistory.size}}|{{router.executionsHistory.size}}|Add 
{{router.}} prefix to all router properties|
|Router|{{executions.error.report.size}}|{{router.executions.error.report.size}}|Add
 {{router.}} prefix to all router properties|
|Router|{{config.allowedEndpoints}}|{{router.config.allowedEndpoints}}|Add 
{{router.}} prefix to all router properties|
|Router|{{configs.refresh.interval}}|{{router.configs.refresh.interval}}|Add 
{{router.}} prefix to all router properties|
|Cluster|{{nodeId}}|{{cluster.nodeId}}|Domain-specific prefix|
|Cluster|{{nodeStatisticsUpdateFrequency}}|{{cluster.nodeStatisticsUpdateFrequency}}|Domain-specific
 prefix|
|Plugins 
Base|{{maxProfilesInOneMerge}}|{{merge.maxProfilesInOneMerge}}|Domain-specific 
prefix|
|Services|{{segment.max.retries.update.profile.segment}}|{{updateProfileSegment.maxRetries}}|More
 readable, domain-specific|

h3. Implementation Details
* Update {{.cfg}} files:*
 # Rename property names (left side of {{{}={}}})
 # Keep {{{}$\{...{}}}} system property references unchanged (right side of 
{{{}={}}})
 # Add explanatory comments about why the naming is used

*Update code references:*
 # Blueprint XML: Update {{<cm:property>}} names and {{{}$\{...{}}}} references
 # Java code: Update property lookups and constants
 # Tests: Update property name references

*System properties:*
 # Old system properties in {{custom.system.properties}} become unused for 
overrides
 # They still work for variable substitution in {{.cfg}} files
 # Can be removed or left for backward compatibility

h3. Benefits
 * *Fixes the problem:* Configuration Admin updates will work correctly
 * *Backward compatible:* System properties still work for variable substitution
 * *No breaking changes:* Users don't need to update 
{{custom.system.properties}}
 * *Better readability:* Some properties become more readable (e.g., 
{{{}updateProfileSegment.maxRetries{}}})
 * *Self-documenting:* Domain-specific prefixes make configuration clearer

h3. Impact Assessment
||Component||Impact Level||Files to Update||
|Migration|Low|1 {{{}.cfg{}}}, 1 Java file|
|Router|High|1 {{{}.cfg{}}}, 1 Blueprint XML (~15 references)|
|Cluster|Medium|1 {{{}.cfg{}}}, 1 Blueprint XML (2 references)|
|Plugins Base|Low|1 {{{}.cfg{}}}, 1 Blueprint XML, 1 Java file|
|Services|Low|1 {{{}.cfg{}}}, 1 Blueprint XML (1 reference)|
h2. Integration Test Analysis
h3. Summary

*Result:* None of the affected properties (excluding V2 compatibility mode) are 
modified dynamically in integration tests using {{{}updateConfiguration(){}}}.

However, one test configuration file uses the old router property names and 
will need to be updated when the renaming is implemented.
h3. Properties Modified Dynamically in Tests
h4. 1. V2CompatibilityModeIT.java (Already Fixed)
 * *Properties:* {{{}v2.compatibilitymode.enabled{}}}, 
{{v2.compatibilitymode.defaultTenantId}}
 * *Status:* Already updated to use new property names
 * *Impact:* None - already fixed

h4. 2. RuleServiceIT.java
 * *Property:* {{rules.optimizationActivated}} in {{org.apache.unomi.services}}
 * *Status:* NOT affected - this property is not in our conflict list
 * *Impact:* None

h4. 3. ProfileServiceIT.java
 * *Property:* {{throwExceptions}} in {{org.apache.unomi.persistence.*}}
 * *Status:* NOT affected - this is a persistence property, not in our conflict 
list
 * *Impact:* None

h3. Properties NOT Modified Dynamically

The following affected properties are *NOT* modified dynamically in integration 
tests:
 # *Migration:* {{recoverFromHistory}} - No tests modify this
 # *Router:* All 13 properties ({{{}kafka.host{}}}, {{{}kafka.port{}}}, etc.) - 
No tests modify these dynamically
 # *Cluster:* {{{}nodeId{}}}, {{nodeStatisticsUpdateFrequency}} - No tests 
modify these
 # *Plugins Base:* {{maxProfilesInOneMerge}} - No tests modify this
 # *Services:* {{segment.max.retries.update.profile.segment}} - No tests modify 
this

h3. Test Configuration Files That Need Updates
h4. Router Test Configuration File

*File:* {{itests/src/test/resources/org.apache.unomi.router.cfg}}

*Current properties (OLD names):*
{code:java}
router.config.type=nobroker
import.oneshot.uploadDir=${karaf.data}/tmp/unomi_oneshot_import_configs/
executionsHistory.size=5
executions.error.report.size=200
config.allowedEndpoints=file,ftp,sftp,ftps
{code}
*Will need to be updated to (NEW names):*
{code:java}
router.config.type=nobroker
router.import.oneshot.uploadDir=${karaf.data}/tmp/unomi_oneshot_import_configs/
router.executionsHistory.size=5
router.executions.error.report.size=200
router.config.allowedEndpoints=file,ftp,sftp,ftps
{code}
*Note:* This file is used in {{BaseIT.java}} line 525:
{code:java}
replaceConfigurationFile("etc/org.apache.unomi.router.cfg", new 
File("src/test/resources/org.apache.unomi.router.cfg")),
{code}
*Impact:* Low - Only need to update the test configuration file when 
implementing the router property renaming.
h3. Conclusion

*Good News:* No integration tests are currently broken by the Karaf override 
issue because:
 * Tests don't dynamically modify the affected properties
 * Tests that do modify properties use properties that are NOT affected

*Action Required:* When implementing the router property renaming, update the 
test configuration file 
{{itests/src/test/resources/org.apache.unomi.router.cfg}} to use the new 
property names with the {{router.}} prefix.
h2. Testing Plan

*Configuration Admin Tests:*
 # Verify {{config:property-set}} and {{config:update}} work for each affected 
component
 # Verify changes are persisted and applied to components
 # Verify {{@Modified}} methods receive updated values
 
*System Property Tests:*
 # Verify system properties no longer override Configuration Admin
 # Verify system properties still work for variable substitution in {{.cfg}} 
files

 *Integration Tests:*
 # Run existing integration tests
 # Add tests to verify Configuration Admin updates work correctly
 # Update {{itests/src/test/resources/org.apache.unomi.router.cfg}} when 
implementing router property renaming

h2. Migration Notes
 * *For Users:* No immediate action required. System properties in 
{{custom.system.properties}} will continue to work for variable substitution.
 * *For Administrators:* Configuration Admin commands will now work correctly. 
Old system properties can be removed from {{custom.system.properties}} if 
desired, but it's not required.
 * *Documentation:* Update configuration documentation to reflect new property 
names.

h2. References
 * Karaf Configuration Documentation: [Environment Variables & System 
Properties|https://karaf.apache.org/manual/latest/#_environment_variables_system_properties]



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to