Develop > Application Configuration > CML reference > Sequence aggregation

Sequence aggregation

Because Application Configuration values can be set across many different levels in the Application Configuration inheritance hierarchy (also referred to as the inheritance scope), it is important that you be able control the way multiple sequence values are merged together when you push an Application Configuration on to a server.

ACM allows you to control the way sequence values are merged across inheritance scopes. This means that you can, for example, add some values to a sequence in the Customer scope, Group scope, and the Server scope, and all the values will be merged together to form the final sequence.

The manner in which sequence values are merged is controlled by special tags in the CML template, using three different sequence merge modes:

  • Sequence replace : Sequence values from more specific scopes completely replace those from less specific scopes. This occurs for both sequences of sets and lists.
  • Sequence append : For lists, values at more general scopes are appended (placed after) to those at more specific scopes. Duplicates, if present, are not removed. For sets, the behavior is the same, except duplicates are merged. For lists, duplicates are identified according to child elements marked with the primary-key tag, and then merged. For scalars, this is done by simply removing duplicate values, leaving only the value from the most specific scope (the last occurrence is the merged sequence). This is the default mode, and will be used if nothing else is specified.
  • Sequence Prepend: Works the same as append, but values at more general scopes are prepended (placed before) to those at more specific scopes.

For example, with these two sets:

  • “a, b” — At a more specific (inner) level of the inheritance scope, for example, server instance level.
  • “c, d” — At a more general (outer) of the inheritance scope, for example, the server group level.

When the application configuration template is pushed onto the server, the merging results would be:

  • Sequence replace: “a, b”
  • Sequence append: “a, b, c, d”
  • Sequence prepend: “c, d, a, b”

Sequence aggregation occurs not only between scopes, but also within a scope itself. This is evident if there are duplicate values within a sequence of name spaces.

Sequence replace

In the Replace merge mode (CML tag “sequence-replace”), the contents of a sequence defined at a particular scope replace those of less specific scopes, and no merging is performed on the individual elements of the sequence.

For example, if the sequence-replace tag has been set for a list in an configuration template CML source, then values set for that list at the server instance level will override, or replace, those set at the group level and at the Application Configuration default values level.

For example, if a list in an etc/hosts file was defined at the group level (outer) as the following:

/system/dns/host/1/ip		           127.0.0.1
/system/dns/host/1/hostnames/1  localhost
/system/dns/host/1/hostnames/2  mymachine
/system/dns/host/2/ip           10.10.10.10
/system/dns/host/2/hostnames/1  loghost

 

And the same list was defined at the device scope (inner), as the following:

/system/dns/host/1/ip           127.0.0.1
/system/dns/host/1/hostnames/1  localhost
/system/dns/host/1/hostnames/2  mymachine.mydomain.net
/system/dns/host/2/ip           10.10.10.100
/system/dns/host/2/hostnames/1  mailserver

 

If template had defined the /system/dns/host element with the sequence-replace tag, the final results of the configuration file on the server after the push would be:

127.0.0.1 localhost mymachine.mydomain.net
10.10.10.100 mailserver

Sequence append

When the append list merge mode (CML tag “sequence-append”) is used for sequences, the values at more general scopes are appended (placed after) those of more specific scopes. Sequence append mode is the default mode for merging list values. If nothing is specified in the CML of the template, the sequence append will be used.

If a list in an etc/hosts file was defined at the group level (outer) as the following:

/system/dns/host/1/ip		           127.0.0.1
/system/dns/host/1/hostnames/1  localhost
/system/dns/host/1/hostnames/2  mymachine
/system/dns/host/2/ip           10.10.10.10
/system/dns/host/2/hostnames/1  loghost

 

And the same list was defined at the device scope (inner), as the following:

/system/dns/host/1/ip           127.0.0.1
/system/dns/host/1/hostnames/1  localhost
/system/dns/host/1/hostnames/2  mymachine.mydomain.net
/system/dns/host/2/ip           10.10.10.100
/system/dns/host/2/hostnames/1  mailserver

 

Using the value sets from the above example, if the /system/dns/host element was a list with the sequence-append tag set in the configuration template, the final results of the configuration file on the server after the push would be:

127.0.0.1 localhost mymachine.mydomain.net
10.10.10.100 mailserver
127.0.0.1 localhost mymachine
10.10.10.10 loghost

But since it is not allowable for a hosts file to contain duplicate entries, the/system/dns/host element will have to be flagged in the configuration template as a set rather than a list, because sets do not allow duplicates. To avoid duplication of the list values in the example, the configuration template author would use the Primary Key option.

Primary key option in sequence merging

When operating in append mode on sets, new values in more specific scopes are appended to those of less specific ones, and duplicate values are merged with the resulting value placed in the resulting sequence according to its position in the more specific scope.

How this affects merged sequence values depends on what kind of data is contained in the sequence:

  • For elements in a sequence which are scalars, the value from the most specific scope is used. In other words, values at the server instance level would replace the values at the group level.
  • For elements which are namespace sequences, the value is obtained by applying the merge mode specified for that element (in this example, append) based upon matching up the primary fields.

To avoid the duplication of the /system/dns/host/.ip value, the configuration template author would use the CML primary-key option. With this option set, ACM will treat entries with the same value for /system/dns/host/.ip as the same and merge their contents.

In the example above, the final results of the configuration file on the server after the push would be:

127.0.0.1 localhost mymachine.mydomain.net mymachine
10.10.10.100 mailserver
10.10.10.10 loghost

Note
Since it is possible to have a set without primary keys, if there are scalars in the sequence, then an aggregation of all scalar values will be used as the primary key. If there are no scalars, then the aggregation of all values in the first sequence will be used as the primary key. Although this is an estimate, in most cases the values will be merged effectively. To ensure that the correct values are used as primary keys, we recommend that you always explicitly set the primary key in a sequence.

Sequence prepend

When the prepend list merge mode (CML tag “sequence-prepend”) is used for sequences, the values at more general scopes are prepended (placed before) those of more specific scopes.

For example, if a sequence in an etc/hosts file was defined at the group level (outer) as the following:

/system/dns/host/1/ip           127.0.0.1
/system/dns/host/1/hostnames/1 localhost
/system/dns/host/1/hostnames/2 mymachine
/system/dns/host/2/ip 10.10.10.10
/system/dns/host/2/hostnames/1 loghost

And the same sequence was defined at the device scope (inner), as the following:

/system/dns/host/1/ip 127.0.0.1
/system/dns/host/1/hostnames/1 localhost
/system/dns/host/1/hostnames/2 mymachine.mydomain.net
/system/dns/host/2/ip 10.10.10.100
/system/dns/host/2/hostnames/1 mailserver

If the /system/dns/host element was a set with the sequence-prepend tag set in the configuration template, the final results of the configuration file on the server after the push would be:

10.10.10.10 loghost
127.0.0.1 mymachine localhost mymachine.mydomain.net
10.10.10.100 mailserver

CML grammar

The following table describes CML grammar illustrating several types of CML tags.

CML grammar

CML tag/element

Description

replace-tag

"@" source [ ";" [ type ] [ ";" [ range ] *option ] ] "@"

data-definition-tag

"@~" source CRLF *def-line "@"

conditional-tag

"@" [ group-level ] "?" source [ ";" [ type ] [ ";" [ range ] *option ] ] "@"

loop-tag

“@" [ group-level ] "*" source [ ";" [ type ] [ ";" [ range ] *option ] ] "@"

loop-target-tag

"@.@"

block-tag

"@" [ group-level ] "[" *option "@"

block-termination-tag

"@" [ group-level ] "]@"

line-continuation-tag

"@\"

instruction-tag

"@!" *option "@"

single-line-comment

"@#" [ string CRLF ]

multi-line-comment

"@##" *[ string / CRLF ] "#@"

def-line

type-line / range-line / option-line / printable-line / desc-line

type-line

"type" WSP "=" WSP type-elem CRLF

range-line

"range" WSP "=" WSP range CRLF

option-line

option-elem CRLF

printable-line

"printable" WSP "=" WSP string CRLF

desc-line

"description" WSP "=" *[ WSP string CRLF ]

group-level

int

source

absolute-path / relative-path / local-path

absolute-path

"/" path-component* name

relative-path

[ path-component* ] name

path-component

( name / sequence-id ) "/"

sequence-id

int

local-path

"." name

name

string

type

sequence / type-elem

sequence

[ order "-" ] type-elem "-" sequence-elem

sequence-elem

"set" / "list"

type-elem

"int" / "string" / "ip" / "port" / "file" / etc...

order

ordered" / "unordered"

range

and-range *[ "," and-range ]

and-range

range-elem *[ "&" range-elem ]

range-elem

numeric-range / string range

numeric-range

gt-range / ge-range / lt-range / le-range / eq-range

string range

string-literal / regular-exp

gr-range

int ">"

ge-range

int ">="

lt-range

">" int

le-range

">=" int

eq-range

"=" int

string-literal

<"> string <">

regular-exp

"r" <"> string <">

option

";" option-elem

option-elem

option-name / option-nv

option-nv

option-nv

option-name

string

option-value

string