Distribuerad programmering med CORBA
Föreläsning 16
CORBA: vad, varför, hur?
Innehåll
Datornätverk
Behov och krav
CORBA
Historik, principer, arkitektur och beståndsdelar
Exempel i Java
Läs också den utmärkta och konkreta tutorialen som du hittar på
följande adress:
http://www.javasoft.com/docs/books/tutorial/idl/index.html
previous
next
CORBA
Nätverk av datorer
• Idag har vi ett behov av att kommunicera mellan olika datorer och
annan hårdvara
• Vi vill kunna använda olika sätt att lösa ett problem, tex mha
olika programmeringsspråk
• Vi vill ha kostnadseffektiva lösningar
• Vi vill inte binda oss till en viss leverantör
• Troligen finns mycket programvara, ny eller gammal, av olika
slag i organisationen
previous
next
2
CORBA
CORBA (Common Object Request Broker Architecture)
• Standardisering av distribution konstruerad av OMG
(Object Management Group)
– OMG en sammanslutning av flera hundra (>600) intressenter
för att standardisera objekttekniker
• Digital, HP, SUN, IBM, Oracle, Netscape, Microsoft, Ericsson mfl
• Avsikt
– att konstruera ett språk- och plattformsoberoende
objektorienterat system för distribution
• Tillåter konstruktion av applikationer som kommunicerar över både
plattforms- och språkgränser
– minimerar beroendet av både hårdvara och programmeringsspråk
– enklare att använda mjukvara från olika leverantörer
previous
next
3
CORBA
... CORBA ...
• Baserad på en server-klient-modell
– en server erbjuder service
– en klient utnyttjar den
– på en viss plattform kan vissa objekt ta rollen av servrar
medan andra tar rollen av klienter
– ibland tar ”noderna” rollen av både server och klient
samtidigt, dvs så kallad ”peer-to-peer” kommunikation
• Finns bindningar till flera programspråk
– C++, ADA, Smalltalk, Java, C, COBOL, ...
previous
next
4
CORBA
... CORBA STARTA ...
• Starta namnserver
– dvs starta det objekt/program som ansvarar för att hantera
namngivna delade (/distribuerade) objekt
• Starta server med objekt
– bind objektet till namnservern
– låt servern vänta på att klienter skall kommunicera med dess
objekt
• Starta klienter och anslut till servern
– fråga namnservern om referens till visst objekt
– skicka meddelanden till objektet
previous
next
5
CORBA
... CORBA ...
• Meddelanden mellan klient och server förmedlas av en
mäklare, Object Request Broker (ORB)
– dom går aldrig direkt utan alltid via ORBen
• Både klient och server ”isolerar” implementationen av
klasser med hjälp av IDLer (Interface Description
Language)
Objektets
Klient
implementation
IDL
”Stubbe”
IDL
”Skelett”
Meddelande (Request)
Object Request Broker
previous
next
6
CORBA
...
• På serversidan definierar ett så kallat skelett API:et för
ett serverobjekt
• På klientsidan beskrivs serverns objekt med en så kallad
stubbe
• Ett protokoll som heter IIOP (Internet Inter-ORB
Protocol) definierar hur transport av objekt och
meddelanden mellan server och klienter på binär nivå
sker
– IIOP specificerades i CORBA 2.0, tidigare var inte denna del
standardiserad vilket gjorde att olika implementationer gjorde
på sina egna sätt.
previous
next
7
CORBA
CORBA innehåller flera ”services”
• Några viktiga är
–
–
–
–
–
–
–
–
Lifscykel, grundläggande mekanismer för att skapa, initiera, ta bort objekt mm
Relations, hanterar relationer mellan objekt
Namn, namnger delade objekt så att flera klienter unikt kan referera dem
Persistens, hanterar persistenta objekt, dvs objekt som är långlivade
Extern lagring, kan flytta objekt mellan intern och externa lagringsformer
Transaktion, ger en infrastruktur för att hantera transaktioner
Händelse, låter objekt kommunicera mha händelser
Parallellkontroll, koordinerar objekt och access till delade resurser
• Några andra (ett urval)
– Trader, erbjuder sätt att "hitta" objekt utgående önskad service
– Säkerhet, erbjuder säkerhetsmekanismer som identifiering och auktorisering
– Time, för synkronisering av händelser, hantering av alarm och liknande
previous
next
8
CORBA
Kommunikationen mellan klienter och servrar
• Lös koppling till plattform, programspråk och detaljer
mha
– Adaptorer
• som döljer skillnader
– Brokers
• förmedlar meddelanden
– Bryggor mellan protokoll
• det finns bryggor mellan olika protokoll
previous
next
9
CORBA
CORBA och API-beskrivningar
• I CORBA beskrivs gränssnitten (API:erna) för objekten med så
kallade IDL:er, dvs grässnittsbeskrivningar.
• En IDL påminner till stor del om Java:s gränssnittsbeskrivningar
(dvs Java:s interface).
– En IDL kan dock innehålla konstruktioner som har sitt ursprung i C/C++,
som tex typedef, struct och sequence
– Vidare deklareras parametrar till metoder som antingen
• in, parameterns värde skickas med som argument till metoden, dvs den typ av
parameteröverföring Java använder sig av
• out, parameterns värde sätts i metoden och anropande variabel förändras
• inout, parametern används som både in och out samtidigt
• Gränssnitt organiseras så att ett eller flera gränssnitt definieras i
en modul (eng. module)
previous
next
10
CORBA
Exempel: Steg 1) Gör gränssnittsbeskrivning
module MyApp
{
modulenamnet
blir ett package
i Java då vi "kör"
idltojava
interface MyInterface
{
string myMethod();
};
};
previous
next
och IDL-interfacet
blir ett vanligt
Java-interface
CORBAs string
blir sedan String
i Java då vi implementerar
motsvarande Java-interface
(via idltojava)
11
CORBA
Steg 2) På serversidan ...
• I koden på serversidan kontaktar vi först aktuell ORB
• Därefter skapar vi en referens till namnservern
• Vi skapar ett serverobjekt (dvs en vanlig instans i Java)
och "registrerar" det hos namnservern
• Till slut låter vi servern vänta på att serva anslutande
klienter
• (Vi kan självklart registrera flera objekt på servern om vi vill)
previous
next
12
CORBA
... så här ser det ut i Java ...
• Skapa referens till ORB (args innehåller adress för namnservern)
ORB orb = ORB.init(args, null);
• Fråga ORB om namnserver
org.omg.CORBA.Object nameServiceRef =
orb.resolve_initial_references("NameService");
• Gör om referensen till ett namnkontextobjekt
NamingContext ncRef =
NamingContextHelper.narrow(nameServiceRef);
• Skapa ett en instans av ett objekt som implementerar
MyInterface och registrera det i ORBen
MyServerClass objectRef = new MyServerClass();
orb.connect(objectRef);
previous
next
13
CORBA
... serversidan ...
• Konstruera ett namnkomponentobjekt med ett namn för objektreferensen
som vi vill dela
NameComponent nc =
new NameComponent("MittObjektNamn", "");
NameComponent path[] = {nc};
• Bind objektet objectRef till namnet path i namnservern, så att klienter
kan referera till det. Dvs om någon klient sedan ber namnservern om ett
objekt med detta namn så får den en referens till objectRef.
ncRef.rebind(path, objectRef);
• Vänta på att klienter skall ansluta
java.lang.Object sync = new java.lang.Object();
synchronized (sync) {sync.wait();}
previous
next
14
CORBA
Steg 3) Konstruera klient
På klientsidan refererar vi ORBen på samma sätt som på
serversidan, dvs
• Vi kontaktar namnservern
• Vi ber namnservern om referens till namngivet objekt
• Vi skickar meddelanden till objektet
• (självklart kan vi be namnservern om flera objekt och hantera alla
dessa parallellt på klienten)
previous
next
15
CORBA
... så här ser klientens kod ut i Java ...
• Skapa referens till ORB (args anger adress för namnservern även här)
ORB orb = ORB.init(args, null);
• Fråga ORB om namnserver
org.omg.CORBA.Object nameServiceRef =
orb.resolve_initial_references("NameService");
• Gör om referensen till ett namnkontextobjekt
NamingContext ncRef =
NamingContextHelper.narrow(nameServiceRef);
• Konstruera ett namnkomponentobjekt med samma namn som det objekt
som skapades på serversidan (som synes på exakt samma sätt också)
NameComponent nc = new
NameComponent("MittObjektNamn", "");
NameComponent path[] = {nc};
previous
next
16
CORBA
... klientsidan ...
• Be namnservern om en referens till det objekt som har samma namn som
namnkomponentobjektet
MyInterface objectRef =
MyInterfaceHelper.narrow(ncRef.resolve(path));
Omvandla referensen till
ett Java-objekt
som implementerar
interfacet
Be namnservern
om generiskt CORBAobjekt med givet namn
• Skicka meddelande till serverobjektet (på exakt samma sätt som ett
meddelande till ett icke distribuerat objekt)
String result = objectRef.myMethod();
System.out.println("Serverobjektet svarade: " +
result);
previous
next
17
CORBA
Konstruera klass och IDL
• Konstruera en IDL-beskrivning av gränssnittet mot klassen som konstrueras
– server och klient kan ha olika definitioner (fast ofta används likadan IDL för både
server och klienter)
• Generera hjälpklasser
– i JDK1.2 används kommandot idltojava
• Skriv server med klassbeskrivning och instans för objektet som klienter skall
kunna kommunicera med
– Registrera objektet i ORBen och associera det med globalt namn (så att den unikt
kan identifieras hos server och alla klienter). Vanligen används namnserver.
• Skriv klienter som via ORB och (vanligen) namnserver refererar serverobjektet
och sedan skickar meddelanden till det
previous
next
18
CORBA
IDL (Interface Description Language)
• Ett programspråksneutralt sätt att beskriva en klass
• Några huvuddelar:
– statiskt typat
– "fördefinierade" primitiva typer
any motsvarar
Javas Object
• med long, float, boolean, char, void, any osv
– metoder och argument deklareras med typ
– moduler som innehåller gränssnittsbeskrivningar
– gränssnitt (Interface)
• Kan användas som typ
• Kan ärva från andra interface
• Javas Interface har stora likheter med CORBAs interface
– datatyper, konstanter, operationer, fält, parametrar
• parametrar deklareras med typ och som in, out eller inout
– undantagshantering (exceptions)
• undantag som skall kastas av metoder i klass deklareras i interfaces
previous
next
19
CORBA
... IDL exempel, modul med fyra gränssnitt ...
module CosEventComm {
exception Disconnected {};
Undantag deklareras på
detta sätt
interface PushConsumer {
void push (in any event_data) raises (Disconnected);
void disconnect_push_consumer ();};
event_data:s
värde skickas
med som argument
interface PushSupplier {
void disconnect_push_supplier ();};
interface PullConsumer {
void disconnect_pull_consumer ();};
Kan kasta
undantag
interface PullSupplier {
any pull () raises (Disconnected);
any try_pull (out boolean has_event) raises (Disconnected);
void disconnect_pull_supplier ();};
has_event
ges värde i
metoden try_pull
};
previous
next
20
CORBA
Java IDL
• I Java IDL gör vi först gränssnittsbeskrivningen
– INTERFACE.idl
• Med kommandot idltojava genereras filer som vi kan utnyttja
vid skrivandet av server och klienter
idltojava INTERFACE.idl
– En katalog med samma namn som modulen skapas och en Java-interfacebeskrivning motsvarande IDL-beskrivningen skapas.
– En del hjälpklasser som gör det enkelt att skriva servrar och klienter
konstrueras
– Alla dessa klasser definieras automatiskt tillhöra ett package med samma
namn som modulen (och därmed också den nyskapade katalogens)
previous
next
21
CORBA
...
• Följande fem filer skapas:
INTERFACE.java
• Javaversionen av interfacet
_INTERFACEImplBase.java
• serverskellett som implementerar interfacet
_INTERFACEStub.java
• klientstubbe som implementerar interfacet
INTERFACEHelper.java
• en klass med statiska hjälpmetoder (tex narrow() som
behövs för att ovandla CORBA-objektet till INTERFACEtypen)
INTERFACEHolder.java
• "Håller" en instans av INTERFACE och hjälper till att
hantera out och inout variabler som ju inte
egentligen finns i Java
previous
next
22
CORBA
Exempel: Hello World
• Ett enkelt CORBA-exempel där vi konstruerar ett objekt
på en server som returnerar en sträng till den klient som
ansluter
• Illustrerar hur IDL-beskrivning görs, hur skelett och
stubbar samt andra hjälpklasser automatiskt konstrueras,
hur en server respektive klient konstrueras, hur
namnserver samt server och klient startas
previous
next
23
CORBA
1) Hello World Interface
module HelloApp{
interface Hello {
string sayHello();
};
};
Gränssnittet definierar endast
en metod, sayHello, vars
resultat (returvärde)
är en sträng (string)
• Filen heter HelloApp.idl
previous
next
24
CORBA
2) Skapa hjälpklasser
idltojava -fno-cpp HelloApp.idl
om vi inte vill använda
C-preprocessor
(som inte säkert finns)
• Katalogen HelloApp och följande filer i denna
katalog/package skapas:
Hello.java
_HelloImplBase.java
_HelloStub.java
HelloHelper.java
HelloHolder.java
previous
next
25
CORBA
3) Hello World Server
import
import
import
import
HelloApp.*;
org.omg.CosNaming.*;
org.omg.CosNaming.NamingContextPackage.*;
org.omg.CORBA.*;
här följer en beskrivning
av den klass vars instans vi
vill distribuera
_HelloImplBase implementerar
interfacet Hello.java
och är ett serverskelett,
dvs en brygga mot ORBen
class HelloServant extends _HelloImplBase {
int i = 0;
public String sayHello()
{return "\nHello world !! (no: " + ++i + ")\n";}
}
previous
next
26
CORBA
...
public class HelloServer {
public static void main(String args[])
{ try{ORB orb = ORB.init(args, null);
skapa referens
till
namnserver
instansiera serverobjekt och registrera det i ORBen
konstruera namnobjekt
och bind serverobjektet
till detta namn i
namnservern
previous
next
kontakta ORB
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
NamingContext ncRef =
NamingContextHelper.narrow(objRef);
HelloServant helloRef = new HelloServant();
orb.connect(helloRef);
NameComponent nc = new NameComponent("Hello", "");
NameComponent path[] = {nc};
ncRef.rebind(path, helloRef);
27
CORBA
...
// vänta på att klienter skall ta kontakt
java.lang.Object sync = new java.lang.Object();
synchronized (sync) {
sync.wait();
}
} catch (Exception e) {
System.err.println("ERROR: " + e);
e.printStackTrace(System.out);
}
}}
previous
next
28
CORBA
4) Hello World Klient
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
public class HelloClient {
public static void main(String args[])
{try{ORB orb = ORB.init(args, null);
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
NameComponent nc = new NameComponent("Hello", "");
NameComponent path[] = {nc};
skapa referens till
serverns "Hello"objekt
previous
next
Hello helloRef = HelloHelper.narrow(ncRef.resolve(path));
29
CORBA
...
String hello = helloRef.sayHello();
skicka ett
meddelande
till serverobjektet
System.out.println(hello);
} catch (Exception e) {
System.out.println("ERROR : " + e);
e.printStackTrace(System.out);
}
}}
previous
next
30
CORBA
5) Kompilera och Kör
Kompilera
javac *.java HelloApp/*.java
Kör
a) starta namnserver
tnameserv -ORBInitialPort 1050
b) Starta HelloServer
java HelloServer -ORBInitialPort 1050
c) Kör klient
java HelloClient -ORBInitialPort 1050
previous
next
31
CORBA
Sammanfattning starta och anslut till namnserver
starta namnserver
tnameserv -ORBInitialPort PORTNUMMER
Starta SERVER
java SERVER -ORBInitialHost IPADRESS
-ORBInitialPort PORTNUMMER
Kör KLIENT
java KLIENT -ORBInitialHost IPADRESS
-ORBInitialPort PORTNUMMER
previous
next
32
CORBA
Exempel: på att bla definiera metod i klienten som anropas
av servern
• I IDL-gränssnittet definierar vi ett gränssnitt för ett objekt som
skickas med som parameter från klienten till servern
• Innan klienten anropar servern skapar klienten en instans av detta
"callback-objekt" och registrerar det i ORBen
• Från servern skickar vi ett meddelande till detta objekt som
resulterar att en metod på klientsidan utförs
• Kodexempel i callback-, kylanläggnings-, respektive
meddelandecentralexempel i (också som appendix till utdelade
materialet):
http://www.nada.kth.se/kurser/kth/2D4334/99-00/contents/exempel.html
previous
next
33