Utilizing VO Standards and Protocols: Server Side

These are notes to accompany this part of the Summer school program. This section is intended to be on Sept. 10 1:30 until break. This is a play along section - you are encouraged to look at the code and do the examples as we go along. Please ask questions at any time. Think more tutorial less lecture.

For this to work you need the Software listed on the the software page .

We shall look at developing some standard DAL services.   

All paths below are from the java level of the summerschool java directory that $NVOSS_HOME on UNIX or %NVOSS_HOME% on windows.

For examples where %VAR% is used the equivalent on UNIX is $VAR. apache.jpg

Simple Cone Shell

Tomcat

First lets make sure our tomcat works. We should check that CATALINA_HOME is properly set.

> dir "%CATALINA_HOME%"
or on UNIX
>  ls $CATALINA_HOME
          

OK if that returns a listing we should be able to use our script to start tomcat:

> starttomcat
          

This will fail if tomcat is already running on the port. The port is set in the server.xml file in the conf directory under CATALINA_HOME. The default is 8080 - but you may change it.  As a reminder, there are additional utilies for managing the server.

> bouncetomcat (to stop and start) or
				
> stoptomcat

If you are having a service error, it may be due to a bad reset or not waiting for the server to complete initialization. In the case of error, sometimes try to reset the server using the utilities provided making sure you allow a few seconds for the initialization to complete. The Tomcat server may be verified at

http:\\localhost:8080\

Java Server Pages (JSP)

JSP is a very quick way to develop highly functional web pages. Effectively each page becomes a java class (a servlet) which is compiled once by the server. When coding in JSP we may intermix java code with actual output such as XML or HTML to create our pages. The .NET framework also now provides a facility like this which are its ASPX pages.

Lets look at the cone service. Effectively it is a web application which takes 3 parameters: RA,DEC,SR. It then needs to do a lookup using this information and provide the answer in a VOTABLE. So a call to a cone service should look like

   coneservice?RA=108&DEC=1.5&SR=0.5

So an easy way to do this would be to make a simple JSP page and have it pull these parameters from the request. Such a page is provided in the distribution package in dev/conserver/coneShell.jsp.

We will walk through the code before we deploy it. This is a nice easy JSP so for deployment all we need to do is copy it to a web directory. The default root of the tomcat installation is in the webapps/ROOT directory so we need to :

> copy coneShell.jsp "%WEB_DEPLOY%"\ROOT
or on UNIX
> cp coneShell.jsp $WEB_DEPLOY/ROOT

Then this will be available at

http://localhost:8080/coneShell.jsp?SR=1&DEC=180&RA=1

But there is no data there yet.

ConeSearch Server from VOTable - WAR Files, Junit, Ant

The simple JSP does not call any other java code. Nor is there any data pulled in to it. Still it is a good starting point and we know it works. A modified version of this is in the web subdirectory called cone.jsp. Normally we may connect this to a database and JDBC is good for that.

Here for simplification we will use an a VOTABLE for our data.  This sample file (abell.xml) is located in the java\data directory.

. This is not efficient nor probably a good way to do this but lets assume the table is small and we can load it all in memory. OK then we need some method which can do a ConeSearch on the loaded data. Thats fairly easy - we need a routine which calculates the angular distance between two points then (again not efficient) we may scan the table and see if the input point is closer than SR to the point in the catalog.

Still in the dev/coneserver you will find a src\sumsch\VOTCone.java. This does all of the above. We shall take a look.

Note:  You need to EDIT the VOTCone.java file and modify the datapath to point to the correct location:

For example on Windows,  it should be

public static String dataPath = System.getProperty("dataPath","\\nvoss2005\\java\\data\\");

The code is in a src directory mainly through convention. You could put it in any directory you like. The readvotable example just has the code in the root directory.

 Lets also have a look at how we might use that in the cone.jsp page.

Junit

Regression testing is essential for any code. Web applications such as we are building debugging is even more difficult. A good level of unit testing will make things go much more smoothly. Junit is a framework for building test cases and running them automatically. The notion of the unit test is to try each small part of the program individually. This may influence the way we write our code. Some testing philosophies suggest writing the tests before the code (eXtreme programming). Some tools however will build entire test suites for existing code (e.g. Jbuilder with Junit plugging - Axis ant also will attempt to build tests for generated stubs).

Whatever the philosophy having the test is good and with ant (more below) and Junit its easy. A simple set of test for VOT cone are in src\sumsch\test\TestVOTCone.java. It conventional to call the Test for a class Test and the individual method test test.

Web Archives (WAR files)

So now we have a JSP file a Java Class and a library (VOTCone uses ivoa-0.3.jar) which we need to deploy. We know we can copy the JSP file to the root and it will work. If we look at the ROOT dir in tomcat we will see a WEB-INF directory. In that there is a classes directory and a lib directory. This is where we can put individual classes (in classes) and jar files (in lib). However you can see how this would get messy with more than one application to deploy.

In fact the structure of ROOT is a web application structure defined for all java application servers. You may create any directory with this structure under webapps of any application server and your application should work. Normally you do not create a directory though you create a jar file which has this structure and contains your entire website. This is give the extension .war. When a war file is copied to the webapps folder the application server unpacks it creating a directory with the same name as the file. Hence if we create a cone.war and drop it in webapps we will have a new cone application. Furthermore app servers check for updates and manage hot deployment - so each time we put a new war file in webapps it will be automatically unpacked to replace the old one. Of course this also allows one to have multiple version of an app or website on the same server.

Building the war file would of course be tedious by hand but most IDEs have a method for doing this and Ant also has a target for it. Time to look at ant.

Ant

Ant is an very useful platform independent build system for java. Its not exactly make nor is it exactly a scripting language but it covers a little of both. Everything in ant is a task and tasks may depend on other tasks. All tasks are defined in xml files. The default name for the file is build.xml. When you type ant it looks for file called build.xml to execute tasks. The xml file is structured as a project which contains properties and targets. The targets generally contain the tasks. Any target may be specified on the the command line after ant is invoked so to get the cone classes compiled we could do

> ant compile 

NOTE You may see and error in the build test,  due to dataPath in build.xml.  HOWEVER it is fine for this exercise as long as you see... 

test: [junit] Testsuite: nvo.test.TestVOTCone [junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 1.041 sec

    <target name="test" depends=    "compile"> <junit fork=
   "yes"> <jvmarg
      value= "-DdataPath=/nvoss2005/java/data/"/>

If we do not specify a target for ant then the default target is used. This is specified in the project declaration

   <project name="cone build file" default="dist" base dir=".">

In the properties we set up useful variables. One special variable to notice is web_deploy - this shows how to pull something from the environment :

   <property environment="env"/>
   <property name="web_deploy" value="${env.WEB_DEPLOY}"/>

We shall look at the tasks in build.xml: javac,junit, war, copy.

Now we may run that test we saw earlier - or any other test which may exist or have been added to the project:

> ant test 
   :
test:
    [junit] Testsuite: nvo.test.TestVOTCone
    [junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.625 sec

Of course we may now also deploy this simply with :

> ant deploy 

We have built cone.war and in it there is the cone.jsp. So this will appear as a new webapp and may be invoked with :

http://localhost:8080/cone/cone.jsp?RA=180&DEC=88&SR=10

System Properties

The correct way to pass setup parms to a WebApplication is using the Context. We can pass the path to this in the conf/web.xml these lines set the path to the abell.xml - you may need to modify it. 

<env-entry>
  <env-entry-name>dataPath</env-entry-name> 
  <env-entry-type>java.lang.String</env-entry-type> 
  <env-entry-value>/nvoss2005/java/data</env-entry-value> 
 </env-entry>

The fast and nasty way is to modify the catalina.bat or catalina.sh and pass the dataPath property do this by adding a line

set JAVA_OPTS=-DdataPath=/nvoss2005/java/data/
This also means your code may be put in a stand alone app.

Simple Image Access Server

The SIA is similar to cone it takes some parameters from the request and returns a VOTable. An SIA server in fact does not return any images only links to images so in a sense it is easier than a ConeSearch. This subdirectory of dev contains a simple image access server. Again it is in the form of a shell.

UseBean

A Java Bean is an object of a class which adheres to the Bean interface standards in java. For our purposes this just means that it has 'get' and 'set' methods to access attributes and these are of the form getAttribute. In the ConeSearch we used the request directly to get data from the request and then managed these in the page. JSP provides a special construct where by we may specify a Java Bean and it will use the 'set' methods of the bean to determine the attributes it should look for in the request. Such beans are very useful as we can put them in the session and pass them around between pages on the server. Its also useful for refilling forms when there is an error or outputting the PARAM elements specified for the SIAP.

src\nvo\SIAbean.java is a bean which we could use for the SIA parameters. Notice it has setSIZE, setPOS and setFORMAT It also has an isOk method which we may use to check the validity of the input. This allows us to take the input validation away form the web page and put it in a neat class - this of course could be used in an app elsewhere.

Once we have the bean using it is easy we just need two lines in our jsp, the first declares the bean for use, the second tells JSP to grab all it can from the request:

NOTE:  you need to edit the class to have the nvo.  with the SIAbean

<jsp:useBean id="sia" scope="page" class="nvo.SIAbean" />
<jsp:setProperty name="sia" property="*" />

jsp:include

Otherwise our JSP is not much different to the one for the cone search. We no longer need to build up the error string as that is now done by the bean so it s little tidier. One other small addition is tho show how part of a JSP file may be included from another file (Server side include basically) . The VOTABLE header is pulled in with :

<jsp:include page="top.xml"/>

As with the previous example there is a test class and a war is built by ant do it all with :

ant deploy

and we can see it on

http://localhost:8080/siap/siapShell.jsp

using a set of sample inputs you can run

http://localhost:8080/siap/siapShell.jsp?POS=12,12&SIZE=0.1&FORMAT=image/fits

SOAP WebServices

At this point we have already heard a little about SOAP/XML and WebServices. The above are not WebServices since they do not contain a machine readable description which allows a set of client stubs to be constructed. Generally when we speak of WebServices we mean a services accepting and transmitting SOAP messages and defined with a WSDL.