Subject: Re: An approach to modeling ForCES events

From: "Deleganes, Ellen M" <[email-masked]>
Date: Thu, 14 Apr 2005 17:25:00 -0700

I didn't quite follow what point you were making in the comment about
some of the event triggers may not be universal. I agree that the
<fallsbelow> or <exceeds> triggers only makes sense for some types of
fields, namely counters. The triggers seem useful in some cases, so I
hope you weren't suggesting to eliminate those triggers altogether. 

Regards,
Ellen

-----Original Message-----
From: Forwarding and Control Element Separation
[mailto:[email-masked]] On Behalf Of Jamal Hadi Salim
Sent: Wednesday, April 13, 2005 7:13 AM
To: [email-masked]
Subject: Re: An approach to modeling ForCES events

Joel,

Good - lets have some activity on the list; hopefully this discussion
doesnt turn out into you and I batting a ball at each other(trying to
guilt other people ;-> We can make good progress if people understand
whats being said now as opposed to spending many hours later rehashing
the same things again)

I have a small variation to your approach further below. It wouldnt be
fun otherwise ;->

On Wed, 2005-04-13 at 07:44, Joel M. Halpern wrote:
> Assume that the LFB include a foo and bar elements. foo is an array 
> whose contents are a structure with fields baz, caz, daz where daz 
> is in turn an array of uint32.
> oddity is an array indexed by the same idex as the daz entires.
> 

Does oddity make sense the way you described it? If i read correctly, 
there will be many daz "tables" but only one oddity.

> I have not defined any specific semantics for the objects because it
would 
> take a lot of text.  These are simply examples of things which can
change, 
> and which teh CE wants to know about.
> 

Didnt quiet follow:
Are you talking about registration? Or how things will be laid out in
the LFB text? 

> <events eventBaseID="7" registerBaseID="8">
>     <event eventID="1">
>        <target> bar </target>
>        <change/>
>        <synopsis> report if bar changes </synopsis>
>        <reports>
>           <report> bar </report>
>        </reports>
>     </event>
>

I am assuming the target is going to be a path syntax i.e you just have
it above for illustratation purposes.

>     <event eventID="2">
>        <target> foo.$1.baz </target>
>        <exceed> 75 </exceed>
>        <synopsis> report if any baz in foo gets above 75 </synopsis>
>        <reports>
>           <report> foo.$1.baz </report>
>           <report> foo.$1.caz </report>
>           <!-- no need to report the index $1, as that will be in the
event 
> path ID -->
>        </reports>
>     </event>
>     <event eventID="3">
>        <target> foo.$1.daz.$2 </target>
>        <fallsbelow> 3 </fallsbelow>
>        <reports>
>           <report> foo.$1.daz.$2 </report>
>           <report> foo.$1.caz </report>
>           <report> oddity.$2.state </report>
>        </reports>
>     </event>
>     <event eventID="4">
>        <target> oddity </target>
>        <change/>
>        <reports>
>           <report-cause/>
>           <report> bar </report>
>        </reports>
>     </event>
> </events>
> 

I think you have all the needed constructs above. Good stuff.

The triggers that cause events as you have them right now may not be
universal; example fallsbelow or exceeds makes sense only if you have
counters. I think this can be revisted later, but let me just digress a
little:
I may also be interested in getting a synchronous event ("send me 
bar every 30 seconds") or even more interesting async ones perhaps
driven by some packet arrival  like "notify me about bar when you
receive ICMPs from Joel". I am not sure the second one fits well, but
certainly the first one does. 
Also additional semantics like "let me know if it changes X times" which
could be viewed as a superset of </change> where X=1

> This declares that paths within this LFB that start with 7 reference 
> events, and paths that start with 8 are for the boolean variables that

> represent registration state for the events.  Paths starting with 7
will 
> appear only in notifications.
>
> Q: I could have used a single path starting point, and simply had
different 
> meanings for its use in SET / GET (where it would reference the
boolean 
> variable) and in NOTIFICATIONS (where it would mean the event itself
and 
> the associated reporting type.  I thought this was a bad idea.
> 

I think your approach of the subscription being a different scope than
notification is better.
Related:
The event subscribe/unsubscribe are essentially SETs. GET "all events"
or "all event to do with foo" doesnt exist at the moment.

> Each even then has an ID which is concatenated with the base paths to
start 
> building the notification and registration paths.  For event 1
(changes to 
> bar) the paths are simply 7.1 for the notification and 8.1 for
registering.

Makes sense.

> Events 2 and 3 are events about array elements inside the LFB.  Thus
the 
> path to a specific event is the base, the eventid, and the subscript.
So a 
> specific occurrence (say in the fourth daz entry in the second foo
entry) 
> of event 3 would be reported with the path 7.3.2.4

Q. How does an FE LFB say "I can support foo.$1.daz.$2" as a event
target?
If you decide to describe it in english in some text - does that limit
things? Or do we let the CE register and have the FE reject when it cant
do it.

Heres where i think i should mention the variation i have over what you
present, the other way to do this is to say:

If i subscribe to event path 8.X <target>foo</target> it would mean I am
interested in anything that happens in foo. 
If i subscribe to target foo.$1.baz then i am interested in column baz
of table foo.
If i subscribe to target bar then i am only interested in that scalar.

In other words theres a hierachical connotation to event targets. i.e
if i say target "foo" then that implies "foo.$1.baz" and
"foo.$1.caz" and "foo.$1.daz.$2"
The only issue with above is conflict resolution which is resolvable.

The <report> construct still is the one that defines the verbosity of
what gets reported back.
In other words, even on the <report> you could have different syntatic
sugar; verbosity levels are:
3)  "tell me what exactly changed".
The notify will have to give you the path and new target values.
2) "tell me the path of what changed" as well under event id 30.
1) "dont bother telling me what exactly changed - all i need to know is
event 3 happened"

> Q: We have been asked to support registering for events on a whole 
> table.  Currently, set 8.3.2 would be setting teh table of boolean 
> variables. 

Refer to my comments above.

> However, it is not legal to directly create or delete entries 
> in this table (Since it mirrors the foo[]daz table structure.)  So we
could 
> declare that a reference to the entire array is in this case a
reference to 
> a single boolean that covers the array.  It seems useful to have that.
But 
> allowing that will seriously complicate the type determination logic.
> 

Seems like it will be ok to subscribe/unsubscribe though. In other words
if i subscribe for event 3 - that is something that will exist in the
FEs LFB state information i.e i can query it; if i unsubscribe then i
cant query for that event.

> Each event includes a target variable (with subscripts if the target
is in 
> an array.)  The subscripts are named so they can be referenced in the 
> reports clause.  The subscripts themselves will appear in the event 
> notification.
> Each event then includes a condition.  I have not tried to enumerate
all 
> the conditions yet, but some of them are shown above.

The conditions are essentially triggers for the events - I think we can
probably say there exist only a handful of those.

> Q: Should we directly put the different condition tags, as I have done

> above, or should we use:
>     <condition>
>       <cond-kind-tag/>
>       <!-- optional -->
>       <condition-value> value </condition-value>
>     </condition>
> 
> The target variable can be an array, rather than its entries.  In that

> case, the change trigger would mean the deletion or creation of any 
> entry.  (We will probably have separate deletion and creation triggers
as 
> well.)  In that case, the event path will include the subscript of the

> entry being created or deleted.  the <report-cause> in the reports
will 
> cause a scalar to be included indicating what event has occurred.
(This is 
> legal with any report, but is likely most useful with arrays.)
> 
> The reports element indicates what information to send along with the 
> notification.  It can select any elements from the LFB Class.  It can
use 
> any of the subscripts in the trigger path.  Essentially, it defines
the 
> data type and contents for the data portion of the notification TLV.
> 
> One additional question that occurred to me later is, if a change is
made 
> by the CE, and the CE is registered for an event triggered by the 
> change,  should the notification be generated?  Should we have a flag
in 
> the SET request to suppress such notifications?  My first reaction is
that 
> it should be generated even for changes by the CE, but I am not sure.
> 
> Is this sufficiently ugly to prompt someone to do a better job?
> 

Look at my comments on more genericity of subscription;
I think the constructs needed are all there in what you define.

Hopefully the other folks in the protocol and model would chip in as
well in this discussion.

cheers,
jamal

---

From: Jamal Hadi Salim <[email-masked]>
Date: Fri, 15 Apr 2005 10:19:31 -0400

> hope you weren't suggesting to eliminate those triggers altogether. 

What i am suggesting is if we go and add triggers such as these which
deal only with specific cases we might as well enumerate more. Example i
gave was a synchronous trigger such as timers for example etc.
A table or any attribute manipulation is another. A packet arrival thats
interesting could also be used as a trigger. Note all these are not
universal either.

cheers,
jamal

---

From: "Joel M. Halpern" <[email-masked]>
Date: Fri, 15 Apr 2005 10:48:28 -0400

Yes, one of the tasks in writing the event section of the model document 
will be to put together a list of ALL the triggers we want to support, what 
model information they need, and the exact semantics.  I was just showing 
some samples so as to indicate the approach.  For example, I did not show a 
case with a configurable threshold, whether the alarm condition might be
       <exceeds-var> foo.$1.threshold </exceeds-var>

I am trying to find out if this approach, with explicitly listed events, 
the mechanism for subscript handling, the ability to register for changes 
to a table itself, and separately some way to register for all occurrences 
of an element related event in a table (which I have not figured out) is 
what we want.

Frankly, I am really hoping someone will come up with something with this 
expressive power but a better syntax / structure, because I am not really 
happy with what I have suggested.  Things like the $1 (or worse 
foo.$1.bar.$2.zang.$3.quibble) are not what I would really like.  But since 
you need to report the index of the event, and you may need to pick 
elements out of parallel tables with related indexing for reporting with 
the event, I can not currently see any way around this.

Yours,
Joel

---

From: Jamal Hadi Salim <[email-masked]>
Date: Fri, 15 Apr 2005 14:52:29 -0400

On Fri, 2005-15-04 at 10:48 -0400, Joel M. Halpern wrote:
> model information they need, and the exact semantics. 

ok, nice.

>  I was just showing 

I think it would be better if they are listed somewhere so there is no
confusion (understood that this was a quick intro you did).

> of an element related event in a table (which I have not figured out) is 

I didnt catch the last part on "all occurrences  of an element related
event in a table".
But certainly explictly listing of possible events on a per LFB class is
the approach taken by SNMP traps - so theres prior experience. I am
however skeptical about being as restrictive as SNMP was; i.e i should
be able to show interest in table foo and/or foo.$1.daz.

> the event, I can not currently see any way around this.

How about this, lets list semantics in English and see how your approach
fits and suggest how we could extend things (This also helps add text to
explain the constructs you posted)

For subscription purposes you would need the following:
=======================================================

1) a way to describe the specific event of interest. 
The explicit listing of events with registerBaseID for subscription,
event IDs and <target> for picking specific LFB-attributes is sufficient
in my opinion.

2) A way to define a trigger. So far you have listed the following
triggers:
i) <change> 
probably the most generic. Captures a change in any attribute.

ii) <exceed>
iii) <fallsbelow>

The above 2 are specific to counters of some form.

Maybe we need a <trigger> ..</trigger> to surround each.

We should add more triggers; timers for example.

3) Event report formatting.
The <report> looks good. The main issue i had is the verbosity level
of reporting. I know you (Joel) have had issues with the levels of
reporting in other discussions regarding the protocol. I think it's an
important addition.
Example of verbosity would be something along the lines of:

*level0) "just tell me when the event happens - dont want any details" 
*level1) "tell what the value of foo.$1.bar when this event happens" 

4) Ability for the FE to reject nonsense.

For notification, whats needed is:
==================================
Close to what you had in the wire format you posted earlier ...

1) A event ID 
2) optionally (depending on whether we agree on reporting levels)
a data value for that path as per subscription time <report> construct.

On Hierarchy and conflict resolution
====================================

Consider a structure such as a table which may have cells/children
composed of other structures which may in turn have other structures
(eventually hitting some terminal atomic element).
To use your earlier example: Assume an LFB with a foo and bar elements.
foo is an array whose  contents are a structure with fields baz, caz,
daz where daz is in turn an array of uint32.

Assume the only trigger in this LFB is <change>
Here are some sample events that i may be interested in (and to which i
should be allowed to subscribe to):
A) change in foo.$1.daz.3  (entries in all columns of foo called daz. In
particular the index 3 of daz).
B) change in foo.$1.daz (entries in all columns of foo called daz)
C) change in foo (everything in daz)

Clearly A is a subset of B which is a subset of C.

->A solution to this is to explicitly disallow it by definition. This is
what SNMP does i think (however with triggers we are already going
beyond what SNMP can do). 
->Another is to allow 3 events to be generated every time C happens;
2 every time B but not intersecting C happens etc.
->Another way to do it is have the FE figure it out at event generation
time and only send events which are most specific (example if C happens
the only C related event is triggered).
-> an extension to the above: add <priority> construct which
unambigously tells the FE what event to send. In the above example,
C would be set to be higher priority than B (which is higher than A).

Having said the above, it is clearly desirable once you have hierachies
to also be able to ask for reporting thats less specific.
To use the example above; if i subscribe to an event and have <target> 
be table foo, then i should be able to define that <report> returns
me in level1 verbosity level what caused the event; i.e i dont wanna
explicitly say "report to me the value of foo.$1.bar" 

Some of these thoughts are derived from our own implementation
experiences and subliminal messages of what we could have done better.

cheers,
jamal

---

From: "Joel M. Halpern" <[email-masked]>
Date: Fri, 15 Apr 2005 15:39:37 -0400

Trying for text description is quite sensible at this point.

Reading your note, there is an assumption I am making, that may be 
different than yours.

I believe that the LFB definition should indicate what events an instance 
of that LFB class amy generate.  A CE may only register for events from 
that set.  And each event declaration includes the specific trigger for 
that event.

So, the CE does not get to decide "I want to know if foo.$1.daz changes 
unless the LFB definer has already defined that as an event and assigned it 
an ID.
Thus, the events registrations and notifications do not need to include the 
full path to the variable that has caused the event (although they do need 
to include any subscripts in the path).
This also makes declaring an event that is a change (creation or deletion 
of entry) in the array foo natural.
If I assume that event 1 is changes in foo, and event 2 are changes in the 
foo.$1.caz variable, then I can register for event 1 by setting 
registerbase.1, and I can register for each event 2 that I want to by 
registering for registerbase.2.subscript.  What is not obvious to me is 
what path the CE would use to register for all occurrences of event 2, 
without regard to subscript.  As I said in the original, using the path 
registerbase.2 seems inconsistent with the normal meaning for that path 
(the array of all the individual registrations in that table.)

Yours,
Joel

---

From: "Joel M. Halpern" <[email-masked]>
Date: Fri, 15 Apr 2005 15:41:37 -0400

I don't know if this is useful, but is easy to represent.  Instead of a 
boolean registration variable, we use a uint8, where 0 means "do not 
notify", 1 means "just notify with no body", and 2 means "notify with body 
according to the declared report information from the LFB class definition."

I assume that event notifications will be relatively rare.  If so, is the 
savings in the report worth it?

Yours,
Joel M. Halpern

---

From: Jamal Hadi Salim <[email-masked]>
Date: Fri, 15 Apr 2005 16:12:09 -0400

> to include any subscripts in the path).

Ok, this was one of the modes i mentioned. I have no issues with doing
it this way. 

> (the array of all the individual registrations in that table.)

Ok, gotcha.

Maybe we need a wildcard. And the subscripts are per $x ordering.

Example:
registerbase.2.*  == "for table foo, all indices/rows, column caz". 
registerbase.2.1  == "for table foo, index=1, column caz" 

If event target was  foo.$1.caz.$2, then:
registerbase.2.*  == "for table foo, all indices/rows, column caz". 
registerbase.2.1  == "for table foo, index=1, column caz" 
registerbase.2.*.4  == "for table foo, all indices/rows, column caz,
index=4 of caz array". 
registerbase.2.1.5  == "for table foo, index=1, column caz, index=5 of
caz array" 

Of course this still means the issue on hierachy and conflicts is still
there.

cheers,
jamal