Abgabe bis zum 09.06.2014 9.00 über Goya Zur Einführung soll eine einfache Börsenanwendung mit Hilfe von CORBA realisiert werden. Die Anwendung gliedert sich in einen Server, der Informationen über Aktien (z.B. Kurse) bereitstellt, und einem Client, der diese Informationen abfragen kann. Teil A - ServerDer Server soll folgende Funktionalitäten bereitstellen:
Verwenden Sie bitte folgende IDL-Schnittstellendefinitionen. module stocks { struct StockInfo { string name; string symbol; string ISIN; enum StockType { common_stock, preferred_stock, tresury_stock } type; struct StockQuote { long high; long low; long last; } quote; };
exception InvalidStock {}; exception InvalidQuoter {};
interface Quoter { readonly attribute string quoter_name; long get_quote (in string stock_name) raises (InvalidStock); };
interface StockQuoter : Quoter { StockInfo get_stock_info (in string stock_name) raises (InvalidStock); };
interface QuoterFactory { Quoter create_quoter (in string name) raises (InvalidQuoter); }; }; Implementationssprache für den Server ist C++ unter Verwendung von MICO CORBA (http://www.mico.org, Installation siehe unten). Zur Vereinfachung liefern alle Quoter gleiche Daten, die fest programmiert sein können. Dabei sollen mindestens die folgenden Sätze abfragbar sein:
Teil B – ClientDer Client ist eine Konsolenanwendung (console application), die dem Nutzer eine einfache Kommandozeile bietet. Er soll in der Sprache Java mit Hilfe des integrierten Java ORB realisiert werden. Der Client besteht konzeptuell aus 2 Teilen: einem "Bibliotheksteil" und der Nutzerschnittstelle. Der Bibliotheksteil implementiert die nachfolgende Java-Schnittstelle und interagiert mit dem Server über die in IDL definierte Schnittstelle. Die Aufgabe des Bibliotheksteils ist das Transformieren der eingehenden Aufrufe (auf der unten stehenden Java-Schnittstelle) in Aufrufe an den Server (über die IDL-Schnittstelle). Die Nutzerschnittstelle stellt dem Benutzer eine Kommandozeile zur Verfügung und interagiert mit dem Bibliotheksteil über die nachfolgende Java-Schnittstelle. Bitte definieren Sie die Kommandosprache selbst. Die Implementierungsklasse für das Interface ClientQuoterFactory soll den Namen ClientQuoterFactoryImpl tragen und das ORB-Objekt als einzigen Parameter für den Konstruktor verwenden (siehe dazu die Methode setUp() der Unittest-Klasse). Diese Zweiteilung des Client ist nicht CORBA-typisch. Sie ist nötig, um sowohl Client als auch Server mit einem Unittest unter Java testen zu können (siehe dazu die unten aufgeführte Testklasse und die Variablen _serverFactory und _clientFactory). package stocks.client;
public class InvalidStockException extends Exception {} public class InvalidQuoterException extends Exception {}
public interface ClientStock { public static final int common_stock = 0; public static final int preferred_stock = 1; public static final int tresury_stock = 2;
String getName(); String getSymbol(); String getISIN(); int getStockType(); long getHigh(); long getLow(); long getLast(); }
public interface ClientStockQuoter { String getQuoterName();
ClientStock getStock ( String stock_name) throws InvalidStockException; }
public interface ClientQuoterFactory { ClientStockQuoter create_quoter (String name) throws InvalidQuoterException; } Abgabe und BewertungBegründen Sie die von Ihnen getroffenen Design-Entscheidungen und beschreiben Sie aufgetretene Besonderheiten und Probleme. Benutzen Sie dafür eine HTML Datei mit dem Namen index.html. Abzugeben sind weiterhin die Quelltexte der Lösung und ein Ant Skript mit dem Namen build.xml, das die Quellen mit den gängigen Werkzeugen automatisiert übersetzt (Bitte die Targets compile, test und clean definieren. Der Server wird jeweils separat von Hand gestartet.). Der Server soll mit einem Shell-Script build.bat/build.sh übersetzt werden. Sie können davon ausgehen, dass die Umgebungsvariable MICO_HOME auf das Installtionsverzeichnis des MICO ORB gesetzt ist, dass das Verzeichnis MICO_HOME/bin im Suchpfad PATH und MICO_HOME/lib im Bibliothekspfad LD_LIBRARY_PATH ist und dass make/nmake verfügbar ist. Bitte schreiben sie ein weiteres Script server.sh/server.bat, dass den Server startet. Bitte reichen Sie die geforderten Dateien in ein ZIP Archiv gepackt ein. Für Test und Bewertung kommt die Unit-Test-Bibliothek jUnit (www.junit.org) zum Einsatz. Die geforderte Funktionalität wird anhand von 10 Unit-Tests überprüft, von denen Ihnen vorab die folgenden 5 zur Verfügung stehen. package stocks.test; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.InputStreamReader; import org.omg.CORBA.ORB;
import stocks.*; import stocks.StockInfoPackage.StockType; import stocks.client.*; import junit.framework.TestCase; import org.junit.*;
public class StockQuoterTest extends TestCase { QuoterFactory _serverFactory = null; ClientQuoterFactory _clientFactory = null; ORB _orb = null;
public static void main(String[] args) { junit.textui.TestRunner.run(StockQuoterTest.class); }
public StockQuoterTest(String name) { super(name); }
@Before protected void setUp() throws Exception { super.setUp();
String[] args = null; _orb = ORB.init(args,null);
_clientFactory = new ClientQuoterFactoryImpl(_orb);
String filename = "quoter_factory.ior"; FileInputStream fis = new FileInputStream(filename); BufferedReader d = new BufferedReader(new InputStreamReader(fis)); String ior = d.readLine();
org.omg.CORBA.Object obj = _orb.string_to_object(ior); _serverFactory = QuoterFactoryHelper.narrow(obj); }
@After protected void tearDown() throws Exception { super.tearDown();
_clientFactory = null; _serverFactory = null; _orb = null; }
@Test public void test1() throws Exception { String name = "Dow Jones"; Quoter dowjones = _serverFactory.create_quoter(name); assertEquals( name, dowjones.quoter_name() );
int iQuote = dowjones.get_quote("Boeing"); assertEquals( 67, iQuote ); }
@Test public void test2() throws Exception { Quoter obj = _serverFactory.create_quoter("Dow Jones"); StockQuoter dowjones = StockQuoterHelper.narrow(obj); }
@Test public void test3() throws Exception { Quoter obj = _serverFactory.create_quoter("Dow Jones"); StockQuoter dowjones = StockQuoterHelper.narrow(obj);
String name = "Intel"; StockInfo intel = dowjones.get_stock_info(name); assertEquals( name, intel.name ); assertEquals( "INTC", intel.symbol ); assertEquals( "US4581401001", intel.ISIN ); assertEquals( StockType._tresury_stock, intel.type.value() ); assertEquals( 29, intel.quote.high ); assertEquals( 27, intel.quote.low ); assertEquals( 27, intel.quote.last ); }
@Test public void test6() throws Exception { String name = "Dow Jones"; ClientStockQuoter dowjones = _clientFactory.create_quoter(name); assertEquals( name, dowjones.getQuoterName() );
ClientStock boeing = dowjones.getStock("Boeing"); assertEquals( 67, boeing.getLast() ); }
@Test public void test7() throws Exception { ClientStockQuoter dowjones = _clientFactory.create_quoter("Dow Jones");
String name = "Intel"; ClientStock intel = dowjones.getStock(name); assertEquals( name, intel.getName() ); assertEquals( "INTC", intel.getSymbol() ); assertEquals( "US4581401001", intel.getISIN() ); assertEquals( ClientStock.tresury_stock, intel.getStockType() ); assertEquals( 29, intel.getHigh() ); assertEquals( 27, intel.getLow() ); assertEquals( 27, intel.getLast() ); } } HinweiseBehandeln Sie auch Fehler- und Ausnahmesituationen entsprechend. Bedenken Sie, dass unter Umständen auch mehrere Clients gleichzeitig auf den Server zugreifen können. Da die IDL-Schnittstelle fest vorgegeben ist, können Sie Ihren Server bzw. Client auch mit denen anderer Praktikumsgruppen betreiben. Für die CORBA IDL existieren weitere Sprachabbildungen, beispielsweise für Python, Pascal, TCL, Perl, C, Ada, etc. (siehe http://en.wikipedia.org/wiki/Corba). Interessierte Praktikumsgruppen können zusätzlich Client oder Server in diesen Sprachen realisieren. Benötigte SoftwareJava SDK 1.5 oder höher. Der IDL-Compiler für die Übersetzung nach Java heißt idlj.MICO CORBAMICO lässt sich mit GCC/Linux oder unter Windows mit GCC/Cygwin
oder dem MS Visual C++ Compiler übersetzen.
Nach erfolgreicher Installation sind in MICO_HOME/bin Wrapper-Scripte für die Aufrufe von Compiler, Linker & Co. zu finden. Diese Scripte haben den Prefix "mico-", beispielsweise mico-c++ für den C++-Compiler. Für die Übersetzung sollten möglichst diese Scripte verwendet werden, da sie die benötigten Pfade, Bibliotheken usw. an die zugrunde liegenden Werkzeuge weitergeben. LiteraturMichi Henning, Steve Vinoski: "Advanced CORBA(R) Programming with C++" [amazon] |
|