How to configure an OsidManager: the XML file format, and the ways configuration files can be named, located, layered, and applied.
Kilimanjaro's built-in OSID Configuration Provider provides the runtime configuration for OSID Providers. The default OSID Configuration Provider is file-based to easily bundle configuration with a distribution artifact.
The purpose of the Kilimanjaro OSID Configuration Provider is to provide configuration services to OSID Providers. The Configuration OSID interfaces themselves can be used for all sorts of things but it does not mean that Kilimanjaro is the panacea of configuration services. In fact, nothing is. One-size fits all approaches create data swamps that don't serve anyone.
The principal audience for Kilimanjaro OSID Configuration is the person who is incorporating your OSID Provider into their application or system. The options described in more detail below give the integrator the flexibility of packaging, managing, operating, and tuning their application.
There may be top-level applications which can also use the Kilimanjaro OSID Configuration Service, especially for identifying which OSID Provider(s) it will load (keep in mind the Orchestration OSID to minimize the OSID Consumer touchpoint when needing many OSID Providers).
These are things to think about and not hard and fast rules. There's always grey area. The beauty of the OSID framework is that it allows the best fit to be applied rather than tossing everything into a single basket to get mediocrity which never quite gets there.
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<configuration xmlns="urn:inet:osid.org:schemas:providers/configuration/base/1"
lastmod="2010-01-29T16:25:00Z">
<displayName>Example Configuration</displayName>
<description>
<div>An example configuration to demonstrate the Base Configuration
OSID Provider.</div>
</description>
<parameter id="shouldThisWork" syntax="boolean">
<displayName>Work</displayName>
<description>
<div>A parameter to specify whether or not this code should
work.</div>
</description>
<value>
<boolean>true</boolean>
</value>
</parameter>
<parameter id="constant" syntax="float">
<displayName>The Constant</displayName>
<description>Constant numbers used to make our program look smart.</description>
<value>
<float>3.14159</float>
</value>
<value>
<float>42</float>
</value>
</parameter>
<parameter id="serverName" syntax="string">
<displayName>Server Name</displayName>
<description>The name of our database server.</description>
<value priority="1">
<string>www1.company.com</string>
</value>
<value priority="1">
<string>www2.company.com</string>
</value>
<value priority="10">
<string>backup.company.com</string>
</value>
</parameter>
<parameter id="language" syntax="type">
<displayName>Language</displayName>
<description>The locale type for what language we will speak.</description>
<value priority="1">
<type>urn:inet:osid.org:types:locale:language/English/US</type>
</value>
<value priority="2">
<type>urn:inet:osid.org:types:locale:language/French</type>
</value>
</parameter>
</configuration>
| Element / Attribute | Cardinality | Description |
|---|---|---|
configuration@lastmod | required | date or dateTime the file was last modified |
configuration@registry | optional | boolean - indicates if this Configuration exists to define Parameters only (a registry of parameters) or it also includes Values. Usually false (default). |
configuration > displayName | required | inline text/markup - the name of this Configuration |
configuration > description | required | block text/markup - a description of this Configuration |
configuration > parameter | 0 or more | list of Configuration Parameters |
parameter@id | required | string - identifier of the Parameter Id. The namespace and authority of the OSID Id is managed by the Kilimanjaro Configuration OSID Provider. |
parameter@syntax | required | one of boolean, byte, cardinal, coordinate, datetime, distance, float, id, integer, object, spatial, string, type |
parameter@shuffleValues | optional | boolean - if a Parameter has multiple Values, this flag indicates whether or not the Values will be shuffled on each retrieval (default false). |
parameter > displayName | required | inline text/markup - the name of this Parameter |
parameter > description | required | block text/markup - a description of this Parameter |
parameter > value | 0 or more | list of Values the Parameter |
value@priority | optional | integer - rank of the Value, lowest to highest, if there are multiple. Values will be returned in the order or the rank unless they are shuffled. |
value > path, rule | optional | schema-legal but not read by providers.configuration.base.Value.parse() — path-based selection is a separate mechanism, see below |
value > <syntax-typed element> | exactly 1 | the actual value, e.g. <string>, <integer>, <type>. This must match parameter@syntax. |
The Kilimanjaro Configuration OSID Provider owns the namespace and authority of the Parameter Ids. Thus in the file, a simple string (the identifier component) is specified. The Value Id is implicitly the Parameter Id plus the position it sits in the Parameter group (serverName#1).
A configuration file can be checked
against schemas/configuration.rnc using the validator
wrapper checked in alongside the schemas:
validate.sh runs
jing, to
validate configuration files against the schema definitions.
Every OsidRuntimeManager
carries an application context string — the value passed
to
BootLoader.getRuntimeManager(context). Configuration
Parameters specified in files whose name carries the
context string are given the highest priority to
give the application integrator the ability to override any
setting in their integration project. These files are fetched from
the classpath and if multiple files of the same name exist in the
classpath, the Classloader will select whichever one it sees first
(typically what is in your build before what is bundled in a
dependency).
The runtime configuration is primarily geared toward configuring OSID Provider implementations. The name of implementation, such as net.tom.providers.TomRepositoryManager or edu.mit.providers.PersonnelProxyManager, may have configuration files specific to their implementation. These are given second priority. It may be that default configurations are shipped with the jar file or it may be desired to associate some or all of an OSID Provider's configuration with the implementation itself.
Finally, there
is osid.xml. This is the catch-all behind the other
tiers. It exists to centralize OSID Provider configurations at a
lower priority to establish a baseline configuration. Perhaps
useful for shared Parameter Ids.
| Precedence | Source |
|---|---|
| Highest | <application context>.xml |
| ↕ | <OsidManager class>.xml |
| Lowest | osid.xml |
Again, these files are fetched as resources from the Classloader.
An application boots with context
"myApplication". It reads a parameter naming which
implementation to load next, that implementation's own file names
the next one down, and so on — a chain of managers, each with its
own configuration file, each one layer lower in precedence than
the one before it:
"myApplication"myApplication.xml — highest precedencecom.me.OrchestrationManager.xmlcom.me.CachingPersonnelManager.xmlorg.dxtera.DataPersonnelManager.xmlnet.okapia.CloudFilingManager.xml — lowest of this stackosid.xmlAnother setup, centralizing the adapter stack because you want to see them all in one place on an application by application basis.
"myApplication"myApplication.xml — highest precedencecom.me.OrchestrationManager.xmlcom.me.CachingPersonnelManager.xmlorg.dxtera.DataPersonnelManager.xmlnet.okapia.CloudFilingManager.xml — lowest of this stackosid.xmlAnother setup, not using any of the class-specific configuration files. Defaulting in osid.xml and allowing application config to override.
"myApplication"myApplication.xml — highest precedencecom.me.OrchestrationManager.xmlcom.me.CachingPersonnelManager.xmlorg.dxtera.DataPersonnelManager.xmlnet.okapia.CloudFilingManager.xml — lowest of this stackosid.xmlWhen a Parameter carries more
than one Value (like serverName in the
example above), value@priority decides the order they
come back in through
getApplicableValueByParameter() (what is on top)
and getApplicableValuesByParameter() (the entire
list). Priorities are in ascending order with the lowest
priorities (includes negative numbers) having the highest
priority. Values with the same priority are always shuffled.
If
(parameter@shuffleValues="true"), the Kilimanjaro
OSID Configuration Provider will randomize across all priority
levels using the priority level as a weight such that
higher priorities (lower numbers) will appear more often than
lower priorities. It uses
an Efraimidis-Spirakis
Reservoir Algorithm.
Worked example — priorities
-10, 0, 0, 2, 3, 4, 999. Lowest present is
-10, so the weights are shifted: 1 - (-10) =
11. Resulting exponents are 1, 11, 11, 13, 14, 15,
1010
| priority | exponent | weight | P(sorts first) |
|---|---|---|---|
| -10 | 1 | 1 | 71.5% |
| 0 | 11 | 1/11 | 6.5% |
| 0 | 11 | 1/11 | 6.5% |
| 2 | 13 | 1/13 | 5.5% |
| 3 | 14 | 1/14 | 5.1% |
| 4 | 15 | 1/15 | 4.8% |
| 999 | 1010 | 1/1010 | 0.07% |
Two implementations that each ask for a
Parameter of the same bare name will collide if that name is ever
defined twice for different purposes — say,
provider in
myApplication.xml, once selecting
com.me.OrchestrationManager for the application
itself, and once meant only for
com.me.CachingPersonnelManager's underlying
provider. The integrator will need to qualify one or both of
them.
A qualifier is the implementation class
name of whichever OsidManager is doing the asking (which also
happens to be the name of its own configuration file, the other
means to help separate Parameter definitions). Qualify a Parameter
identifier using the implementation class name
and |:
This is done behind the OSID Providers' backs. Each OSID Provider will see the Parameter identifier it was expecting to see, unqualified.
"myApplication"myApplication.xml — highest precedenceIt seems someone had too much time on their hands.
Applying Rules to Values adds more files. The <identifier> in the filenames correspond to the filename prefix in the general configuration -- the application context, OsidManager class, or osid.xml.
| File | Schema | Required | Holds |
|---|---|---|---|
<identifier>-rules.xml | rules-config.rnc | to enable any rule filtering at all | maps values to rule ids — only the time-rule mapping is actually read; path routing uses one fixed rule id and ignores this file's own path mapping entirely |
The <identifier>-rules.xml file specifies which Values any Rule applies. Values not listed in this file go through the normal path (no special rules apply) as described above.
The gotcha is that due to
the fact that the Rules OSID Provider is external to the
OSID Configuration Provider, the Value identifiers need to be
fully qualified OSID Ids. Id from the OSID
Configuration Provider assigns each value
(<parameterId>#<sequence>, authority
local, namespace configuration). Note the
Value Id below, referencing the third declared value of
serverName from the earlier example
(backup.company.com) — a single Value can also carry
more than one Rule reference, unlike the single-Rule-per-Value
shape in the time-rules example further down:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<engine xmlns="urn:inet:osid.org:schemas:providers/rules/configuration/1">
<displayName>Server Name Rules</displayName>
<description>Governs when the backup server value applies.</description>
<value id="configuration:serverName#3@local">
<rule id="rule:net.okapia.CloudFilingManager#maintenanceWindow@localhost"/>
<rule id="rule:net.okapia.CloudFilingManager#weekendOverflow@localhost"/>
</value>
</engine>
Check one against its schema the same
way — schemas/rules-config.rnc against
net.okapia.CloudFilingManager-rules.xml:
Now that a couple of Values are known to OSID Rules processing, we can define the Rules which go with them.
| File | Schema | Required | Holds |
|---|---|---|---|
<identifier>-time.xml | rules-time.rnc | only if using time rules | time-of-day, date, and weekday rules |
Time rules are used when Values may be applied at specific times relative to the date and time when it's evaluated. Three kinds of rules, each independently negatable:
| Element | Matches when |
|---|---|
<timeRange><start>/<end></timeRange> | the current time of day (GMT) falls in [start, end), as HH:mm:ss |
<dateRange><start>/<end></dateRange> | the current date falls strictly between start and end |
<dayOfWeek day="Monday"/> | today (GMT) is that weekday — full name, three-letter abbreviation, or single-letter form all work |
Check a file against the schema:
Terms wrap in a <term
op="and"|"or" negate="true"|"false">, which can nest
other <term> elements arbitrarily; a
<rule>'s own top-level terms are always AND'd
together. Here's a deterministic pair — one term that's always
true, one that's the same range negated, so the example doesn't
depend on what day or time it's actually read:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<engine xmlns="urn:inet:osid.org:schemas:providers/rules/time/1"
lastmod="2026-07-11T00:00:00Z">
<displayName>Cloud Filing Manager Time Rules</displayName>
<description>Deterministic always-true / always-false rules.</description>
<rule id="alwaysOpen">
<displayName>Always Open</displayName>
<description>A time range spanning the entire day.</description>
<term op="or">
<timeRange>
<start>00:00:00</start>
<end>23:59:59</end>
</timeRange>
</term>
</rule>
<rule id="alwaysClosed">
<displayName>Always Closed</displayName>
<description>The same all-day range, negated on the leaf term.</description>
<term op="or">
<timeRange negate="true">
<start>00:00:00</start>
<end>23:59:59</end>
</timeRange>
</term>
</rule>
<rule id="openBusinessHours">
<displayName>Open Business Hours</displayName>
<description>Monday through Friday, 9am to 5pm.</description>
<term op="and">
<timeRange>
<start>09:00:00</start>
<end>17:00:00</end>
</timeRange>
<term op="or">
<dayOfWeek day="Monday"/>
<dayOfWeek day="Tuesday"/>
<dayOfWeek day="Wednesday"/>
<dayOfWeek day="Thursday"/>
<dayOfWeek day="Friday"/>
</term>
</term>
</rule>
</engine>
openBusinessHours shows the
two composition rules together: a <term> can
hold more than one leaf directly (five dayOfWeek
children under one op="or", rather than five nested
single-child terms), and terms nest — the outer
op="and" requires both the time range and
the weekday in order to combine the weekday pattern with the
time.
Different Rules may be applied to different Values in a set of Values. The example below illustrates two simple messages, each intended to be applied to whether or not our 9-5 business is open.
<parameter id="businessHoursMessage" syntax="string">
<displayName>Business Hours Message</displayName>
<description>Two candidates, filtered by time.</description>
<value>
<string>Welcome</string>
</value>
<value>
<string>Closed, come back when we are open.</string>
</value>
</parameter>
And how the message Values are applied to the defined Rules, using complete OSID Ids:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<engine xmlns="urn:inet:osid.org:schemas:providers/rules/configuration/1">
<displayName>Cloud Filing Manager Rules</displayName>
<description>Maps businessHoursMessage's two values to their time rules.</description>
<value id="configuration:businessHoursMessage#1@local">
<rule id="rule:net.okapia.CloudFilingManager#alwaysOpen@localhost"/>
</value>
<value id="configuration:businessHoursMessage#2@local">
<rule id="rule:net.okapia.CloudFilingManager#alwaysClosed@localhost"/>
</value>
</engine>
| File | Schema | Required | Holds |
|---|---|---|---|
<identifier>-path.xml | rules-path.rnc | only if using path rules | path patterns, one per named rule |
Paths may be used to scope the application of a Value. A path is a set of components. Each component represents a layer (impl) in the OSID stack so the path is essentially the OSIDs in your stack from the application on down. These are specified in accompanying rules files.
Same requirement as the time example
above: the
-rules.xml enables the Path OSID Rule. However, for
some inconsistent, unknown reason, the Path Rules are
not named like the Time OSID Rules are. The consequence
is that we need a simple enable Path Rules file and the
paths are specified and applied in the path file directly.
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<engine xmlns="urn:inet:osid.org:schemas:providers/rules/configuration/1">
<displayName>Cloud Filing Manager Rules</displayName>
<description>Required so the rules session for this file constructs at all.</description>
</engine>
This is what a path specifier looks like:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<engine xmlns="urn:inet:osid.org:schemas:providers/rules/path/1">
<displayName>Personnel Path Rules</displayName>
<description>Picks a filing directory by caller path.</description>
<rule id="cloudFilingDirectory-by-path">
<value id="configuration:cloudFilingDirectory#1@local">
<path>
<component name="myApplication"/>
<component name="com.me.OrchestrationManager"/>
<component name="*"/>
<component name="net.okapia.CloudFilingManager"/>
</path>
</value>
</rule>
</engine>
What the above example says is apply this Value to a net.okapia.CloudFilingManager used by any OSID Provider or set of OSID Providers which is/are used by the com.me.OrchestrationManager and in turn is used by myApplication.
Again, the Rule needs to reference the
Value by its full Id, not just the bare
<parameterId>#<sequence>.
Check a file against
rules-path.rnc the same way as the others:
I apologize for this.
If you want to manage your runtime configuration in another data store, you can replace it.
Set the system property
kilimanjaro.configuration.impl to the classname of an
alternate org.osid.configuration.ConfigurationManager
before the root runtime boots:
It needs to support
a ValueLookupSession. Specifically:
supportsValueLookup(),
getValueLookupSession(), and
getValueLookupSessionForConfiguration(Id). The
replacement doesn't need to be file-based at all; a database- or
remote-backed ConfigurationManager works fine.
Your OSID Configuration Provider will be
used for Parameter & Value persistence and Kilimanjaro will
continue to handle the ValueRetrievalSession applying
the Values to OsidManagers and other Rules.
You can also supply an OSID Configuration Federating Adapter to have the flexibility of pulling parts of configurations from more than one location.