diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/cosNotification/doc/src/ch_BNF.xml | |
download | otp-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.xml | 456 |
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­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_­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_­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_­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> + |