SearchSocket.java

  1. package gov.usgs.earthquake.indexer;

  2. import gov.usgs.earthquake.distribution.FileProductStorage;
  3. import gov.usgs.util.StreamUtils;

  4. import java.io.BufferedInputStream;
  5. import java.io.BufferedOutputStream;
  6. import java.io.InputStream;
  7. import java.io.OutputStream;
  8. import java.io.PipedInputStream;
  9. import java.io.PipedOutputStream;
  10. import java.net.InetAddress;
  11. import java.net.Socket;
  12. import java.util.zip.DeflaterOutputStream;
  13. import java.util.zip.InflaterInputStream;

  14. /**
  15.  * Client side of search socket interface.
  16.  */
  17. public class SearchSocket {

  18.   /** The remote host to connect. */
  19.   private final InetAddress host;

  20.   /** The remote port to connect. */
  21.   private final int port;

  22.   /**
  23.    * Construct a new SearchSocket.
  24.    *
  25.    * @param host the remote host.
  26.    * @param port the remote port.
  27.    */
  28.   public SearchSocket(final InetAddress host, final int port) {
  29.     this.host = host;
  30.     this.port = port;
  31.   }

  32.   /**
  33.    * Send a search request, converting the response to a java object.
  34.    *
  35.    * @param request the request to send.
  36.    * @param storage where received products are stored.
  37.    * @return the response.
  38.    * @throws Exception if error occurs
  39.    */
  40.   public SearchResponse search(final SearchRequest request, final FileProductStorage storage) throws Exception {
  41.     final PipedInputStream pipedIn = new PipedInputStream();
  42.     final PipedOutputStream pipedOut = new PipedOutputStream(pipedIn);

  43.     // parse response in background, while searching
  44.     ResponseParserThread thread = new ResponseParserThread(pipedIn, storage);
  45.     thread.start();

  46.     // start search, sending response xml to response parser thread
  47.     search(request, pipedOut);

  48.     // wait for parsing to complete
  49.     thread.join();

  50.     // either return parsed object, or raise parse exception
  51.     if (thread.getSearchResponse() != null) {
  52.       return thread.getSearchResponse();
  53.     } else {
  54.       throw thread.getParseError();
  55.     }
  56.   }

  57.   /**
  58.    * Send a search request, writing the response to an outputstream.
  59.    *
  60.    * @param request     the request to send.
  61.    * @param responseOut the outputstream to write.
  62.    * @throws Exception if error occurs
  63.    */
  64.   public void search(final SearchRequest request, final OutputStream responseOut) throws Exception {
  65.     Socket socket = null;
  66.     DeflaterOutputStream out = null;
  67.     InputStream in = null;

  68.     try {
  69.       // connect to the configured endpoint
  70.       socket = new Socket(host, port);

  71.       // send the request as compressed xml
  72.       out = new DeflaterOutputStream(new BufferedOutputStream(socket.getOutputStream()));
  73.       SearchXML.toXML(request, new StreamUtils.UnclosableOutputStream(out));

  74.       // must finish and flush to complete Deflater stream
  75.       out.finish();
  76.       out.flush();

  77.       // now read response
  78.       in = new InflaterInputStream(new BufferedInputStream(socket.getInputStream()));
  79.       StreamUtils.transferStream(in, responseOut);
  80.     } finally {
  81.       // make sure socket is closed
  82.       try {
  83.         socket.close();
  84.       } catch (Exception e) {
  85.         // ignore
  86.       }
  87.     }
  88.   }

  89.   /**
  90.    * Thread used for parsing search response in background.
  91.    */
  92.   private static class ResponseParserThread extends Thread {

  93.     /** Input stream being parsed. */
  94.     private InputStream in = null;

  95.     /** Storage where received products are stored. */
  96.     private FileProductStorage storage = null;

  97.     /** The parsed search response. */
  98.     private SearchResponse searchResponse = null;

  99.     /** Parse error, if one happened. */
  100.     private Exception parseError = null;

  101.     public ResponseParserThread(final InputStream in, final FileProductStorage storage) {
  102.       this.in = in;
  103.       this.storage = storage;
  104.     }

  105.     public void run() {
  106.       try {
  107.         searchResponse = SearchXML.parseResponse(in, storage);
  108.       } catch (Exception e) {
  109.         searchResponse = null;
  110.         parseError = e;
  111.       }
  112.     }

  113.     public SearchResponse getSearchResponse() {
  114.       return searchResponse;
  115.     }

  116.     public Exception getParseError() {
  117.       return parseError;
  118.     }
  119.   }

  120. }