CORBA

Čo je CORBA?

CORBA (The Common Object Request Broker Architecture) je architektúra a špecifikácia na vytváranie, distribuovanie a spravovanie distribuovaných objektov v sieti. Umožňuje distribuovaným aplikáciám, aby spolupracovali, a to nezávisle na tom, v akom jazyku sú napísané a kde sa nachádzajú. Teda jeden objekt je napríklad na unixovskom stroji v jazyku c++, druhý na windowse v jave niekde na druhom konci sveta. Výhodou je, že všetko je štandardizované. CORBA využíva objektovo orientovaný prístup na vytváranie softvérových komponentov, ktoré môžu byť zdieľané medzi aplikáciami.

Ako to funguje?

CORBA je klient/srver architektúra, ktorá sa skladá z troch základných komponentov - klient, server a ORB. ORB (Object Request Broker) spája klientskú aplikáciu s objektmi, ktoré chce aplikácia použiť.

Klientský program nepotrebuje vedieť, či je server s ktorým komunikuje na tom istom počítači, alebo na nejakom vzdialenom počítači niekde v sieti. Klientský program len potrebuje vedieť meno objektu a musí rozumieť ako používať interface objektu. O detaily zamerania objektu, smerovania požiadavky a vrátenia výsledku sa postará ORB. Samotý ORB nie je samostatný proces. Je to kolekcia knižníc, ktorá umožňuje klientským aplikáciám zamerať a využívať objekty.

VisiBroker

VisiBroker (od Borlandu) sprostredkuje kompletné CORBA 2.3 ORB prostredie pre tvorbu, rozvíjanie a správu distribuovaných java aplikácií. Objekty vytvorené pomocou VisiBroker-u sú ľahko prístupné webovo zameranými aplikáciami, ktoré komunikujú využívajúc IIOP (OMG's Internet Inter-ORB Protocol) štandard pre komunikáciu medzi distribuovanými objektami cez internet a cez lokálne siete.

Vývoj distribuovaných aplikácií

Pri vývoji distribuovaných aplikácií pomocou VisiBroker-u zvyčajne sledujeme tieto kroky:

  1. Vytvorenie špecifikácie pre každý objekt použijúc IDL (Interface Definition Language). IDL je jazyk, ktorý slúži na popis objektového rozhrania
  2. Využitie IDL kompilátora na generovanie klientského stub kódu a serverového POA (Portable Object Adapter) kódu. POA je sprostredkovateľ medzi implementáciou objektu a ORB-om.
  3. Napísanie programového kódu pre klienta
  4. Napísanie programového kódu pre serverovské objekty.
  5. Skompilovanie klientského a serverovského kódu

Príklad

Vytvoríme aplikáciu na vztvorenie bankového účtu a výpis jeho stavu.

V Bank.idl si špecifikujeme interface Account s metódou balance() a interface AccountManager s metódou open(). Bank.idl potom zkompilujeme pomocou idlľjava kompilátora, ktorý nám vytvorí potrebné stub kódy a kódy pre servanty.

Klientský program bude pozostávať z týchto krokov:

  1. inicializácia ORB
  2. bind na objekt AccountManager
  3. získanie objektu Account zavolaním metódy open objektu AccountManager
  4. zistenie stavu účtu zavolaním metódy balance objektu Account

public class Client {
  public static void main(String[] args) {
    // Initialize the ORB.
    org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
    // Get the manager Id
    byte[] managerId = "BankManager".getBytes();
    // Locate an account manager. Give the full POA name and the servant ID.
    Bank.AccountManager manager =
      Bank.AccountManagerHelper.bind(orb, "/bank_agent_poa", managerId);
    // use args[0] as the account name, or a default.
    String name = args.length > 0 ? args[0] : "Jack B. Quick";
    // Request the account manager to open a named account.
    Bank.Account account = manager.open(name);
    // Get the balance of the account.
    float balance = account.balance();
    // Print out the balance.
    System.out.println("The balance in " + name + "'s account is $" + balance);
  }
}

Serverovský program bude robiť nasledovné:

  1. inicializácia ORB
  2. vytvorenie POD s potrebnými zásadami (policies)
  3. vytvorenie servant objektu pre account manager-a
  4. aktivovanie servant objektu
  5. aktivovanie POA manager-a
  6. čakanie na príchod požiadavky

import org.omg.PortableServer.*;
public class Server {
  public static void main(String[] args) {
    try {
      // Initialize the ORB.
      org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
      // get a reference to the root POA
      POA rootPOA =       POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
      // Create policies for our persistent POA
        org.omg.CORBA.Policy[] policies = {
        rootPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT)
      };
      // Create myPOA with the right policies
      POA myPOA = rootPOA.create_POA( "bank_agent_poa", rootPOA.the_POAManager(),policies );
      // Create the servant
      AccountManagerImpl managerServant = new AccountManagerImpl();
      // Decide on the ID for the servant
      byte[] managerId = "BankManager".getBytes();
      // Activate the servant with the ID on myPOA
      myPOA.activate_object_with_id(managerId, managerServant);
      // Activate the POA manager
      rootPOA.the_POAManager().activate();
      System.out.println(myPOA.servant_to_reference(managerServant) + " is ready.");
      // Wait for incoming requests
      orb.run();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Potrebujeme ešte implementovaťobjekty Account a AccountManager na strane servra, na čo si vytvoríme triedy AccountImpl a AccountManagerImpl:

public class AccountImpl extends Bank.AccountPOA {
  public AccountImpl(float balance) {
    _balance = balance;
  }
  public float balance() {
    return _balance;
  }
  private float _balance;
}

import org.omg.PortableServer.*;
import java.util.*;
public class AccountManagerImpl extends Bank.AccountManagerPOA {
  public synchronized Bank.Account open(String name) {
    // Lookup the account in the account dictionary.
    Bank.Account account = (Bank.Account) _accounts.get(name);
    // If there was no account in the dictionary, create one.
    if(account == null) {
      // Make up the account’s balance, between 0 and 1000 dollars.
      float balance = Math.abs(_random.nextInt()) % 100000 / 100f;
      // Create the account implementation, given the balance.
      AccountImpl accountServant = new AccountImpl(balance);
      try {
        // Activate it on the default POA which is root POA for this servant
        account = Bank.AccountHelper.narrow(_default_POA().servant_to_reference(accountServant));
      } catch (Exception e) {
        e.printStackTrace();
      }
      // Print out the new account.
      System.out.println("Created " + name + "’s account: " + account);
      // Save the account in the account dictionary._accounts.put(name, account);
    }
    // Return the account.
    return account;
  }
  private Dictionary _accounts = new Hashtable();
  private Random _random = new Random();
}

Teraz zkompilujeme súbory Client.java, AccountImpl.java, AccountManagerImpl.java, Server.java (pomocou vbjc).

Predtým ako spustíme Clienta, alebo serverovské implementácie, musíme najprv spustiť program Smart Agent aspoň na jednom hoste na lokálnej sieti.Potom môžme spustiť server príkazom

start vbj Server

a klienta príkazom

vbj Client

Zazipovana stranka