Objektorienteret Middleware (TIOOMI)
Presentation 20 :
Value Types in CORBA
Agenda
• Design & Use of DTO’s• Complex “class” types in IDL• Internals of Valuetypes• Mappings
A few words of warning:Assumed students are knowledgeable about OOA/OODWe will only look at some aspects of distributed architectureNot much literature available on this subjectNo textbook solutions to this problemThis lecture is just for inspiration – not a dictate
Design by Layering
• Client Presentation tier• Provides a user interface to the end-users. • Thin/Rich. MVC.
• Server Side Presentation tier• Building a response to the Client Presentation
tier.• Server Side Business Logic tier
• Use Case implementation. Control classes. Business logic.
• Server Side Domain Model tier• Domain Model. Entity classes.
• Enterprise Integration tier• Legacy system. Web services.
• Persistence tier / Resource layer• Relational Database. File-system.
Using D
TO
’s
Replicating Objects /Data Transfer Object PatternHow to do it in CORBA?-NOT IDL Interfaces-IDL Structs-IDL Valuetypes
Complex “Class” Types in IDL• Interface
• CORBA Remote objects communicates “by reference”• Holds attributes and operations (methods)• Gives rise to the “round-tripping” anti-pattern• IDL example: interface BankFacade
• Struct• CORBA struct types are communicated “by value”• Holds only attributes, no methods• No support for inheritance• Maps to “class” type in Java, but “struct” in C++• IDL example: struct Address
• Valuetype• Objects that primarily communicates “by value” (hybrids exists)• Holds both attributes AND methods, no POA, no Object ID• Maps to “class” types in Java and C++• IDL example: valuetype Account
By value
By reference
But we Expected This!
• We would expect the ability to transfer objects “by value” in CORBA
• Java RMI has it, .NET Remoting has it, most SOAP implementation toolkits support it
• So – it should be really easy – right?• It is not
• One need to implement varying amounts of code• Depending on the ORB vendor & language mapping
• A bit of a drag – but not that hard
How does it work
Client Server
InfoImpl
1) Instantiate an Info object and initialize itwith data
2) Send request to interface Greetings – marshal Info object
InfoImpl
3) Use Factory to create and initialize the object – unmarshalling. Findfactory in factory table
Example: - we have a “Greetings Interface (CORBA Object) receiving valuetype Info objects by value. This is a simple DTO pattern implementation
Must “know” the InfoImpl
implementationcode
4) All method calls are performed strictly on the local copy. No marshalling is performed (e.g. setName(…))
Must “know” the InfoImpl
implementationcode
IDL:Info:1.0
IDL:other:1:0Info
Factory
Value Factory Table
We need a mechanism for letting theORB de-serialize the object – automatically,making a “local” instance of the Info object
Unmarshals &instantiates
Valuetypemodule Valtype { valuetype Info { // explicit state to transport: private string _name; private string _message; // public interface: string toString();
// public Factory interface: factory create( in string name, in string message ); };
interface Greetings { // receives and returns an Info valuetype by value Info hello( in Info who); };
};
The Valuetype defined
The Factory Interface for unmarshalling
The “regular” CORBA Object
MiddCor C# MappingInterface / class Description
public interface InfoValueFactory : Middsol.CORBA.portable.ValueFactory
Generated – the interface for the value factory
public abstract class Info : Middsol.CORBA.portable.StreamableValue
Generated – an abstract class. This is the one we need to implement
public class InfoHelper Generated – the Helper class. Contains utility code.
public class InfoDefaultFactory : InfoValueFactory Generated – a “default” factory, so that we need not bother do it ourselves. MiddCor does this for us as a service
Also generated: all classes for the Greetings interface – but this will not be mentioned here
Middcor generates:-All needed functionality for marshalling / unmarshalling-An abstract Info class
The developer must:-Write an Info implementation class (InfoImpl)
MiddCor Generated Default Factory
…public class InfoDefaultFactory : InfoValueFactory{
public System.Object read_value( Middsol.CORBA.portable.InputStream ins ){
return ins.read_value( new InfoImpl() );}public Info create( string a_name, string a_message ){
return (Info) new InfoImpl( a_name, a_message );}
}…
the “create”just calls the constructor
Might be extended – if we need some initialization done
Abstract Info classpublic abstract class Info : Middsol.CORBA.portable.StreamableValue
{protected string _name;protected string _message;abstract public string toString( );virtual public void _write( Middsol.CORBA.portable.OutputStream outpStream ){
outpStream.write_string( this._name );outpStream.write_string( this._message );
}virtual public void _read( Middsol.CORBA.portable.InputStream inpStream ){
this._name = inpStream.read_string();this._message = inpStream.read_string();
}private static string[] __truncatable_ids = {InfoHelper.id()};virtual public string[] _truncatable_ids(){
return __truncatable_ids;}virtual public Middsol.CORBA.TypeCode _type(){
return InfoHelper.type();}
}
From IDL definition
No factory from IDL
Need to Implement InfoImpl Yourself
namespace Valtype{ public class InfoImpl: Valtype.Info { public InfoImpl() { } public InfoImpl( string name, string message ) { _name = name; _message = message; } public string name { set { _name = value; } get { return _name; } } public string message { set { _message = value; } get { return _message; } } public override string toString() { return "Info: " + _name + " says " + _message + " (client implementation)"; } }}
Only _toString() needs to be overridden asthis was the only abstract method
You may add all the methods you
like – if you need themlocally. These may
differ on server & client.Constructors necessary for
factory
The C# Client
public void run( string[] args) { try { m_oOrb = Middsol.CORBA._ORB.init( args, null); Middsol.CORBA.Object oGreetingsObj = m_oOrb.string_to_object( "file://c:\\Valuetype.ior"); Valtype.Greetings oGreetings = Valtype.GreetingsHelper.narrow( oGreetingsObj );
// Create parameter for server call: Valtype.InfoImpl oInfo = new Valtype.InfoImpl(); oInfo.name = "John"; oInfo.message = "The weather is fine!";
System.Console.WriteLine( "\nCall server with Info:\n {0}", oInfo.toString() ); Valtype.Info oRetInfo = oGreetings.hello( oInfo );
System.Console.WriteLine( "\nServer answered Info:\n {0}", oRetInfo.toString() ); m_oOrb.destroy(); } catch( Middsol.CORBA.UserException exUser) { Console.WriteLine("CORBA-UserException\n {0}", exUser.GetType().ToString()); } catch( Middsol.CORBA.SystemException exSys) { Console.WriteLine("CORBA-SystemException\n {0}", exSys.ID); }
Instantiated an object &Initialize it with data
Make the remote call andGet an InfoImpl returned
Marshalling of valuetype here – and demarshalling at server using factory
The C# Server (Server & Impl in One Class!)
public void run( string[] args) { try { m_oOrb = Middsol.CORBA._ORB.init( args, null); m_oRootPOA = Middsol.PortableServer.POAHelper.narrow( m_oOrb.resolve_initial_references( "RootPOA" )); m_oRootPOA.the_POAManager.activate(); GreetingsImpl oGreetings = new GreetingsImpl(); Middsol.CORBA._ORB.wrIORtoFile( "c:\\Valuetype.ior", oGreetings._this() ); System.Console.WriteLine("Server is running..." ); m_oOrb.run(); m_oOrb.destroy(); } catch( Middsol.CORBA.UserException exUser) { Console.WriteLine("CORBA-UserException\n {0}", exUser.GetType().ToString()); } catch( Middsol.CORBA.SystemException exSys) { Console.WriteLine("CORBA-SystemException\n {0}", exSys.ID); }
Bring up the Greetings Object
public class GreetingsImpl: Valtype.GreetingsPOA
{ public override Valtype.Info hello( Valtype.Info theInfo ) {
System.Console.WriteLine("\nhello called with\n {0}", theInfo.toString());
Valtype.InfoDefaultFactory oFactory = new Valtype.InfoDefaultFactory(); Valtype.Info oInfo = oFactory.create( "Jack", "The weather will be bad!" );
System.Console.WriteLine("\nReturning\n {0}", oInfo.toString()); return oInfo; } }
The “hello” method implementation
Implicit unmarshalling – ready to use
Make a new Info object (youdo not have to use the factory)
Sun ORB Java MappingInterface / class Description
public abstract class Info implements org.omg.CORBA.portable.StreamableValue
Generated – an abstract class. This is the one we need to implement
abstract public class InfoHelper Generated – the Helper class. Contains utility code.
public final class InfoHolder implements org.omg.CORBA.portable.Streamable
Generated – the Holder class
public interface InfoValueFactory extends org.omg.CORBA.portable.ValueFactory
Generated – an interface for the factory
public class InfoDefaultFactory implements InfoValueFactory
Generated – a “default” factory, so that we need not bother do it ourselves
Also generated: all classes / interfaces for the Greetings interface – but this will not be mentioned here
SUN Java ORB Generates:-All needed functionality for marshalling / unmarshalling-An abstract Info class (so the same as Middcor + Holder)-We still need to implement the InfoImpl class
public class InfoImpl extends Info{
public InfoImpl() { } public InfoImpl( String name, String message ) { _name = name; _message = message; }
public String _toString() { return "Name: "+_name+" Message: "+_message; };
}
You may add all the methods youlike – if you need them locally. These maydiffer on server & client. Constructors are
nessecary for the factory
Java InfoImpl Implementation
Only _toString() needs to be overridden asthis was the only abstract method
Maybe you want getter and setter methods?
The Java Client
public static void main(String args[]) {
try{ // create and initialize the ORB org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);
// Get the stringified object reference and destringify it. java.io.BufferedReader in = new java.io.BufferedReader(new java.io.FileReader("c:\\Valuetype.ior")); String ref = in.readLine(); org.omg.CORBA.Object obj = orb.string_to_object(ref) ;
Greetings oGreetings = GreetingsHelper.narrow(obj);
// Create parameter for the server InfoImpl oInfo = new InfoImpl("Stefan", "Another Hello World Call");
// call the Greetings server object and print results Info oRetInfo = oGreetings.hello( oInfo );
System.out.println(oRetInfo._toString());
} catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out);}
}
Seems familiar?
Orbacus ORB C++Interface / class Description
class Info : virtual public ::CORBA::ValueBase Generated – abstract Info class
typedef OB::ObjVar< Info > Info_var Generated Info_var type for easy memory management
class Info_init : public ::CORBA::ValueFactoryBase Generated – abstract ValueFactoryBase
Also generated: all classes for the Greetings interface – but this will not be mentioned here
Orbacus ORB- We need to implement both Info object and the factory
Other Valuetype possibilites
• There are other valuetypes which we shall not discuss here (not part of curriculum)• Abstract value
• May be used for polymorphic reasons• Abstract interface
• May be used for polymorphic reasons for determining the interface at runtime
• Pass by reference semantics of operations• attributes are transferred by value• operations ”supports” by reference• Use the ”supports” keyword
• Results is rather non-transparent semantics
Remember
• Valuetypes are for implementing the DTO / replicating objects pattern to avoid the round-trip anti-pattern AND reduce the number of CORBA objects running at server
• But it is also just a convenient way of moving data in general between all layers
• Sometimes you may just want to use “structs” – and maybe map these to objects at the receiving side
• Check your ORB vendor for compliance – and generation support
Group Work
• When using OR-mappers: EJB, JPA, Hibernate, NHibernate, LLBLGen, or DB4O as the Persistency Layer
• Discuss (10 minutes): • Which design implications will it have whether you
select structs or valuetypes for DTO/replicating objects pattern?
• Which potential challenges do you see with regards to mapping valuetypes and OR-mapper object types
• Would RDBMS/SQL be better suited?• Plenum (5 minutes):
• Let’s discuss your results
Læringsmål Alignment
Når kurset er færdigt forventes den studerende at kunne:• Definere, beskrive og sammenligne forskellige typer
af objektorienterede middleware frameworks til apparater og computere, med primær fokus på CORBA og sekundært .NET Remoting teknologierne, herunder fordele og ulemper forbundet med de forskellige teknologier
• Definere og beskrive principper omkring transparens og heterogenitet i relation til middlewareteknologier
• Definere og beskrive gængse teorier, metoder og retningslinier indenfor det objektorienterede middleware paradigme og anvende disse til at designe effektive distribuerede systemer
• Designe og konstruere et distribueret system der gør brug af CORBA og .NET Remoting teknologierne med tilhørende værktøjssupport
CORBA valuetypes er et væsentligt
element i CORBA’s arkitektur.
mange andre teknologier er Dog bedre end CORBA her
CORBA valuetypes er et væsentligt
element i CORBA’s arkitektur.
mange andre teknologier er Dog bedre end CORBA her
MANGLER: hvordan I praktisk omsætter denne viden. Fås ved øvelse og projekt.
Valuetypes er vigtige forAccess Transperency og
heterogenitet
Valuetypes er vigtige forAccess Transperency og
heterogenitet
Meget væsentligt arkitekturAspekt at berherske
Valuetypes og forskelleneMed andre komplekse typer
Meget væsentligt arkitekturAspekt at berherske
Valuetypes og forskelleneMed andre komplekse typer