Katedra Architektury Systemów Komputerowych Wydział Elektroniki, Telekomunikacji i Informatyki Politechniki Gdańskiej dr inż. Paweł Czarnul pczarnul@eti.pg.gda.pl Architektury usług internetowych laboratorium nr 2 Instalacja i uruchomienie usługi sieciowej w serwerze Tomcat/AXIS 1. Wprowadzenie i konfiguracja Celem niniejszego laboratorium jest zainstalowanie i uruchomienie usługi sieciowej. Wykorzystany zostanie serwer Tomcat/AXIS, który pozwoli na zainstalowanie usługi sieciowej napisanej w Javie. Instalacja usługi sieciowej w konfiguracji jw. musi zostać poprzedzona zainstalowaniem serwera Tomcat/AXIS. Wymagana jest również instalacja Javy. Na potrzeby tego laboratorium zakładamy, że pracujemy jako użytkownik student z katalogiem domowym /home/student. Zakładamy, że treść pliku ~/.bashrc zawiera konfigurację dla AXIS 1.4 i Javy (należy zmienić katalog na dystrybucję Javy jeśli jest inna). export JAVA_HOME=/usr/local/jdk1.5.0_07 export AXIS_HOME=/home/student/axis1_4 export AXIS_LIB=$AXIS_HOME/lib export AXISCLASSPATH=$AXIS_LIB/axis.jar:$AXIS_LIB/axisant.jar: $AXIS_LIB/commonsdiscovery0.2.jar:$AXIS_LIB/commonslogging1.0.4.jar:\ $AXIS_LIB/jaxrpc.jar:$AXIS_LIB/saaj.jar:$AXIS_LIB/log4j1.2.8.jar:$AXIS_LIB/wsdl4j
1.5.1.jar export CLASSPATH=$CLASSPATH:$AXISCLASSPATH export PATH=$JAVA_HOME/bin:$PATH Zakładamy ponadto, że serwer Tomcat został zainstalowany w katalogu /home/student/apachetomcat5.5.28 jak również podkatalog webapps/axis dystrybucji AXIS został skopiowany do katalogu webapps serwera Tomcat. Proszę zwrócić uwagę na następujące elementy: 1. AXIS_HOME wskazuje na katalog dystrybucji AXISa (tak, aby AXIS_LIB wskazywał na katalog lib). 2. Do Tomcata trzeba przekopiować katalog axis*/webapps/axis nie zaś axis* z dystrybucją. 2. Publikacja usługi sieciowej w serwerze Tomcat/AXIS Narzędzie AXIS pozwala na publikację usługi sieciowej na dwa sposoby: 1. Dysponując kodem klasy Javy z publicznymi metodami, AXIS pozwala na łatwą i szybką publikację usługi poprzez zamianę rozszerzenia.java na.jws (Java Web Service) i umieszczenie w katalogu AXIS tj. w przykładzie powyżej w katalogu $HOME/apachetomcat5.5.28/webapps/axis. W *tomcat*/webapps/axis powinna znaleźć się implementacja w RunTaskServer.jws. 1. W przypadku konieczności określenia dodatkowych parametrów publikowanej usługi takich jak dostępne dla klienta metody (nie wszystkie metody klasy muszą być udostępniane), ewentualnie narzędzi logujących wywoływanie metod usługi sieciowej i ich parametry (jak pliki logów), należy wykorzystać pliki WSDD, (Web Service Deployment Descriptor), które określają ww. parametry. Instalacja usługi sieciowej zdefiniowanej w pliku deploy.wsdd wygląda następująco: java cp $AXISCLASSPATH:. org.apache.axis.client.adminclient deploy.wsdd
Po uruchomieniu serwera Tomcat poleceniem:./startup.sh (system Linux) w podkatalogu bin głównego katalogu Tomcata (powyżej jest to $HOME/apachetomcat5.5.28), należy zweryfikować poprawność funkcjonowania systemu AXIS poprzez wywołanie http://localhost:8080/axis w oknie przeglądarki. 3. Instalacja przykładowej usługi sieciowej Poniższy przykład ilustruje usługę sieciową, która uruchamia zadaną aplikację na serwerze (w tym przypadku na serwerze, na którym uruchomiony został serwer Tomcat/AXIS). Klasa z metodą realizującą powyższe zadanie może mieć następującą postać: import java.io.*; public class RunTaskServer { public int RunTask(String taskname) { try { Process p = Runtime.getRuntime().exec(taskname); catch (IOException e1) { System.err.println(e1); System.exit(1); return 0; Kod ten umieszczony jest w pliku RunTaskServer.java. W celu łatwej instalacji usługi w serwerze Tomcat/AXIS należy przekopiować ten plik jako RunTaskServer.jws i umieścić w katalogu webapps/axis serwera Tomcat. Po uruchomieniu serwera Tomcat, usługa powinna być dostępna pod następującym URL: http://localhost:8080/axis/runtaskserver.jws co można zweryfikować dzięki przeglądarce
internetowej. 4. Opis usługi sieciowej w języku WSDL Jednocześnie, po instalacji usługi sieciowej jak opisano powyżej, można w łatwy sposób (poprzez odwołanie do URL: http://localhost:8080/axis/runtaskserver.jws?wsdl) uzyskać opis usługi w języku WSDL (Web Service Description Language). W szczególności, opis ten określa sygnatury metod dostępnych w ramach usługi sieciowej, a więc typy argumentów, kolejność argumentów jak również, m.in. lokalizację usługi jw. Opis usługi pozwala klientowi, potencjalnie klientowi dostawcy usług sieciowych, na zdalne wywołanie usługi. Klient, na podstawie opisu w języku WSDL, może napisać i uruchomić program klienta, który pozwoli usługę wywołać. Poniżej przedstawiono opis usługi sieciowej realizującej metodę uruchomienia zadania na serwerze. W szczególności message RunTaskRequest określa argumenty wejściowe metody (tutaj jeden argument typu xsd:string, mapowany w Javie na String), RunTaskRespone argumenty wyjściowe metody (xsd:int, mapowany w Javie na int). Element operation określa nazwę metody i odwołuje się do argumentów zdefiniowanych jako elementy message i opisane powyżej. Element binding określa protokół (SOAP/HTTP), zaś element port lokalizację usługi (tutaj http://localhost:8080/axis/runtaskserver.jws). Są to elementy niezbędne i wystarczające klientowi do wywołania metody danej usługi. <wsdl:definitions targetnamespace="http://localhost:8080/axis/runtaskserver.jws/axis/runtaskserver.jws "> <wsdl:message name="runtaskrequest"> <wsdl:part name="taskname" type="xsd:string"/> </wsdl:message> <wsdl:message name="runtaskresponse"> <wsdl:part name="return" type="xsd:int"/> </wsdl:message> <wsdl:porttype name="runtaskserver">
<wsdl:operation name="runtask" parameterorder="taskname"> <wsdl:input message="intf:runtaskrequest" name="runtaskrequest"/> <wsdl:output message="intf:runtaskresponse" name="runtaskresponse"/> </wsdl:operation> </wsdl:porttype> <wsdl:binding name="runtaskserversoapbinding" type="intf:runtaskserver"> <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="runtask"> <wsdlsoap:operation soapaction=""/> <wsdl:input name="runtaskrequest"> <wsdlsoap:body encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/runtaskserver.jws/axis/runtaskserver.jws" use="encoded"/> </wsdl:input> <wsdl:output name="runtaskresponse"> <wsdlsoap:body encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/runtaskserver.jws/axis/runtaskserver.jws" use="encoded"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="runtaskserverservice"> <wsdl:port binding="intf:runtaskserversoapbinding" name="runtaskserver"> <wsdlsoap:address location="http://localhost:8080/axis/runtaskserver.jws"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
AXIS pozwala na wygenerowanie zarówno plików pomocniczych dla klienta (stub) oraz dla serwera (skeleton, implementacja itd.) w celu odpowiednio napisania programu klienta i implementacji właściwej usługi na podstawie opisu WSDL. W tym przypadku, z punktu widzenia klienta, istotna jest pierwsza funkcja. Wywołanie ma postać: java cp $AXISCLASSPATH:. org.apache.axis.wsdl.wsdl2java RunTaskServer.jws.xml W katalogu localhost, wygenerowane zostaną następujące pliki: RunTaskServer.java RunTaskServerServiceLocator.java RunTaskServerService.java RunTaskServerSoapBindingStub.java Odpowiednie klasy znajdują się w pakiecie localhost. Przykładowa implementacja klienta (uruchomienie programu emacs na serwerze) może wyglądać nastepująco: import java.io.*; import localhost.*; public class RunTaskClient { public static void main(string [] args) throws Exception { RunTaskServerService service = new RunTaskServerServiceLocator(); RunTaskServer port = service.getruntaskserver(); try { port.runtask("emacs"); catch (IOException e) { //
Implementacja ta ukrywa np. lokalizację usługi, która z kolei zakodowana jest w klasach pomocniczych, wygenerowanych wcześniej. Pozwala to klientowi na wywołanie właściwej metody bez implementacji szczegółów określonych już w opisie WSDL. Kod programu powinien zostać umieszczony w katalogu nadrzędnym w stosunku do katalogu pakietu localhost. Wywołanie programu wygląda wówczas następująco: java cp $AXISCLASSPATH:. RunTaskClient Klienta można również zaimplementować w sposób następujący, bez użycia wygenerowanych wcześniej narzędziem WSDL2Java plików: import org.apache.axis.client.call; import org.apache.axis.client.service; import org.apache.axis.encoding.xmltype; import org.apache.axis.utils.options; import javax.xml.rpc.parametermode; public class RunTaskClient1 { public static void main(string [] args) throws Exception { Options options = new Options(args); String endpoint = "http://localhost:" + options.getport() + "/axis/runtaskserver.jws";
args = options.getremainingargs(); String method = "RunTask"; String s1 = new String(args[0]); Service service = new Service(); Call call = (Call) service.createcall(); call.settargetendpointaddress( new java.net.url(endpoint) ); call.setoperationname( method ); call.addparameter( "op1", XMLType.XSD_STRING, ParameterMode.IN ); call.setreturntype( XMLType.XSD_INT ); Integer ret=(integer) call.invoke( new Object [] { s1 ); System.out.println("Got result : " + ret); Wywołanie wygląda wówczas: java RunTaskClient1 emacs
Dla argumentów typu inout lub out, wygenerowane zostaną klasy Holder, które posiadają pole value typu, który opakowują. W ten sposób serwer może przypisać wartości zwracane następnie klientowi. Szczegóły dostępne pod adresem: http://ws.apache.org/axis/java/userguide.html#wsdl2javabuildingstubsskeletonsanddatatypesfromwsdl W przypadku konieczności, przy kompilacji i uruchomieniu, należy podać odpowiednie ścieżki do odpowiednich pakietów np.: javac classpath $AXISCLASSPATH:.... java cp $AXISCLASSPATH:.... Literatura 1. AXIS User's Guide. http://ws.apache.org/axis/java/userguide.html 2. Refsnes Data. WSDL Tutorial. http://www.w3schools.com/wsdl/default.asp