28.2. Client development

28.2.1. Receiving files

How to develop client applications for the web services in BASE is, of course, depends on which program language you are using. BASE comes with a simple client API for java for the existing services. If you use this API, you don't have to worry about WSDL files, stubs and skeletons and other web services related stuff. Just use it the client API as any other java API.

The client API can be downloaded with example code from the BASE plug-ins website. The package contains all external JAR files you need, the WSDL files (in case you still want them) and some example code that logs in to a BASE server, lists projects and experiments and then logs out again. Here is a short example of how to login to a BASE server, list the experiments and then logout.

String serviceUrl = "http://your.base.server/base2/services";
String login = "mylogin";
String password = "mypassword";

// Create new session
SessionClient session = new SessionClient(serviceUrl, null, null);

// Login
session.login(login, password, null, false);

// Get all projects and print out name and ID
ExperimentClient ex = new ExperimentClient(session);
ExperimentInfo[] experiments = ec.getExperiments(new QueryOptions());

if (experiments != null && experiments.length > 0)
{
   for (ExperimentInfo info : experiments)
   {
      System.out.println("name=" + info.getName() + "; id=" +info.getId());
   }
}

// Logout
session.logout();

If you want to use another language than Java or you don't want to use our client API, you probably need the WSDL files. These can be found in the client API package discussed above and also in the BASE core distribution in the <base-dir>/misc/wsdl directory. The WSDL files can also be generated on the fly by the BASE server by appending ?wsdl to the url for a specific service. For example, http://your.base.server/base2/services/Session?wsdl.

28.2.1. Receiving files

Some methods can be used to download files or exported data. Since this kind of data can be binary data the usual return methods can't be used. BASE uses a method commonly known as web services with attachments using MTOM (SOAP Message Transmission Optimization Mechanism) to send file data. Read the MTOM Guide from Apache if you want to know more about this.

With the client API it is relatively easy to download a file. Here is a short program example that downloads the CEL files for all raw bioassays in an experiment.

int experimentId = ...
SessionClient session = ...
String fileType = "affymetrix.cel";

// Create clients for experiment and raw bioassay
ExperimentClient ec = new ExperimentClient(session);
RawBioAssayClient rc = new RawBioAssayClient(session);

// Get all raw bioassays in the experiment
RawBioAssayInfo[] rawInfo = ec.getRawBioAssays(experimentId, new QueryOptions());
if (rawInfo == null && rawInfo.length == 0) return;

for (RawBioAssayInfo info : rawInfo)
{
   // We receive the file contents as an InputStream
   InputStream download = rc.downloadRawDataByType(info.getId(), fileType);
   
   // Save to file with the same name as the raw bioassay + .cel
   // assume that there are no duplicates
   File saveTo = new File(info.getName() + ".cel");
   FileUtil.copy(download, new FileOutputStream(saveTo));
}

If you are using another programming language than Java or doesn't want to use the client API you must know how to get access to the received file. The data is sent as a binary attachment to an element in the XML. It is in the interest of the client developer to know how to get access to a received file and to make sure that the programming language/web services framework that is used supports MTOM. Below is a listing which shows an example of a returned message from the RawBioAssayService.downloadRawDataByType() service.


--MIMEBoundaryurn_uuid_1526E5ADD9FC4431651195044149664
Content-Type: application/xop+xml; charset=UTF-8; type="application/soap+xml"
Content-Transfer-Encoding: binary
Content-ID: <0.urn:uuid:1526E5ADD9FC4431651195044149665@apache.org>

<ns:downloadRawDataByTypeResponse xmlns:ns="http://server.ws.basedb.sf.net">
  <ns:return>
    <Test.cel:Test.cel xmlns:Test.cel="127.0.0.1">
       <xop:Include href="cid:1.urn:uuid:1526E5ADD9FC4431651195044149663@apache.org" 
          xmlns:xop="http://www.w3.org/2004/08/xop/include" />
    </Test.cel:Test.cel>
  </ns:return>
</ns:downloadRawDataByTypeResponse>
--MIMEBoundaryurn_uuid_1526E5ADD9FC4431651195044149664
Content-Type: text/plain
Content-Transfer-Encoding: binary
Content-ID: <1.urn:uuid:1526E5ADD9FC4431651195044149663@apache.org>

... binary file data is here ...

Here is a programlisting, that shows how to pick up the file. This is the actual implementation that is used in the web service client that comes with BASE. The InputStream returned from this method is the same InputStream that is returned from, for example, the RawBioAssayClient.downloadRawDataByType() method.

// From AbstractRPCClient.java
protected InputStream invokeFileBlocking(String operation, Object... args)
   throws AxisFault, IOException
{
   //Get the original response element as sent from the server-side
   OMElement response = getService().invokeBlocking(getOperation(operation), args);

   //The file element returned from the service is the first element of the response
   OMElement fileElement = response.getFirstElement();
   
   //The data node always in the first element.
   OMElement dataElement = fileElement.getFirstElement();	
   if (dataElement == null) return null;
   
   //Get the binary node and pick up the inputstream.
   OMText node = (OMText)dataElement.getFirstOMChild();
   node.setBinary(true);
   DataHandler dataHandler = (DataHandler)node.getDataHandler();		
   return dataHandler.getInputStream();
}