Details
-
Bug
-
Status: Resolved
-
Resolution: Done
-
Helium
-
None
-
None
-
Operating System: All
Platform: All
-
1616
Description
In the distributed datastore, the operational and config data stores are separate modules but have the same configuration data. Instead of duplicating the config definitions I created a grouping to contain them, i.e.
grouping data-store-properties {
leaf max-shard-data-change-executor-queue-size
...
leaf max-shard-data-change-executor-pool-size
}
augment "/config:modules/config:module/config:configuration" {
// operation data store
...
container operational-properties
}
augment "/config:modules/config:module/config:configuration" {
// configuration data store
...
container config-properties { uses data-store-properties; }
}
In the initial config XML I didn't specify anything for operational-properties. This resulted in an exception emanating from CompositeAttributeResolvingStrategy#parseAttribute from this line:
Util.checkType(value, Map.class);
The error occurred for "operational-properties" when trying to get the default value (which should be null). The 'value' instance was a String with value "20" but the code expects a Map instance.
After debugging I tracked the bug to ObjectXmlReader#caseTOAttribute. This code runs for the "operational-properties" container and obtains the default value from the instance returned from getLastAttribute() which is set by the base class prior to calling caseTOAttribute. Prior to this, caseTOAttribute loops through and processes the entries for the inner leafs. However, these entries result in calls back into the base class which changes the instance returned from getLastAttribute(). So "operational-properties" ends up getting the default value for the last inner leaf ("20" in this case).
I was able to fix this by retrieving and storing getLastAttribute() in a local var at the beginning of ObjectXmlReader#caseTOAttribute. I also did the same for a couple other methods that could suffer the same issue. The use of getLastAttribute() seems fragile - this should probably get passed into the methods but that would require some refactoring.
I then ran into another problem with specifying partial config params in the XML. Eg, with this XML:
<operational-properties>
<max-shard-data-change-executor-queue-size>500</max-shard-data-change-executor-queue-size >
</operational-properties>
From the resulting OperationalProperties instance that's injected into the Module, I got the expected value of 500 from getMaxShardDataChangeExecutorQueueSize(). However getMaxShardDataChangeExecutorPoolSize() returned null - I should have gotten the default value 20.
This required a change in CompositeAttributeReadingStrategy#readElementHook to take the default value of the inner leaf if its XML value isn't specified.