Develop > Application Configuration > CML primer > Use case 1 - Simple Key=Value Configuration File

Use case 1 - Simple Key=Value configuration file

The simplest type of configuration file has one or more Key = Value entries as in the following example:

Port = 1280
IPAddress = 192.168.0.1
ServerName = server01

In this configuration file, types and descriptions are easy to figure out.

Using the Replace instruction

To write a template for this configuration file, use a CML tag to represent where the value exists and where it will be stored in the value set name space. The tag for this is the Replace tag.

The replace tag is composed of several fields and, as with all tags in the CML language, it begins and ends with the “@” symbol and the fields are separated by semicolons. The form looks something like this:

@ <name> ; [type] ; [range] ; [option] ; [option] … @

Of all the fields, only the <name> field is required. So the most basic CML that could represent the configuration file above would be:

@!namespace=/example/namespace/@
@!filename-key=/files/example@
@!filename-default=/etc/example@
Port = @port@
IPAddress = @ipaddress@
ServerName = @servername@

This specifies that the value for the port number will be stored in the SA database at the key “/example/namespace/port”. The IP address will be stored at the key “/example/namespace/ipaddress” and the server name at the key “/example/namespace/servername”.

This would technically work, but you would be missing a lot of the field validation and error checking available that prevents entering invalid data such as “someport” for the port, for example.

The <name> field in the Replace instruction tag

If the <name> field is relative (that is, it does not start with a “/” or a “.”) it gets appended to the current name space and becomes part of the key used to store the value read from the SA database by this tag.

If the name is absolute (that is, it starts with a “/”) it is the entire key and the value gets stored under this key.

Finally, if the name starts with a dot “.”, it will be appended to the name space of whatever loop it is a part of. With very few exceptions, every tag inside a loop should start with a dot, “.”.

The <type> field in the Replace instruction tag

The <type> field lets you assign certain predefined ranges and error checking to different values, based on well-known types. For the full list of types, see CML type attributes. For this configuration file, use the predefined types “port,” “ip” and “hostname” for the separate entries, as follows:

@!namespace=/example/namespace/@
@!filename-key=/files/example@
@!filename-default=/etc/example@
Port = @port;port@
IPAddress = @ipaddress;ip@
ServerName = @servername;hostname@

Adding these types restricts the values and provides validation and error checking.

You can also use the replace tag to represent a sequence of repeating values by prepending “ordered-” or “unordered-” and appending “-set” or “-list”. More on this in the next example.

The default for this field is “string”, which will match anything.

The <range> field in the Replace instruction tag

The <range> field allows you to set the allowable range for the values. You can set either integer ranges or string ranges. Integer ranges are valid for any type that consists of strictly integers, string ranges are valid for all other types.

Ranges can be combined with logical OR by using a comma, “,”. Ranges can be combined with logical AND by using the ampersand character, “&”. The “!” character negates the range.

Keep in mind that the specified ranges will be used when reading in a configuration file as well as when accepting values from the SA Client. If you have a configuration file that has a value outside of the ranges you set in the template, then an error will be given when parsing that file. Specify the valid ranges based on the documentation for the configuration file.

Integer ranges

Integer ranges can only use the < and the = symbols to specify “less than” or “greater than” ranges. Specify the position of the number used in the comparison as follows:

Specifying integer ranges

Range condition

Symbols to use

Greater than

n<

Greater than or equal

n<=

Less than

<n

Less than or equal

<=n

Equal

=n

For example, if the ports in the configuration file can only be between 1024 and 2048 inclusive, you would add the ranges to the tag like this:

Port = @port;port;1024<=&<=2048@

String ranges

String ranges can be a list of valid strings surrounded by quotes and a list of regular expressions starting with the characters r” and ending with a quote. For example, if the ServerName field can only be anything starting with the word “server”, you would want to add the ranges to the servername tag like this:

ServerName = @servername;hostname;r"server.*”@

The [option] fields in the Replace instruction tag

You may append as many options as you need to the tag. Everything after the third semicolon is considered an option and every option is separated by semicolons.

For example, if the IPAddress line in the configuration file is optional and not required to make the configuration file valid, and the IP address could stop at a forward-slash, you could add the option like this:

IPAddress = @ipaddress;ip;;optional;delimiter="/"@

This would match the following entry:

IPAddress = 192.168.0.1

It would also match the following entry:

IPAddress = 192.168.0.2/

Notice that the range field is left empty. Any fields you want to leave as default must still be represented if you want to fill in any later fields. For instance, the following two lines are valid:

@ipaddress@

@ipaddress;;;optional@

However, the following is not valid because the field “optional” will be interpreted as the <type> field rather than as an option and will result in an error.

@ipaddress;optional@

Final CML template

After all the types, options and ranges are set, the CML template should look something like this:

@!namespace=/example/namespace/@
@!filename-key=/files/example@
@!filename-default=/etc/example@
Port = @port;port;1024<=&<=2048@
IPAddress = @ipaddress;ip;;optional;delimiter="/"@
ServerName = @servername;hostname;r"server.*"@

Resulting value set

Using the above configuration template to read in the example target configuration file from above will result in the following value set stored in the SA database:

/example/namespace/port = 1280
/example/namespace/ipaddress = 192.168.0.1
/example/namespace/servername = server01

As you can see, the keys in the name space are a combination of the template's name space
(/example/namespace) and each individual tag's name, since they all use relative names.