
                      OSIMIS CHANGES IN ICM RELEASE 3.5

This document outlines the changes in the ICM OSIMIS release 3.5 mainly
since the release 3.3. There is similar information for changes from
3.0/3.2 to 3.3. Emphasis is placed to the non backwards-compatible changes.
Important additions are also mentioned but this document does NOT serve
as a manual for those.

This document should be read very carefully before converting previous
code to work under 3.5 and its guidelines should be followed to the letter.


PEPY -> PEPSY CONVERSION
------------------------

OSIMIS uses now pepsy only and not a mixture of pepy/pepsy as before.
See the document pepsy.txt for details. The only necessary non backwards
compatible API change is that the type_SMI_StringList structure in SmiAsn.h
is now called StringListVal according to the OSIMIS naming conversion
for hand-crafted structures that correspond to ASN.1 types.
Its string member is now called string instead of IA5String.



ATTRIBUTES
----------

A number of new attributes were introduced:

RealList, IA5String, GraphicString, PrintableString,
IA5StringList, GraphicStringList, PrintableStringList,
AttributeIdList, ObjectInstanceList, Scope

The String and StringList attributes still exist but they now default
to GraphicString and GraphicStringList respectively. You are encouraged
to use the exact type (Graphic, Printable, IA5) for string syntaxes
in GDMO definitions rather than using String and StringList.
Note that you will need to change your oidtable.at to replace the
String and StringList syntaxes with GraphicString and GraphicStringList
respectively.

A Attr::_getelem virtual method for list syntaxes was added. This
and the existing Attr::_getnext one are encapsulated by the public
methods Attr::getElem and Attr::getNext which can be used to walk
through the elements of a list attribute in C++ style:

    void* cur = NULLVD; // NULLVD signifies the beginning

    while (cur = intList->getNext(cur)) {
        int* elem = strList->getElem(cur);
        // do something with elem ...
    }

instead of the C-style used before (still valid):

    IntegerListVal* cur = (IntegerListVal*) intList->getval();

    while (cur) {
	int elem = cur->integer;
        // do something with elem
        cur = cur->next;
    }


Now all the Structure/Definition of Management Information Syntaxes (SMI/DMI)
are in the directory $(TOP)/agent/smi in the library libsmisntx.a,
including the C++ attribute classes which were previously in libgms.a .
This means that managing only applications can now use the exact
syntax type rather than using AnyType which requires access to oidtables:

    // exctract from $(TOP)/examples/odp/OdpTestClnt.cc
    // that prepares the action arguments for the RMIB access API:

    if (argc == 2)      // 1 number - sqrt service asked
        actionArg = new AVA("calcSqrt", new Real(atof(argv[1])));
    else {              // > 1 numbers - meanStdDev service asked
        RealList* realList = new RealList;
        for (register int i = 1; i < argc; i++)
            realList->addval(atof(argv[i]));
        actionArg = new AVA("calcMeanStdDev", realList);
    }



ACTION INFORMATION / RESULT
---------------------------

Actions of OSIMIS managed objects can now have different syntaxes
for information and result. This was possible before only by creating
a new syntax that was the untagged CHOICE of the two others.
See the document pepsy.txt for details of the new facility for actions.



GDMO COMPILER
-------------

Access to managed object attributes is now supported by special
compiler produced methods that return the exact type, so using
the attribute array and casting back is not needed any more.
For example, setting the value for the uxObj1 nUsers attribute can be now:

    nUsers() -> setreal(nusers);

instead of (dangerous and not elegant back-casting):

    ((Gauge*) _attrs[I_nUsers]) -> setreal(nusers);

The produced inline methods have the name of the attribute as
in the GDMO definition (see also the gmsapi.txt document).


In trying to reduce the size of executables, the GDMO compiler produces
now only forward references for C++ attributes/actions in <mo>.h
while the relevant header files are included only in <mo>.cc .
That way, other code that includes <mo>.h but does not need to access
a particular attribute does not link inline methods of the latter
as static symbols. This means though that if you need access to a
particular attribute you will need to include its header file
e.g. "IntegerList.h" in your code.

In converting old code you may receive compile time errors about
"incomplete class definition" which means that your .cc file needs
to include a missing header file.



GMS API
-------

VERY IMPORTANT, all the polymorphic GMS methods have now a different
API for better error reporting (arbitrary error parameters) and future
support for atomicity and asynchronous object operations.
Read very carefully the gmsapi.txt document and also look at example
code to convert you objects. It should be rather easy as the additional
parameters are not going to be used. Be careful though to do the changes
to the method interface pedantically: as if you forget one of the new
arguments your code will compile with g++ without warnings and then
it will NOT execute polymorphically. The ATT CC 2.1 compiler at least
gives a warning of "method hiding virtual one".


The triggerAttributeValueChange and triggerStateChange object management
notifications of Top can now be invoked from outside an object if needed
by taking a char* (notification name) first argument instead of the
two integers (notifId, classLevel) which may be unknown "outside" the class.

The oldAttributeValue optional argument of those notifications is now
of type void* and NOT PE as before (non backwards compatible change).
The GMS is now responsible for freeing this value and NOT the user.
The (optional) old value should be copied before the new value is set.
An example from the monitor metric objects (monitorMetric class):

    void* val;
    if (_pmoObserved == NULLMO ||
            (val = forceGet(_pmoObserved, _oidObservedAttribute)) == NULLVD) {
        void* oldStateVal = scanner::operationalState()->copy();
        scanner::operationalState() -> set(os_disabled);
        triggerStateChange(I_operationalState, scanner::_level, oldStateVal);

        advise (NULL, "Error: NULLMO in monitorMetric::updateDerivedGauge()\n");
        return;
    }


Some of the MIB access methods of the MO class (e.g. getMO,
getSubordinates etc.) take now an additional argument of AVA*& type.
This is simply a pointer that may be set to an AVA object containing
an error type and possibly relevant information if the MIB access fails.
This may only take place if "refreshing" the MIT involves a remote
operation to a loosely coupled resource, in which case the communication
may be broken, the loosely coupled resource may have crashed etc.
If there is no such possibility or even if there is and the user of the
access method is not interested to know of the failure, this parameter can
be simply set to NULLAVA. It could have been made optional but
the ATT C++ 2.1 compiler did complain that it was
"too complex an argument to be optional"!


When an object is created at initialisation time,
through a resource operation or through a CMIS M-CREATE, its logic (code)
has now the means to distinguish of what type of creation it is
and to act accordingly if needed so. The following enumerated type
is defined in GenericMO.h and a pointer to it is passed to <mo>::createRR
through the optional void* argument:

typedef enum
{
    ct_undefined,
    ct_initialisation,
    ct_managementOperation,
    ct_resourceOperation

} CreationType;

a. ct_initialisation is passed during the MIB initialisation
b. ct_managementOperation is passed during creation through CMIS

In the case of a creation because of resource operation it is the
user's code that creates the MO e.g.

    CreationType crType = ct_resourceOperation;
    tpConn = (transportConnection*)
                        transportConnection::create(str2rdn(id), _tpEntity);
    tpConn -> createRR(&crType);

In that case the user should pass ct_resourceOperation if the managed
object's create behaviour needs it.



RMIB API
--------

This was simply enhanced to allow the user of the services of an RMIBAgent
instance if the association to the remote application is broken.
This is effected through the RMIBAgent methods

    int    notifyBrokenAssociation (RMIBManager*);
    int    cancelCallbacks (RMIBManager*);

and the RMIBManager callback:

    virtual int brokenAssociation (RMIBAgent*);


Also now the RMIBAgent Get method has a boolean optional argument
to signify the return of replies one-by-one (not assembling service).
A unique integer is returned by the Get method and can be used
as the token to effect a CMIS CancelGet. Single replies are returned
to the CMISManager through the method

    virtual int singleGetResult (CMISObject*, RMIBAgent*);

the last one being an empty result with the id of that sequence.



LOCATION TRANSPARENCY
---------------------

This was enhanced at UCL to be able to access single-instance
agents without having to pass the host name. All the programs
in $(TOP)/manager/general have been modified to take the two
first arguments as (example):

maction ODPTEST kinou -i simpleStatsId=test -a sqrt=2  or
maction -S ODPTEST -i simpleStatsId=test -a sqrt=2

The first is a version without location transparency while
the second uses location transparency to find where ODPTEST runs
(and not only if it is up and running only). The -S stands for -Single .

Single instanced agents should initialise the CMISAgent object in the
main program by passing the optional singleInstanceAgent boolean
argument as True (default being False) - you may look at
$(TOP)/examples/odp/OdpTestSrv.cc .



ODP EXAMPLE
-----------

OSIMIS contains now a simple ODP-like example with a ODPTEST server
applications containing a simpleStats class that provides simple
statistical services (square root and mean/standard deviation).
You may consult the odpexample.txt document ans also look in
$(TOP)/examples/odp .



SIMULATED TIME
--------------

The simulated time support service was updated to relay "upwards"
the time change event report in a management hierarchy. You may see
the document simtime.txt and study the examples in $(TOP)/simtime/example .



SECURITY
--------

The MIDAS security extensions have been included in this release
but OSISEC and the QUIPU DSA for public key access are needed.
More information on this feature will be supplied later.



ATTRIBUTE COMPILER
------------------

This has also been included but its use is discouraged as the code
it produces is still buggy and also does not compile with ATT CC 2.1 .



NON-FUNCTIONAL CHANGES
----------------------

Access to oidtables uses now a much better hashing function which
increases performance while the maximum size limitation for both OIDs
and syntaxes has now been lifted.

OSIMIS applications are now substantially
smaller at run-time due to a number of optimisations.

Finally, the top part of $(TOP)/CONFIG.make contains a configuration
facility through which whole components can be left out at compile time
without the need to modify Makefiles.



CHANGES FOR NON-GDMO COMPILER PRODUCED CLASSES (FULLY HAND-WRITTEN)
-------------------------------------------------------------------

Classes that were written by hand for version 3.0 can still work
as far as they are updated according to the changes described above.

There are though two additional requirements for those classes
which are taken care by the GDMO compiler for others:

a. in <class>::initialiseClass the parent class should be set using
   the MOClassInfo::setParent method. An example (class Log):

    /* set parent class (meta-class tree) */
    _info.setParent(Top::getClassInfo());

b. in <class>::initialiseClass, the create/mcreate methods should
   be set accordingly (the mcreate one only if CMIS creation is allowed).
   An example (class Log):

    _info.setCreate(Log::create);
    _info.setMCreate(Log::cmisCreate);

