The Hasher Web Service

From Plnwiki

Allows to obtain the hash of an archival unit or of the content of one of its URLs.

Operations

WSDL

The Hasher web service WSDL (Web Services Description Language) file, an XML file that describes the functionality of a web service, can be obtained from the LOCKSS web application; if the application is running on port 80 of localhost, the URL

http://localhost/ws/HasherService?wsdl

will display the WSDL file of the Hasher web service.

The WSDL file is particularly useful to automatically generate client stubs and other artifacts.

For Java, two tools that are widely available are wsimport and wsdl2java.

For Python, there is wsdl2py.

Client

The following is an example of a web service client that provides the hash of the archival unit with the identifier

org|lockss|plugin|emerald|EmeraldPlugin&base_url~http%3A%2F%2Fwww%2Eemeraldinsight%2Ecom%2F&journal_issn~0951-3574&volume_name~4

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.URL;
import javax.activation.DataHandler;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import org.lockss.ws.entities.HasherWsParams;
import org.lockss.ws.entities.HasherWsResult;
import org.lockss.ws.hasher.HasherService;

public class HasherWsExample {
  private static final String USER_NAME = "lockss-u";
  private static final String PASSWORD = "lockss-p";
  private static final String ADDRESS_LOCATION =
      "http://localhost:8081/ws/HasherService?wsdl";
  private static final String TARGET_NAMESPACE = "http://hasher.ws.lockss.org/";
  private static final String SERVICE_NAME = "HasherServiceImplService";
  private static final String TIMEOUT_KEY =
      "com.sun.xml.internal.ws.request.timeout";
  // The length of the client connection timeout in seconds.
  private static final int TIMEOUT_VALUE = 600;
  private static final String AU_ID =
      "org|lockss|plugin|emerald|EmeraldPlugin&base_url~http%3A%2F%2Fwww%2Eemeraldinsight%2Ecom%2F&journal_issn~0951-3574&volume_name~4";

  /**
   * The main method.
   * 
   * @param args
   *          A String[] with the command line arguments.
   * @throws Exception
   */
  public static void main(String args[]) throws Exception {
    HasherWsExample example = new HasherWsExample();

    // Authenticate.
    example.authenticate();

    // Get the service.
    Service service = Service.create(new URL(ADDRESS_LOCATION), new QName(
	TARGET_NAMESPACE, SERVICE_NAME));

    HasherService port = service.getPort(HasherService.class);

    // Set the client connection timeout.
    ((javax.xml.ws.BindingProvider) port).getRequestContext().put(TIMEOUT_KEY,
	new Integer(TIMEOUT_VALUE*1000));

    // Set the hashing parameters.
    HasherWsParams params = new HasherWsParams();
    params.setAuId(AU_ID);

    // Call the service and get the results of the operation.
    HasherWsResult result = port.hash(params);

    System.out.println("result = " + result);
    example.handleResultFiles(result, "/tmp");
  }

  /**
   * Sets the authenticator that will be used by the networking code when the
   * HTTP server asks for authentication.
   */
  private void authenticate() {
    Authenticator.setDefault(new Authenticator() {
      @Override
      protected PasswordAuthentication getPasswordAuthentication() {
	return new PasswordAuthentication(USER_NAME, PASSWORD.toCharArray());
      }
    });
  }

  /**
   * Writes to the filesystem any files received with the result of an
   * operation.
   * 
   * @param result
   *          A HasherWsResult with the web service operation result.
   * @param tempDirName
   *          A String with the name of the temporary directory where to write
   *          the files.
   * @throws IOException
   */
  private void handleResultFiles(HasherWsResult result, String tempDirName)
      throws IOException {
    String recordFileName = result.getRecordFileName();
    DataHandler recordFileDataHandler = result.getRecordFileDataHandler();

    if (recordFileName != null && recordFileDataHandler != null) {
      writeFile(recordFileName, recordFileDataHandler, tempDirName);
    }

    String blockFileName = result.getBlockFileName();
    DataHandler blockFileDataHandler = result.getBlockFileDataHandler();

    if (blockFileName != null && blockFileDataHandler != null) {
      writeFile(blockFileName, blockFileDataHandler, tempDirName);
    }
  }

  /**
   * Writes to the filesystem a file received with the result of an operation.
   * 
   * @param fileName
   *          A String with the name of the file.
   * @param dataHandler
   *          A DataHandler with the contents of the file.
   * @param dirName
   *          A String with the name of the directory where to write the file.
   * @throws IOException
   */
  private void writeFile(String fileName, DataHandler dataHandler,
      String dirName) throws IOException {
    File file = new File(dirName, fileName);
    System.out.println("file = " + file.getAbsolutePath());

    // Write the received file.
    InputStream dhis = null;
    FileOutputStream fos = null;
    byte[] buffer = new byte[1024 * 1024];
    int bytesRead = 0;

    try {
      dhis = dataHandler.getInputStream();
      fos = new FileOutputStream(file);

      while ((bytesRead = dhis.read(buffer)) != -1) {
	fos.write(buffer, 0, bytesRead);
      }
    } finally {
      if (dhis != null) {
	try {
	  dhis.close();
	} catch (IOException ioe) {
	  System.out
	  .println("Exception caught closing DataHandler input stream.");
	}
      }

      if (fos != null) {
	fos.flush();
	fos.close();
      }
    }
  }
}