CORBA Session Examples

## 5 CORBA Session Examples

### 5.1 A CORBA Session in Erlang

Following is a simplified example of a client written in Erlang to access `Mnesia` via the CORBA session interface. The type definitions are the same as in the previous chapter.

To begin with include the necessary files.

    %% Include to get the mnesia types, used in create table
    -include_lib("mnesia_session/include/mnesia.hrl").

    %% Include to get the corba types i.e. any
    -include_lib("orber/include/corba.hrl").

    %% Include my own types
    -include("persons.hrl").

Find the connector and create a private session.

    start_corba_session(Host, Port) ->
        %% Lookup the inital corba name sever
        Addr = "iiop://" ++ atom_to_list(Host) ++ ":" ++ integer_to_list(Port),
        NS = corba:resolve_initial_references_remote("NameService", [Addr]),

        %% Create a corba name object
        NC = lname_component:set_id(lname_component:create(),
                                    "mnesia_corba_connector"),
        N = lname:insert_component(lname:create(), 1, NC),

        %% Lookup the object reference to the factory mnesia_corba_connector
        Cok = 'CosNaming_NamingContext':resolve(NS, N),

        %% Use the factory to create a session
        Sok = mnesia_corba_connector:connect(Cok),
        {Cok, Sok}.

In Erlang, objects are represented as processes. To access the method of the object, call the method where the first argument is the object reference, as in `mnesia_connector:connect(ConnPid)`. All functions in the IDL specification have an additional first argument which is the object reference, more information is given in the `IC` and `Orber` documentation.

To create a table with the structure defined in the IDL definition, we use the function create_person_table.

Define the table properties and call the function:

    create_person_table(ObjKey) ->

        %% Define the table properties
        Attrs = [atom_to_list(F) || F <- record_info(fields, persons_person)],
        TabDef = #mnesia_TableDef{type = bag, mode = read_write,
                                  ram_copies = [],
                                  disc_copies = [],
                                  disc_only_copies = [],
                                  index_list = [4],  %% Index on married_to
                                  attributes = Attrs,
                                  %% NOTE that the record name must be exactly
                                  %% the same as the name of the
                                  %% structure/record to be used.
                                  record_name = "persons_person"},

        Res = mnesia_corba_session:create_table(ObjKey, "persons", TabDef),
        case Res of
            {ok, ""} ->
                ok;
            Else ->
                io:format("ERROR: ~s~n", [Else])
        end.

In this example the insert and a read operation looks like:

    insert_person(SessionKey, Name, Sex, Age, Phone, Mt, Ch) ->
        Data = #persons_data{sex = Sex, age = Age, phone = Phone},
        Person = #persons_person{name = Name, personData = Data,
                                 married_to = Mt, children = Ch},

        Any = #any{typecode = persons_person:tc(), value = Person},
        {ok, ""} = mnesia_corba_session:dirty_write(SessionKey, "persons", Any),
        Person.

    get_person(SessionKey, Name) ->
        Obj = #any{typecode = {tk_string, 0}, value = Name},
        {ok, RObjs, ""} =
            mnesia_corba_session:dirty_read(SessionKey, "persons", Obj),
        RObj = hd(RObjs),
        RObj#any.value.

Notice the usage of the `any` type in both the read and write operations. `erlang::term` in the IDL specification is represented as the CORBA type `any` when using the CORBA session interface. The `any` type is represented as a 2-tuple containing type-code and value, the user must in Erlang insert the type-code.

### 5.2 A CORBA Session in Java

This example is the same but using Java and OrbixWeb.

For this example to work, the following specifications need to be compiled:

- compilation of the user defined IDL specifications (`UNIX: , Windows:` )
- ${OTP_ROOT}/lib/mnesia_session-Version/src/mnesia_corba_session.idl (`UNIX: , Windows:` )
- ${OTP_ROOT}/lib/ic-Version/include/erlang.idl (`UNIX: , Windows:` )
- ${OTP_ROOT}/lib/orber-Version/COSS/CosNaming/cos_naming.idl (`UNIX: , Windows:` )
- ${OTP_ROOT}/lib/orber-Version/examples/Stack/InitialReferences.idl (`UNIX: , Windows:` )

Import CORBA and CosNaming Classes:

    import CosNaming._NamingContextRef;
    import CosNaming.Name;
    import IE.Iona.Orbix2._CORBA;
    import IE.Iona.Orbix2.CORBA.*;

Find the connector and create a private session.

        public static mnesia._corba_sessionRef
            start_corba_session(String args[])
        {
            mnesia._corba_sessionRef mcsRef = null;
            mnesia._corba_connectorRef mccRef = null;
            CORBA._InitialReferencesRef init;
            _NamingContextRef nsContext;
            Name name;
            _ObjectRef initRef, nsRef, objRef;
            Orber.InitialReference ir = new Orber.InitialReference();

            String srvHost = new String(args[0]);
            Integer srvPort = new Integer(args[1]);
            try
            {
                // For an explanation about initial reference handling see
                // the "Interoperable Naming Service" specification.

                // Create Initial reference (objectkey "INIT").
                String s = ir.stringified_ior(srvHost, srvPort.intValue());
                initRef = _CORBA.Orbix.string_to_object(s);
                init = CORBA.InitialReferences._narrow(initRef);
                // Fetch name service reference.
                nsRef = init.get("NameService");
                nsContext = CosNaming.NamingContext._narrow(nsRef);
                // Create a name
                name = new Name(1);
                name.buffer[0] =
                    new CosNaming.NameComponent("mnesia_corba_connector", "");
                try
                {
                    objRef = nsContext.resolve(name);
                }
                catch(UserException n)
                {
                    System.out.println("Unexpected exception: " + n.toString());
                    return null;
                }
                mccRef = mnesia.corba_connector._narrow(objRef);

                // Create and return the session reference
                mcsRef = mccRef.connect();
                return mcsRef;
            }
            catch(SystemException se)
            {
                System.out.println("Unexpected exception: " + se.toString());
                se.printStackTrace();
                return null;
            }
        }

Create the person table

        public static void create_person_table(mnesia._corba_sessionRef mcsRef)
        {
            String name = "persons";
            mnesia.TableDef def = new mnesia.TableDef();
            def.type = mnesia.SetOrBag.bag;
            def.mode = mnesia.AccessMode.read_write;
            def.ram_copies = new mnesia.NodeList(0);
            def.disc_copies = new mnesia.NodeList(0);
            def.disc_only_copies = new mnesia.NodeList(0);
            mnesia.Indices idxs = new mnesia.Indices(1);
            idxs.buffer[0] = 4;
            def.index_list = idxs;
            mnesia.AttrNames attrs = new mnesia.AttrNames(4);
            attrs.buffer[0] = "name";
            attrs.buffer[1] = "personData";
            attrs.buffer[2] = "married_to";
            attrs.buffer[3] = "children";
            def.attributes = attrs;
            def.record_name = "persons_person"; // The used IDL type

            StringHolder reason;
            reason = new StringHolder();
            try
            {
                if(mnesia.Status.ok != mcsRef.create_table(name, def, reason))
                    System.out.println("Create Table Error " + reason.value);
            }
            catch( SystemException se)
            {
                System.out.println("Unexpected exception: " + se.toString());
                return;
            }
        }

The insert operation. Observe the encapsulation of person in the `mnesia.Record`. Java or OrbixWeb will handle the type encoding.

        public static void insert_person(mnesia._corba_sessionRef mcsRef,
                                         String name,
                                         int sex,
                                         int age,
                                         int phone,
                                         String mt,
                                         _sequence_String children)
        {
            persons.data data;
            data = new persons.data(sex, age, phone);
            persons.person person = new persons.person();
            person.name = name;
            person.personData = data;
            person.married_to = mt;
            person.children = children;

            try
            {
                StringHolder reason = new StringHolder();
                mnesia.Record object = new mnesia.Record();
                object.insert(person);

                if(mnesia.Status.ok != mcsRef.dirty_write("persons", object, reason))
                    System.out.println("Insert person Error " + reason.value);
            }
            catch(SystemException se)
            {
                System.out.println("Unexpected exception: " + se.toString());
                return;
            }
        }

A read operation. Observe the extraction of person from the received `mnesia.Recordlist` and the `key` object handling.

        public static persons.person
            get_person(mnesia._corba_sessionRef mcsRef, String name)
        {
            try
            {
                StringHolder reason = new StringHolder();
                mnesia.Key key = new mnesia.Key();
                mnesia.Recordlist res = new mnesia.Recordlist();
                key.insertString(name);

                if(mnesia.Status.ok == mcsRef.dirty_read("persons",
                                                         key, res, reason))
                {
                    if(res.length > 0)
                    {
                        persons.person rec1 = new persons.person();
                        res.buffer[0].extract(rec1);
                        return rec1;
                    }
                    else
                        return null;
                }
                else
                {
                    System.out.println("Insert person Error " + reason.value);
                    return null;
                }
            }
            catch(SystemException se)
            {
                System.out.println("Unexpected exception: " + se.toString());
                return null;
            }
        }

Copyright © 1991-2007 Ericsson AB