aboutsummaryrefslogtreecommitdiffstats
path: root/lib/cosNotification/doc/src/ch_BNF.xml
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/cosNotification/doc/src/ch_BNF.xml
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/cosNotification/doc/src/ch_BNF.xml')
-rw-r--r--lib/cosNotification/doc/src/ch_BNF.xml456
1 files changed, 456 insertions, 0 deletions
diff --git a/lib/cosNotification/doc/src/ch_BNF.xml b/lib/cosNotification/doc/src/ch_BNF.xml
new file mode 100644
index 0000000000..545280a1f4
--- /dev/null
+++ b/lib/cosNotification/doc/src/ch_BNF.xml
@@ -0,0 +1,456 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Filters and the Constraint Language BNF</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date>2000-04-13</date>
+ <rev></rev>
+ <file>ch_BNF.xml</file>
+ </header>
+
+ <section>
+ <title>Filters and the Constraint Language BNF</title>
+ <p>This chapter describes, the grammar supported by
+ <seealso marker="CosNotifyFilter_Filter">CosNotifyFilter_Filter</seealso> and
+ <seealso marker="CosNotifyFilter_MappingFilter">CosNotifyFilter_MappingFilter</seealso>,
+ and how to create and use filter objects.
+ </p>
+
+ <section>
+ <title>How to create filter objects</title>
+ <p>To be able to filter events we must create a filter and associate
+ it with one, or more, of the administrative or proxy objects. In the example
+ below, we choose to associate the filter with a ConsumerAdmin object.</p>
+ <code type="none">
+FilterFactory = cosNotificationApp:start_filter_factory(),
+Filter = 'CosNotifyFilter_FilterFactory':
+ create_filter(FilterFactory,"EXTENDED_TCL"),
+ConstraintInfoSeq = 'CosNotifyFilter_Filter':
+ add_constraints(Filter, ConstraintExpSeq),
+FilterID = 'CosNotifyChannelAdmin_ConsumerAdmin':
+ add_filter(AdminConsumer, Filter),
+ </code>
+ <p><c>"EXTENDED_TCL"</c> is the only grammar supported by Orber Notification
+ Service.</p>
+ <p>Depending on which operation type the Admin object uses, i.e.,
+ <c>'AND_OP'</c> or <c>'OR_OP'</c>, events will be tested using the
+ associated filter. The operation properties are:</p>
+ <p></p>
+ <list type="bulleted">
+ <item>
+ <p>'AND_OP' - must be approved by the proxy's <em>and</em> its parent admin's
+ filters. If all filters associated with an object (Admin or Proxy)
+ return false the event will be discarded. In this situation it is pointless
+ to try and verify with the other object's associated filters since the outcome
+ still would be the same.</p>
+ </item>
+ <item>
+ <p>'OR_OP' - if one of the object's (Admin or Proxy) filters return true, the event
+ will not be checked against any other filter associated with a proxy or its
+ parent admin. If a object's associated filters all return false,
+ the event will be forwarded to related proxies/admins, and
+ tested against any associated filters.</p>
+ </item>
+ </list>
+ <p>Initially, filters are empty and will always return true. Hence, we must
+ add constraints by using <c>'CosNotifyFilter_Filter':add_constraints/2</c>.
+ As input, the second argument must be a sequence of:</p>
+ <code type="none">
+#'CosNotifyFilter_ConstraintExp'{
+ event_types = [#'CosNotification_EventType'{
+ domain_name = string(),
+ type_name = string()}],
+ constraint_expr = string()}
+ </code>
+ <p>The <c>event_types</c> describes which types of events that should be matched using
+ the associated <c>constraint_expr</c>.</p>
+ <p>If a constraint expression is supposed to apply for all events, then the <c>type_name</c> can
+ be set to the special event type <c>%ALL</c> in a constraint's event type sequence. The
+ <c>domain_name</c> should be <c>""</c> or <c>"*"</c>.</p>
+ <p>In the following sections we will take a closer look on how to write
+ constraint expressions.</p>
+ </section>
+
+ <section>
+ <title>The CosNotification Constraint Language</title>
+ <p>The constraint language supported by the Notification Service is:</p>
+ <code type="none"><![CDATA[
+<constraint> := /* empty */
+ | <bool>
+
+<bool> := <bool_or>
+
+<bool_or> := <bool_or> or <bool_and>
+ | <bool_and>
+
+<bool_and> := <bool_and> and <bool_compare>
+ | <bool_compare>
+
+<bool_compare> := <expr_in> == <expr_in>
+ | <expr_in> != <expr_in>
+ | <expr_in> < <expr_in>
+ | <expr_in> <= <expr_in>
+ | <expr_in> > <expr_in>
+ | <expr_in> >= <expr_in>
+ | <expr_in>
+
+<expr_in> := <expr_twiddle> in <Ident> /* sequence only */
+ | <expr_twiddle>
+ | <expr_twiddle> in $ <Component> /* sequence only */
+
+<expr_twiddle> := <expr> ~ <expr> /* string data types only */
+ | <expr>
+
+<expr> := <expr> + <term>
+ | <expr> - <term>
+ | <term>
+
+<term> := <term> * <factor_not>
+ | <term> / <factor_not>
+ | <factor_not>
+
+<factor_not> := not <factor>
+ | <factor>
+
+<factor> := ( <bool_or> )
+ | exist <Ident>
+ | <Ident>
+ | <Number>
+ | - <Number>
+ | <String>
+ | TRUE
+ | FALSE
+ | + <Number>
+ | exist $ <Component>
+ | $ <Component>
+ | default $ <Component> /* discriminated unions only */
+
+<Component> := /* empty */
+ | . <CompDot>
+ | <CompArray>
+ | <CompAssoc>
+ | <Ident> <CompExt> /* run-time variable */
+
+<CompExt> := /* empty */
+ | . <CompDot>
+ | <CompArray>
+ | <CompAssoc>
+
+<CompDot> := <Ident> <CompExt>
+ | <CompPos>
+ | <UnionPos>
+ | _length /* only valid for arrays or sequences */
+ | _d /* discriminated unions only */
+ | _type_id /* only valid if possible to obtain */
+ | _repos_id /* only valid if possible to obtain */
+
+<CompArray> := [ <Digits> ] <CompExt>
+
+<CompAssoc> := ( <Ident> ) <CompExt>
+
+<CompPos> := <Digits> <CompExt>
+
+<UnionPos> := ( <UnionVal> ) <CompExt>
+
+<UnionVal> := /* empty */
+ | <Digits>
+ | - <Digits>
+ | + <Digits>
+ | <String>
+
+/* Character set issues */
+<Ident> :=<Leader> <FollowSeq>
+ | \\ < Leader> <FollowSeq>
+
+<FollowSeq> := /* <empty> */
+ | <FollowSeq> <Follow>
+
+<Number> := <Mantissa>
+ | <Mantissa> <Exponent>
+
+<Mantissa> := <Digits>
+ | <Digits> .
+ | . <Digits>
+ | <Digits> . <Digits>
+
+<Exponent> := <Exp> <Sign> <Digits>
+
+<Sign> := +
+ | -
+
+<Exp> := E
+ | e
+
+<Digits> := <Digits> <Digit>
+ | <Digit>
+
+<String> := ' <TextChars> '
+
+<TextChars> := /* <empty> */
+ | <TextChars> <TextChar>
+
+<TextChar> := <Alpha>
+ | <Digit>
+ | <Other>
+ | <Special>
+
+<Special> := \\\\
+ | \\'
+
+<Leader> := <Alpha>
+
+<Follow> := <Alpha>
+ | <Digit>
+ | _
+
+<Alpha> is the set of alphabetic characters [A-Za-z]
+<Digit> is the set of digits [0-9]
+<Other> is the set of ASCII characters that are not <Alpha>, <Digit>, or <Special>
+ ]]></code>
+ <p>In the absence of parentheses, the following precedence relations hold :</p>
+ <list type="ordered">
+ <item><c>()</c>, <c>exist</c>, <c>default</c>, <c>unary-sign</c></item>
+ <item><c>not</c></item>
+ <item><c>*</c>, <c>/</c></item>
+ <item><c>+</c>, <c>-</c></item>
+ <item><c>~</c></item>
+ <item><c>in</c></item>
+ <item><c>==</c>, <c>!=</c>, <c><![CDATA[<]]></c>, <c><![CDATA[<=]]></c>, <c>></c>, <c>>=</c></item>
+ <item><c>and</c></item>
+ <item><c>or</c></item>
+ </list>
+ </section>
+
+ <section>
+ <title>The Constraint Language Data Types</title>
+ <p>The Notification Service Constraint Language, defines how to write
+ constraint expressions, which can be used to filter events. The
+ representation does, however, differ slightly from ordinary Erlang terms.</p>
+ <p>When creating a <c>ConstraintExp</c>, the field <c>constraint_expr</c> must be
+ set to contain a string, e.g., <c><![CDATA["1 < 2"]]></c>. The Notification Service Constraint
+ Language, is designed to be able to filter structured and unstructured events
+ using the same constraint expression. The Constraint Language Types and Operations
+ can be divided into two sub-groups:</p>
+ <list type="bulleted">
+ <item>
+ <p>Basic - arithmetics, strings, constants, numbers etc.</p>
+ </item>
+ <item>
+ <p>Complex - accessing members of complex data types, such as unions.</p>
+ </item>
+ </list>
+ <p>Some of the basic types, e.g., integer, are self explanatory. Hence, they are not described further.</p>
+ <table>
+ <row>
+ <cell align="center" valign="middle"><em>Type/Operation</em></cell>
+ <cell align="center" valign="middle"><em>Examples</em></cell>
+ <cell align="center" valign="middle"><em>Description</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>string</c></cell>
+ <cell align="left" valign="middle"><c>"'MyString'"</c></cell>
+ <cell align="left" valign="middle">Strings are represented as a sequence of zero or more <c><![CDATA[<TextChar>]]></c>s enclosed in single quotes, e.g., <c>'string'</c>.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>~</c></cell>
+ <cell align="left" valign="middle"><c>"'Sring1' ~ 'String2'"</c></cell>
+ <cell align="left" valign="middle">The operator <c>~</c>is called the substring operator and mean "String1 is contained within String2".</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>boolean</c></cell>
+ <cell align="left" valign="middle"><c>"TRUE == (('lang' ~ 'Erlang' + 'fun' ~ 'functional') >= 2)"</c></cell>
+ <cell align="left" valign="middle">Booleans may only be TRUE or FALSE, i.e., only capital letters. Expressions which evaluate to TRUE or FALSE can be summed up and matched, where TRUE equals 1 and FALSE 0.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>sequence</c></cell>
+ <cell align="left" valign="middle"><c>"myIntegerSequence[2]"</c></cell>
+ <cell align="left" valign="middle">The BNF use C/C++ notation, i.e., the example will return the <em>third</em>element.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>_length</c></cell>
+ <cell align="left" valign="middle"><c>"myIntegerSequence._length"</c></cell>
+ <cell align="left" valign="middle">Returns the length of an sequence or array.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>in</c></cell>
+ <cell align="left" valign="middle"><c>"'Erlang' in $.FunctionalLanguages&shy;StringSeq"</c></cell>
+ <cell align="left" valign="middle">Returns <c>TRUE</c>if a given element is found in the given sequence. The element must be of a simple type and the same as the sequence is defined to contain.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>$</c></cell>
+ <cell align="left" valign="middle"><c>"$ == 40"</c></cell>
+ <cell align="left" valign="middle">Denote the current event as well as any run-time variables. If the event is unstructured and its contained value 40, the example will return <c>TRUE</c>.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>.</c></cell>
+ <cell align="left" valign="middle"><c>"$.MyStructMember == 40"</c></cell>
+ <cell align="left" valign="middle">The structure member operator <c>.</c>may be used to reference its members when the data refers to a named structure, discriminated union, or CORBA::Any data structure.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>_type_id</c></cell>
+ <cell align="left" valign="middle"><c>"$._type_id == 'MyStruct'"</c></cell>
+ <cell align="left" valign="middle">Returns the unscoped IDL type name of the component. This operation is only valid if said information can be obtained.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>_repos_id</c></cell>
+ <cell align="left" valign="middle"><c>"$._repos_id == 'IDL:MyModule/MyStruct:1.0'"</c></cell>
+ <cell align="left" valign="middle">Returns the RepositoryId of the component. This operation is only valid if said information can be obtained.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>_d</c></cell>
+ <cell align="left" valign="middle"><c>"$.eventUnion._d"</c></cell>
+ <cell align="left" valign="middle">May only be used when accessing discriminated unions and refers to the discriminator.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>exist</c></cell>
+ <cell align="left" valign="middle"><c>"exist $.eventUnion._d and $.eventUnion._d == 10"</c></cell>
+ <cell align="left" valign="middle">To avoid that a filtering of an event fails due to that, for example, we try to compare a union discriminator which does not exist, we can use this operator.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>default</c></cell>
+ <cell align="left" valign="middle"><c>"default $.eventUnion._d"</c></cell>
+ <cell align="left" valign="middle">If the <c>_d</c>operation is in conjunction with the <c>default</c>operation, TRUE will be returned if the union has a default member that is active.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>union</c></cell>
+ <cell align="left" valign="middle"><c>"$.(0) == 5"</c>eq. <c>"$.('zero') == 5"</c></cell>
+ <cell align="left" valign="middle">When the component refers to a union, with one of the cases defined as <c>case 0: short zero;</c>, we use <c>0</c>or <c>'zero'</c>. The result of the example is <c>TRUE</c>if the union has a discriminator set to <c>0</c>and the value <c>5</c>. If more than one case is defined to be<c>'zero'</c>, <c>$.('zero')</c>accepts both; <c>$.(0)</c>only returns <c>TRUE</c>if the discriminator is set to <c>0</c>. Leaving out the identifier, i.e., <c>$.()</c>, refers to the default value.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>name-value pairs</c></cell>
+ <cell align="left" valign="middle"><c>"$.NameValueSeq('myID') == 5"</c>eq.<c>"$.NameValueSeq[1].name == 'myID' and $.NameValueSeq[1].value == 5"</c></cell>
+ <cell align="left" valign="middle">The Notification service makes extensive use of <c>name-value pairs</c>sequences within structured events, which allow us to via the identifier <c>name</c>access its <c>value</c>, as shown in the example.</cell>
+ </row>
+ <tcaption>Table 1: Type and Operator Examples</tcaption>
+ </table>
+ <p>In the next section we will take a closer look at how it is possible to write constraints using
+ different types of notation etc.</p>
+ </section>
+
+ <section>
+ <title>Accessing Data In Events</title>
+ <p>To filter events, the supplied constraints must describe the contents of
+ the events and desired values. We can, for example, state that we are only
+ interested in receiving events which are of type <em>CommunicationsAlarm</em>.
+ To be able to achieve this, the constraint must contain information
+ that points out which fields to compare with. Figure one illustrates a conceptual overview of a
+ structured event. The exact definition is found in the <c>CosNotification.idl</c> file.</p>
+ <marker id="eventstructure"></marker>
+ <image file="eventstructure.gif">
+ <icaption>
+Figure 1: The structure of a structured event.</icaption>
+ </image>
+ <p>The Notification Service supports different constraint expressions
+ notation:</p>
+ <list type="bulleted">
+ <item>
+ <p>Fully scoped, e.g., "$.header.fixed_header.event_type.type_name == 'CommunicationsAlarm'"</p>
+ </item>
+ <item>
+ <p>Short hand, e.g., "$type_name == 'CommunicationsAlarm'"</p>
+ </item>
+ <item>
+ <p>Positional Notation, e.g., "$.0.0.0.1 == 'CommunicationsAlarm'"</p>
+ </item>
+ </list>
+ <note>
+ <p>Which notation to use is up to the user, however, the fully scoped may
+ be easier to understand, but in some cases, if received from an ORB that do not populate ID:s of
+ named parts, the positional notation is the only option.</p>
+ </note>
+ <note>
+ <p>If a constraint, which access fields in a structured event structure,
+ is supposed to handle unstructured events as well, the CORBA::Any must contain
+ the same type of members.</p>
+ </note>
+ <p>How to filter against the fixed header fields, is described in the
+ table below.</p>
+ <table>
+ <row>
+ <cell align="center" valign="middle">Field</cell>
+ <cell align="center" valign="middle">Fully Scoped Constraint</cell>
+ <cell align="center" valign="middle">Short Hand Constraint</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">type_name</cell>
+ <cell align="left" valign="middle">"$.header.fixed_header.event_&shy;type.type_name == 'Type'"</cell>
+ <cell align="left" valign="middle">"$type_name == 'Type'"</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">domain_name</cell>
+ <cell align="left" valign="middle">"$.header.fixed_header.event_&shy;type.domain_name == 'Domain'"</cell>
+ <cell align="left" valign="middle">"$domain_name == 'Domain'"</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">event_name</cell>
+ <cell align="left" valign="middle">"$.header.fixed_header.event_&shy;name == 'Event'"</cell>
+ <cell align="left" valign="middle">"$event_name == 'Event'"</cell>
+ </row>
+ <tcaption>Table 2: Fixed Header Constraint Examples</tcaption>
+ </table>
+ <p>If we are only interested in receiving events regarding 'Domain', 'Event'
+ and 'Type', the constraint can look like
+ <c>"$domain_name == 'Domain' and $event_name == 'Event' and $type_name == 'Type'"</c>.</p>
+ <p>The variable event header consists of a sequence of <em>name-value pairs</em>. One way to filter on these are to use a constraint that looks
+ like <c>"($.header.variable_header[1].name == 'priority' and $.header.variable_header[1].value > 0)"</c>. An easier way to
+ accomplish the same result is to use a constraint that treats the name-value
+ pair as an associative array, i.e., when given a name the corresponding
+ value is returned. Hence, instead we can use
+ <c>"$.header.variable_header(priority) > 0"</c>.</p>
+ <p>Accessing the event body is done in the same way as for the event header
+ fields. The user must, however, be aware of, that if a run-time variable
+ (<c>$variable</c>) is used data in the event header may take precedence.
+ The order of precedence is:</p>
+ <list type="ordered">
+ <item>Reserved, e.g., <c>$curtime</c></item>
+ <item>A simple-typed member of <c>$.header.fixed_header</c>.</item>
+ <item>Properties in <c>$.header.variable_header</c>.</item>
+ <item>Properties in <c>$.filterable_data</c>.</item>
+ <item>If no match is found it is translated to <c>$.variable</c>.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Mapping Filters</title>
+ <p>Mapping Filters may only be associated with Consumer Administrators or Proxy
+ Suppliers. The purpose of a Mapping Filter is to override Quality of Service
+ settings.</p>
+ <p>Initially, Mapping Filters are empty and will always return true. Hence, we must
+ add constraints by using <c>'CosNotifyFilter_MappingFilter':add_mapping_constraints/2</c>.
+ If a constraint matches, the associated value will be used instead of the
+ related Quality of Service system settings.</p>
+ <p>As input, the second argument must be a sequence of:</p>
+ <code type="none">
+#'CosNotifyFilter_MappingConstraintPair'{
+ constraint_expression = #'CosNotifyFilter_ConstraintExp'{
+ event_types = [#'CosNotification_EventType'{
+ domain_name = string(),
+ type_name = string()}],
+ constraint_expr = string()},
+ result_to_set = any()}
+ </code>
+ </section>
+ </section>
+</chapter>
+