[OpenSRF-GIT] OpenSRF branch rel_2_1 updated. osrf_rel_2_1_0-rc1-11-gf6d3808

Evergreen Git git at git.evergreen-ils.org
Wed May 2 16:24:19 EDT 2012


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "OpenSRF".

The branch, rel_2_1 has been updated
       via  f6d38086a42cd6a60d7ed45461d99076cf4d9e5e (commit)
       via  d9487c42a1e3432be9fa3da9b2fad2b42d24a645 (commit)
       via  c4c2d62cdf47ee7e5d02fac44cce5515a77c362c (commit)
       via  d7d8923e98a91c070668a529957d7ee7033529a7 (commit)
       via  ad253eb0d67098b69c71141061563b1802f33f97 (commit)
       via  5b5e28f16be77d9b23a98579d10173103dd907ed (commit)
      from  85830ce301654e2dfefcd186a2bd63bd3785a967 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f6d38086a42cd6a60d7ed45461d99076cf4d9e5e
Author: Dan Scott <dan at coffeecode.net>
Date:   Tue May 1 22:11:00 2012 -0400

    Minor cleanups to Java dependency build process
    
    While configure.ac still hardcodes the expected location of the Java
    dependencies (JSON and Memcached classes), we can clean up some of the
    lower-level challenges with the Java build.
    
    * StAX and WSTX were rolled into the core Java environment long ago,
      so there's no need to download them and even less need to verify
      that the downloaded version exist.
    * The Memcached class is now up to 2.0.1, per deps.sh, but the deps.inc
      file was pointing at 1.5.1.
    * Speaking of the deps.inc file, nothing seems to use it; delete it.
    * The Makefile was dying because the variables for the Memcached and
      JSON classes weren't defined. Define those at the top of the Makefile.
    
    Signed-off-by: Dan Scott <dan at coffeecode.net>

diff --git a/src/java/Makefile.am b/src/java/Makefile.am
index fca8600..bc9615b 100644
--- a/src/java/Makefile.am
+++ b/src/java/Makefile.am
@@ -1,9 +1,12 @@
 DISTCLEANFILES = Makefile.in Makefile
 
+MEMCACHE=java_memcached-release_2.0.1.jar
+JSON=json.jar
+
 JAVAC=javac -J-Xmx256m
 JAVA=java -Xmx256m 
 JAVA_LIBDIR = .lib
-JAVA_LIBS = .:$(OSRF_JAVA_DEPSDIR)/$(WSTX):$(OSRF_JAVA_DEPSDIR)/$(STAX):$(OSRF_JAVA_DEPSDIR)/$(MEMCACHE):$(OSRF_JAVA_DEPSDIR)/$(JSON)
+JAVA_LIBS = .:$(OSRF_JAVA_DEPSDIR)/$(MEMCACHE):$(OSRF_JAVA_DEPSDIR)/$(JSON)
 JAVA_SRC = \
 	org/opensrf/net/xmpp/*.java \
 	org/opensrf/util/*.java \
@@ -15,8 +18,6 @@ JAVA_SRC = \
 all-local:	verify_deps dirs jar
 
 verify_deps:
-	@if [ ! -e "$(OSRF_JAVA_DEPSDIR)/$(WSTX)" ]; then echo -e "\nmissing dependency $(WSTX)!\n" && exit 1; fi
-	@if [ ! -e "$(OSRF_JAVA_DEPSDIR)/$(STAX)" ]; then echo -e "\nmissing dependency $(STAX)!\n" && exit 1; fi
 	@if [ ! -e "$(OSRF_JAVA_DEPSDIR)/$(MEMCACHE)" ]; then echo -e "\nmissing dependency $(MEMCACHE)!\n" && exit 1; fi
 	@if [ ! -e "$(OSRF_JAVA_DEPSDIR)/$(JSON)" ]; then echo -e "\nmissing dependency $(JSON)!\n" && exit 1; fi
 
diff --git a/src/java/deps.inc b/src/java/deps.inc
deleted file mode 100644
index dc21f6c..0000000
--- a/src/java/deps.inc
+++ /dev/null
@@ -1,5 +0,0 @@
-export STAX="stax-api-1.0.1.jar"
-export WSTX="wstx-lgpl-3.2.1.jar"
-export MEMCACHE="java_memcached-release_1.5.1.jar"
-export JSON="json.jar"
-

commit d9487c42a1e3432be9fa3da9b2fad2b42d24a645
Author: Dan Scott <dan at coffeecode.net>
Date:   Tue May 1 22:08:23 2012 -0400

    Clean up root directory: INSTALL, .gitignore, autoreconf
    
    * Update the README to avoid running autoreconf with the "-f" flag.
    * Make the INSTALL file a symbolic link to the README to avoid
      creating a generic INSTALL file each time autoreconf is run.
    * Add a .gitignore file that ignores all of the built files.
    
    Signed-off-by: Dan Scott <dan at coffeecode.net>

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2c1e6ec
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,181 @@
+aclocal.m4
+autom4te.cache/
+bin/opensrf-perl.pl
+bin/osrf_config
+bin/osrf_ctl.sh
+compile
+config.guess
+config.log
+config.status
+config.sub
+configure
+depcomp
+doc/dokuwiki-doc-stubber.pl
+examples/math_bench.pl
+examples/math_client.py
+examples/math_xul_client/Makefile
+examples/multisession-test.pl
+examples/simple_text.py
+install-sh
+libtool
+ltmain.sh
+Makefile
+Makefile.in
+missing
+src/c-apps/.deps/
+src/c-apps/.libs/
+src/c-apps/Makefile
+src/c-apps/Makefile.in
+src/c-apps/osrf_dbmath.la
+src/c-apps/osrf_dbmath.lo
+src/c-apps/osrf_dbmath.o
+src/c-apps/osrf_math.la
+src/c-apps/osrf_math.lo
+src/c-apps/osrf_math.o
+src/c-apps/osrf_version.la
+src/c-apps/osrf_version.lo
+src/c-apps/osrf_version.o
+src/c-apps/timejson
+src/c-apps/timejson.o
+src/gateway/Makefile
+src/gateway/Makefile.in
+src/java/deps/
+src/java/.lib/
+src/java/Makefile
+src/java/Makefile.in
+src/java/opensrf.jar
+src/jserver/.deps/
+src/jserver/Makefile
+src/jserver/Makefile.in
+src/libopensrf/.deps/
+src/libopensrf/libopensrf.la
+src/libopensrf/libopensrf_la-log.lo
+src/libopensrf/libopensrf_la-log.o
+src/libopensrf/libopensrf_la-md5.lo
+src/libopensrf/libopensrf_la-md5.o
+src/libopensrf/libopensrf_la-osrf_application.lo
+src/libopensrf/libopensrf_la-osrf_application.o
+src/libopensrf/libopensrf_la-osrf_app_session.lo
+src/libopensrf/libopensrf_la-osrf_app_session.o
+src/libopensrf/libopensrf_la-osrf_cache.lo
+src/libopensrf/libopensrf_la-osrf_cache.o
+src/libopensrf/libopensrf_la-osrfConfig.lo
+src/libopensrf/libopensrf_la-osrfConfig.o
+src/libopensrf/libopensrf_la-osrf_hash.lo
+src/libopensrf/libopensrf_la-osrf_hash.o
+src/libopensrf/libopensrf_la-osrf_json_object.lo
+src/libopensrf/libopensrf_la-osrf_json_object.o
+src/libopensrf/libopensrf_la-osrf_json_tools.lo
+src/libopensrf/libopensrf_la-osrf_json_tools.o
+src/libopensrf/libopensrf_la-osrf_json_xml.lo
+src/libopensrf/libopensrf_la-osrf_json_xml.o
+src/libopensrf/libopensrf_la-osrf_legacy_json.lo
+src/libopensrf/libopensrf_la-osrf_legacy_json.o
+src/libopensrf/libopensrf_la-osrf_list.lo
+src/libopensrf/libopensrf_la-osrf_list.o
+src/libopensrf/libopensrf_la-osrf_message.lo
+src/libopensrf/libopensrf_la-osrf_message.o
+src/libopensrf/libopensrf_la-osrf_parse_json.lo
+src/libopensrf/libopensrf_la-osrf_parse_json.o
+src/libopensrf/libopensrf_la-osrf_prefork.lo
+src/libopensrf/libopensrf_la-osrf_prefork.o
+src/libopensrf/libopensrf_la-osrf_settings.lo
+src/libopensrf/libopensrf_la-osrf_settings.o
+src/libopensrf/libopensrf_la-osrf_stack.lo
+src/libopensrf/libopensrf_la-osrf_stack.o
+src/libopensrf/libopensrf_la-osrf_system.lo
+src/libopensrf/libopensrf_la-osrf_system.o
+src/libopensrf/libopensrf_la-osrf_transgroup.lo
+src/libopensrf/libopensrf_la-osrf_transgroup.o
+src/libopensrf/libopensrf_la-osrf_utf8.lo
+src/libopensrf/libopensrf_la-osrf_utf8.o
+src/libopensrf/libopensrf_la-sha.lo
+src/libopensrf/libopensrf_la-sha.o
+src/libopensrf/libopensrf_la-socket_bundle.lo
+src/libopensrf/libopensrf_la-socket_bundle.o
+src/libopensrf/libopensrf_la-string_array.lo
+src/libopensrf/libopensrf_la-string_array.o
+src/libopensrf/libopensrf_la-transport_client.lo
+src/libopensrf/libopensrf_la-transport_client.o
+src/libopensrf/libopensrf_la-transport_message.lo
+src/libopensrf/libopensrf_la-transport_message.o
+src/libopensrf/libopensrf_la-transport_session.lo
+src/libopensrf/libopensrf_la-transport_session.o
+src/libopensrf/libopensrf_la-utils.lo
+src/libopensrf/libopensrf_la-utils.o
+src/libopensrf/libopensrf_la-xml_utils.lo
+src/libopensrf/libopensrf_la-xml_utils.o
+src/libopensrf/libosrf_json.la
+src/libopensrf/libosrf_json_la-log.lo
+src/libopensrf/libosrf_json_la-log.o
+src/libopensrf/libosrf_json_la-md5.lo
+src/libopensrf/libosrf_json_la-md5.o
+src/libopensrf/libosrf_json_la-osrf_hash.lo
+src/libopensrf/libosrf_json_la-osrf_hash.o
+src/libopensrf/libosrf_json_la-osrf_json_object.lo
+src/libopensrf/libosrf_json_la-osrf_json_object.o
+src/libopensrf/libosrf_json_la-osrf_json_tools.lo
+src/libopensrf/libosrf_json_la-osrf_json_tools.o
+src/libopensrf/libosrf_json_la-osrf_json_xml.lo
+src/libopensrf/libosrf_json_la-osrf_json_xml.o
+src/libopensrf/libosrf_json_la-osrf_legacy_json.lo
+src/libopensrf/libosrf_json_la-osrf_legacy_json.o
+src/libopensrf/libosrf_json_la-osrf_list.lo
+src/libopensrf/libosrf_json_la-osrf_list.o
+src/libopensrf/libosrf_json_la-osrf_parse_json.lo
+src/libopensrf/libosrf_json_la-osrf_parse_json.o
+src/libopensrf/libosrf_json_la-osrf_utf8.lo
+src/libopensrf/libosrf_json_la-osrf_utf8.o
+src/libopensrf/libosrf_json_la-string_array.lo
+src/libopensrf/libosrf_json_la-string_array.o
+src/libopensrf/libosrf_json_la-utils.lo
+src/libopensrf/libosrf_json_la-utils.o
+src/libopensrf/.libs/
+src/libopensrf/log.o
+src/libopensrf/Makefile
+src/libopensrf/Makefile.in
+src/libopensrf/md5.o
+src/libopensrf/opensrf-c
+src/libopensrf/opensrf.o
+src/libopensrf/osrf_hash.o
+src/libopensrf/osrf_json_object.o
+src/libopensrf/osrf_json_test
+src/libopensrf/osrf_json_test.o
+src/libopensrf/osrf_json_tools.o
+src/libopensrf/osrf_json_xml.o
+src/libopensrf/osrf_legacy_json.o
+src/libopensrf/osrf_list.o
+src/libopensrf/osrf_parse_json.o
+src/libopensrf/osrf_utf8.o
+src/libopensrf/string_array.o
+src/libopensrf/utils.o
+src/Makefile
+src/Makefile.in
+src/perl/blib/
+src/perl/_build/
+src/perl/Build
+src/perl/Makefile
+src/perl/Makefile.in
+src/perl/MYMETA.json
+src/perl/MYMETA.yml
+src/ports/strn_compat/Makefile
+src/python/build/
+src/python/Makefile
+src/python/Makefile.in
+src/python/opensrf.py
+src/router/.deps/
+src/router/.libs/
+src/router/Makefile
+src/router/Makefile.in
+src/router/opensrf_router
+src/router/osrf_router_main.o
+src/router/osrf_router.o
+src/srfsh/.deps/
+src/srfsh/.libs/
+src/srfsh/Makefile
+src/srfsh/Makefile.in
+src/srfsh/srfsh
+src/srfsh/srfsh.o
+tests/.deps/
+tests/Makefile
+tests/Makefile.in
diff --git a/INSTALL b/INSTALL
new file mode 120000
index 0000000..100b938
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1 @@
+README
\ No newline at end of file
diff --git a/README b/README
index ac95ce6..31c11e2 100644
--- a/README
+++ b/README
@@ -81,7 +81,7 @@ source directory to generate the configure script and Makefiles:
 
 [source, bash]
 ------------------------------------------------------------------------------
-autoreconf -f -i
+autoreconf -i
 ------------------------------------------------------------------------------
 
 Configuration and compilation instructions

commit c4c2d62cdf47ee7e5d02fac44cce5515a77c362c
Author: Dan Scott <dan at coffeecode.net>
Date:   Tue May 1 21:31:38 2012 -0400

    Change Java deps.sh to include . in CLASSPATH
    
    Following the directions given by running deps.sh was a little bit
    frustrating; we need to work in some documentation on how to use the
    Java bits of OpenSRF - and perhaps look at a more standard option like
    maven for dependencies.
    
    Signed-off-by: Dan Scott <dan at coffeecode.net>

diff --git a/src/java/deps.sh b/src/java/deps.sh
index c6302ca..17becce 100755
--- a/src/java/deps.sh
+++ b/src/java/deps.sh
@@ -33,5 +33,5 @@ fi
 echo ""
 echo "To compile OpenSRF java:"
 echo ""
-echo "CLASSPATH=deps/$MEMCACHE:deps/$JSON_JAR javac org/opensrf/*.java org/opensrf/net/xmpp/*.java org/opensrf/util/*.java org/opensrf/test/*.java"
+echo "CLASSPATH=deps/$MEMCACHE:deps/$JSON_JAR:. javac org/opensrf/*.java org/opensrf/net/xmpp/*.java org/opensrf/util/*.java org/opensrf/test/*.java"
 echo ""

commit d7d8923e98a91c070668a529957d7ee7033529a7
Author: Bill Erickson <berick at esilibrary.com>
Date:   Fri Mar 16 09:56:13 2012 -0400

    Java Gateway interface improved exception handling
    
    Handle any exceptions that should not reasonably occur in normal
    operation under the covers.  Bubble the rest up.  Update test code with
    examples.
    
    Signed-off-by: Bill Erickson <berick at esilibrary.com>
    Signed-off-by: Dan Scott <dscott at laurentian.ca>

diff --git a/src/java/org/opensrf/net/http/GatewayRequest.java b/src/java/org/opensrf/net/http/GatewayRequest.java
index 00631bf..696d8d4 100644
--- a/src/java/org/opensrf/net/http/GatewayRequest.java
+++ b/src/java/org/opensrf/net/http/GatewayRequest.java
@@ -28,74 +28,75 @@ public class GatewayRequest extends HttpRequest {
         readComplete = false;
     }
 
-    public GatewayRequest send() {
-        try {
-
-            String postData = compilePostData(service, method);
+    public GatewayRequest send() throws java.io.IOException {
+        String postData = compilePostData(service, method);
 
-            urlConn = (HttpURLConnection) httpConn.url.openConnection();
-            urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
-            urlConn.setDoInput(true);
-            urlConn.setDoOutput(true);
+        urlConn = (HttpURLConnection) httpConn.url.openConnection();
+        urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
+        urlConn.setDoInput(true);
+        urlConn.setDoOutput(true);
 
-            OutputStreamWriter wr = new OutputStreamWriter(urlConn.getOutputStream());
-            wr.write(postData);
-            wr.flush();
-            wr.close();
-
-        } catch (java.io.IOException ex) {
-            failed = true;
-            failure = ex;
-        }
+        OutputStreamWriter wr = new OutputStreamWriter(urlConn.getOutputStream());
+        wr.write(postData);
+        wr.flush();
+        wr.close();
 
         return this;
     }
 
-    public Object recv() {
+    public Object recv() throws java.io.IOException {
 
-        if (readComplete) 
-            return nextResponse();
+        if (!readComplete) {
+            readResponses();
+            readComplete = true;
+        }
 
-        try {
+        Object response = nextResponse();
+        if (response == null) 
+            complete = true;
+
+        return response;
+    }
+
+    /**
+     * Reads responses from network and populdates responseList. 
+     */
+    private void readResponses() throws java.io.IOException {
 
-            InputStream netStream = new BufferedInputStream(urlConn.getInputStream());
-            StringBuffer readBuf = new StringBuffer();
+        InputStream netStream = new BufferedInputStream(urlConn.getInputStream());
+        StringBuffer readBuf = new StringBuffer();
 
-            int bytesRead = 0;
-            byte[] buffer = new byte[1024];
+        int bytesRead = 0;
+        byte[] buffer = new byte[1024];
 
-            while ((bytesRead = netStream.read(buffer)) != -1) {
-                readBuf.append(new String(buffer, 0, bytesRead));
-            }
-            
-            netStream.close();
-            urlConn = null;
+        while ((bytesRead = netStream.read(buffer)) != -1) 
+            readBuf.append(new String(buffer, 0, bytesRead));
+        
+        netStream.close();
+        urlConn = null;
 
-            Map<String,?> result = null;
+        // parse the JSON response
+        Map<String,?> result = null;
 
-            try {
-                result = (Map<String, ?>) new JSONReader(readBuf.toString()).readObject();
-            } catch (org.opensrf.util.JSONException ex) {
-                ex.printStackTrace();
-                return null;
-            }
+        try {
+            result = (Map<String, ?>) new JSONReader(readBuf.toString()).readObject();
 
-            String status = result.get("status").toString(); 
-            if (!"200".equals(status)) {
-                failed = true;
-                // failure = <some new exception>
-            }
+        } catch (org.opensrf.util.JSONException ex) {
+            // if this happens, something is wrong
+            Logger.error("Gateway returned bad data " + ex.getStackTrace());
+            return;
+        }
 
-             // gateway always returns a wrapper array with the full results set
-             responseList = (List) result.get("payload"); 
+        // extract the gateway status value
+        String status = result.get("status").toString(); 
 
-        } catch (java.io.IOException ex) { 
-            failed = true;
-            failure = ex;
+        if (!"200".equals(status)) {
+            return;
+            // throw some new exception
         }
 
-        readComplete = true;
-        return nextResponse();
+        // gateway always returns a wrapper array with the full results set
+        responseList = (List) result.get("payload"); 
     }
 
     private String compilePostData(String service, Method method) {
@@ -116,10 +117,15 @@ public class GatewayRequest extends HttpRequest {
         }
 
         try {
+
             // not using URLEncoder because it replaces ' ' with '+'.
             uri = new URI("http", "", null, postData.toString(), null);
+
         } catch (java.net.URISyntaxException ex) {
-            ex.printStackTrace(); 
+
+            // if this happens, something is wrong
+            Logger.error("Error compiling POST data " + ex.getStackTrace());
+            return null;
         }
 
         return uri.getRawQuery();
diff --git a/src/java/org/opensrf/net/http/HttpConnection.java b/src/java/org/opensrf/net/http/HttpConnection.java
index 32fdebc..c40b9f9 100644
--- a/src/java/org/opensrf/net/http/HttpConnection.java
+++ b/src/java/org/opensrf/net/http/HttpConnection.java
@@ -29,12 +29,17 @@ public class HttpConnection {
         url = new URL(fullUrl);
     }
 
+    /** 
+     * Maximun number of threads allowed to communicate with the server.
+     */
     public int getMaxThreads() {
         return maxThreads;
     }
 
     /** 
-     * Set the maximum number of actively communicating threads allowed 
+     * Set the maximum number of actively communicating (async) threads allowed.
+     *
+     * This has no effect on synchronous communication.
      */
     public void setMaxThreads(int max) {
         maxThreads = max;
@@ -66,19 +71,22 @@ public class HttpConnection {
          //thread if necessary, then pass the result to the handler
         Runnable r = new Runnable() {
             public void run() {
-
                 Object response;
-                request.send();
 
-                while ((response = request.recv()) != null) {
-                    if (request.handler != null) 
+                try {
+                    request.send();
+                    while ((response = request.recv()) != null)
                         request.handler.onResponse(request, response);
-                }
 
-                if (request.handler != null)
                     request.handler.onComplete(request);
 
-                activeThreads--;
+                } catch (Exception ex) {
+                    request.handler.onError(request, ex);
+
+                } finally {
+                    // server communication has completed
+                    activeThreads--;
+                }
 
                 if (activeThreads < maxThreads) {
                     try {
diff --git a/src/java/org/opensrf/net/http/HttpRequest.java b/src/java/org/opensrf/net/http/HttpRequest.java
index d91a127..8a4a39f 100644
--- a/src/java/org/opensrf/net/http/HttpRequest.java
+++ b/src/java/org/opensrf/net/http/HttpRequest.java
@@ -8,23 +8,41 @@ import java.net.HttpURLConnection;
 
 public abstract class HttpRequest {
 
+    /** OpenSRF service. */
     protected String service;
+    /** OpenSRF method. */
     protected Method method;
+    /** Connection to server. */
     protected HttpURLConnection urlConn;
+    /** Connection manager. */
     protected HttpConnection httpConn;
-    protected HttpRequestHandler handler;
+
+    /** 
+     * List of responses.
+     *
+     * Responses are not kept after being passed to onResponse .
+     */
     protected List<Object> responseList;
-    protected Exception failure;
-    protected boolean failed;
+
+    /** True if all responses data has been read and delivered */
     protected boolean complete;
 
+    // use a no-op handler by default
+    protected HttpRequestHandler handler = new HttpRequestHandler() {};
+
     public HttpRequest() {
-        failed = false;
         complete = false;
         handler = null;
         urlConn = null;
     }
 
+    /**
+     * Constructor.
+     *
+     * @param conn Connection 
+     * @param service The OpenSRF service.
+     * @param method The method to send to the server.
+     */
     public HttpRequest(HttpConnection conn, String service, Method method) {
         this();
         this.httpConn = conn;
@@ -32,8 +50,14 @@ public abstract class HttpRequest {
         this.method = method;
     }
 
+    /**
+     * Send a request asynchronously (via threads).
+     *
+     * @param handler Manages responses
+     */
     public void sendAsync(final HttpRequestHandler handler) {
-        this.handler = handler;
+        if (handler != null) 
+            this.handler = handler;
         httpConn.manageAsyncRequest(this);
     }
 
@@ -48,19 +72,24 @@ public abstract class HttpRequest {
     }
     
     protected Object nextResponse() {
-        if (complete || failed) return null;
+        if (complete || responseList == null) 
+            return null;
         if (responseList.size() > 0)
             return responseList.remove(0);
         return null;
     }
 
-    public Exception getFailure() {
-        return failure;
-    }
-
-    public abstract HttpRequest send();
+    /**
+     * Send a request to the server.
+     */
+    public abstract GatewayRequest send() throws java.io.IOException;
 
-    public abstract Object recv();
+    /**
+     * Receive one response from the server.
+     *
+     * @return The response object
+     */
+    public abstract Object recv() throws java.io.IOException;
 }
 
 
diff --git a/src/java/org/opensrf/net/http/HttpRequestHandler.java b/src/java/org/opensrf/net/http/HttpRequestHandler.java
index 9c0f9e5..c30a4f6 100644
--- a/src/java/org/opensrf/net/http/HttpRequestHandler.java
+++ b/src/java/org/opensrf/net/http/HttpRequestHandler.java
@@ -1,5 +1,6 @@
 package org.opensrf.net.http;
 
+import org.opensrf.util.*;
 import java.util.List;
 
 /*
@@ -9,8 +10,6 @@ public abstract class HttpRequestHandler {
 
     /**
      * Called when all responses have been received.
-     *
-     * If discardResponses() returns true, will be passed null.
      */
     public void onComplete(HttpRequest request) {
     }
@@ -22,4 +21,8 @@ public abstract class HttpRequestHandler {
      */
     public void onResponse(HttpRequest request, Object response) {
     }
+
+    public void onError(HttpRequest request, Exception ex) {
+        Logger.error("HttpRequest Error: " + ex.getStackTrace());
+    }
 }
diff --git a/src/java/org/opensrf/test/TestGateway.java b/src/java/org/opensrf/test/TestGateway.java
index 967e929..1ac6d90 100644
--- a/src/java/org/opensrf/test/TestGateway.java
+++ b/src/java/org/opensrf/test/TestGateway.java
@@ -10,47 +10,67 @@ import java.util.Arrays;
 
 public class TestGateway {
     
-    public static void main(String[] args) throws java.net.MalformedURLException {
+    public static void main(String[] args) {
 
         if (args.length == 0) {
             System.err.println("Please provide a gateway URL: e.g. http://example.org/osrf-gateway-v1");
             return;
         }
 
-        // configure the connection
-        HttpConnection conn = new HttpConnection(args[0]);
+        try {
 
-        Method method = new Method("opensrf.system.echo");
-        method.addParam("Hello, Gateway");
-        method.addParam(new Integer(12345));
-        method.addParam(new Boolean(true));
-        method.addParam(Arrays.asList(8,6,7,5,3,0,9));
+            // configure the connection
+            HttpConnection conn = new HttpConnection(args[0]);
 
-        // sync test
-        HttpRequest req = new GatewayRequest(conn, "opensrf.math", method).send();
-        Object resp;
-        while ( (resp = req.recv()) != null) {
-            System.out.println("Sync Response: " + resp);
-        }
+            Method method = new Method("opensrf.system.echo");
+            method.addParam("Hello, Gateway");
+            method.addParam(new Integer(12345));
+            method.addParam(new Boolean(true));
+            method.addParam(Arrays.asList(8,6,7,5,3,0,9));
 
-        // exceptions are captured instead of thrown, 
-        // primarily to better support async requests
-        if (req.failed()) {
-            req.getFailure().printStackTrace();
-            return;
-        }
+            // sync test
+            HttpRequest req = new GatewayRequest(conn, "opensrf.math", method).send();
+            Object resp;
+            while ( (resp = req.recv()) != null) {
+                System.out.println("Sync Response: " + resp);
+            }
+
+            // async test
+            for (int i = 0; i < 10; i++) {
+                final int ii = i; // required for nested class
+                HttpRequest req2 = new GatewayRequest(conn, "opensrf.math", method);
+
+                req2.sendAsync(
+                    new HttpRequestHandler() {
 
-        // async test
-        for (int i = 0; i < 10; i++) {
-            final int ii = i; // required for nested class
-            HttpRequest req2 = new GatewayRequest(conn, "opensrf.math", method);
-            req2.sendAsync(
-                new HttpRequestHandler() {
-                    public void onResponse(HttpRequest req, Object resp) {
-                        System.out.println("Async Response: " + ii + " : " + resp);
+                        // called once per response
+                        public void onResponse(HttpRequest req, Object resp) {
+                            System.out.println("Async Response: " + ii + " : " + resp);
+                        }
+
+                        // called after all responses have been received
+                        // used primarily when you don't know how many responses will be returned
+                        public void onComplete(HttpRequest req) {
+                            System.out.println("Async Request complete : " + ii);
+                        }
+
+                        // ruh-roh
+                        public void onError(HttpRequest req, Exception ex) {
+                            if (ex instanceof java.io.IOException) 
+                                System.err.println("Trouble communicating with gateway server!");
+                            ex.printStackTrace();
+                        }
                     }
-                }
-            );
+                );
+            }
+
+        } catch (java.net.MalformedURLException ex) {
+            System.err.println("Malformed Gateway URL! " + args[0]);
+            ex.printStackTrace();
+
+        } catch (java.io.IOException ex) {
+            System.err.println("Trouble communicating with gateway server!");
+            ex.printStackTrace();
         }
     }
 }

commit ad253eb0d67098b69c71141061563b1802f33f97
Author: Bill Erickson <berick at esilibrary.com>
Date:   Thu Mar 15 17:26:16 2012 -0400

    Java gateway interface test class
    
    Signed-off-by: Bill Erickson <berick at esilibrary.com>
    Signed-off-by: Dan Scott <dscott at laurentian.ca>

diff --git a/src/java/org/opensrf/test/TestGateway.java b/src/java/org/opensrf/test/TestGateway.java
new file mode 100644
index 0000000..967e929
--- /dev/null
+++ b/src/java/org/opensrf/test/TestGateway.java
@@ -0,0 +1,58 @@
+package org.opensrf.test;
+
+import org.opensrf.*;
+import org.opensrf.util.*;
+import org.opensrf.net.http.*;
+
+import java.net.URL;
+import java.util.List;
+import java.util.Arrays;
+
+public class TestGateway {
+    
+    public static void main(String[] args) throws java.net.MalformedURLException {
+
+        if (args.length == 0) {
+            System.err.println("Please provide a gateway URL: e.g. http://example.org/osrf-gateway-v1");
+            return;
+        }
+
+        // configure the connection
+        HttpConnection conn = new HttpConnection(args[0]);
+
+        Method method = new Method("opensrf.system.echo");
+        method.addParam("Hello, Gateway");
+        method.addParam(new Integer(12345));
+        method.addParam(new Boolean(true));
+        method.addParam(Arrays.asList(8,6,7,5,3,0,9));
+
+        // sync test
+        HttpRequest req = new GatewayRequest(conn, "opensrf.math", method).send();
+        Object resp;
+        while ( (resp = req.recv()) != null) {
+            System.out.println("Sync Response: " + resp);
+        }
+
+        // exceptions are captured instead of thrown, 
+        // primarily to better support async requests
+        if (req.failed()) {
+            req.getFailure().printStackTrace();
+            return;
+        }
+
+        // async test
+        for (int i = 0; i < 10; i++) {
+            final int ii = i; // required for nested class
+            HttpRequest req2 = new GatewayRequest(conn, "opensrf.math", method);
+            req2.sendAsync(
+                new HttpRequestHandler() {
+                    public void onResponse(HttpRequest req, Object resp) {
+                        System.out.println("Async Response: " + ii + " : " + resp);
+                    }
+                }
+            );
+        }
+    }
+}
+
+

commit 5b5e28f16be77d9b23a98579d10173103dd907ed
Author: Bill Erickson <berick at esilibrary.com>
Date:   Mon Feb 27 18:05:07 2012 -0500

    Java HTTP gateway interface
    
    Supports sync and async requests.  Async requests support onResponse,
    onComplete, and onError handlers.
    
    Supports a max-threads value to limit the number of activately
    communicating threads over any connection.  When max-threads is reached,
    requests are queued and delivered as soon as there is room.
    
    Note that since this is talking to the OpenSRF gateway and not the
    translater, responses are simply collected and passed one at a time to
    onResponse.  They are not streamed.  The goal of supporting onResponse
    is to provide the same client API for both the gateway and translator.
    
    Signed-off-by: Bill Erickson <berick at esilibrary.com>
    Signed-off-by: Dan Scott <dscott at laurentian.ca>

diff --git a/src/java/org/opensrf/net/http/GatewayRequest.java b/src/java/org/opensrf/net/http/GatewayRequest.java
new file mode 100644
index 0000000..00631bf
--- /dev/null
+++ b/src/java/org/opensrf/net/http/GatewayRequest.java
@@ -0,0 +1,129 @@
+package org.opensrf.net.http;
+
+import org.opensrf.*;
+import org.opensrf.util.*;
+
+import java.io.IOException;
+import java.io.BufferedInputStream;
+import java.io.OutputStreamWriter;
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URI;
+import java.net.HttpURLConnection;
+import java.lang.StringBuffer;
+import java.util.List;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class GatewayRequest extends HttpRequest {
+
+    private boolean readComplete;
+
+    public GatewayRequest(HttpConnection conn, String service, Method method) {
+        super(conn, service, method);
+        readComplete = false;
+    }
+
+    public GatewayRequest send() {
+        try {
+
+            String postData = compilePostData(service, method);
+
+            urlConn = (HttpURLConnection) httpConn.url.openConnection();
+            urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
+            urlConn.setDoInput(true);
+            urlConn.setDoOutput(true);
+
+            OutputStreamWriter wr = new OutputStreamWriter(urlConn.getOutputStream());
+            wr.write(postData);
+            wr.flush();
+            wr.close();
+
+        } catch (java.io.IOException ex) {
+            failed = true;
+            failure = ex;
+        }
+
+        return this;
+    }
+
+    public Object recv() {
+
+        if (readComplete) 
+            return nextResponse();
+
+        try {
+
+            InputStream netStream = new BufferedInputStream(urlConn.getInputStream());
+            StringBuffer readBuf = new StringBuffer();
+
+            int bytesRead = 0;
+            byte[] buffer = new byte[1024];
+
+            while ((bytesRead = netStream.read(buffer)) != -1) {
+                readBuf.append(new String(buffer, 0, bytesRead));
+            }
+            
+            netStream.close();
+            urlConn = null;
+
+            Map<String,?> result = null;
+
+            try {
+                result = (Map<String, ?>) new JSONReader(readBuf.toString()).readObject();
+            } catch (org.opensrf.util.JSONException ex) {
+                ex.printStackTrace();
+                return null;
+            }
+
+            String status = result.get("status").toString(); 
+            if (!"200".equals(status)) {
+                failed = true;
+                // failure = <some new exception>
+            }
+
+             // gateway always returns a wrapper array with the full results set
+             responseList = (List) result.get("payload"); 
+
+        } catch (java.io.IOException ex) { 
+            failed = true;
+            failure = ex;
+        }
+
+        readComplete = true;
+        return nextResponse();
+    }
+
+    private String compilePostData(String service, Method method) {
+        URI uri = null;
+        StringBuffer postData = new StringBuffer();
+
+        postData.append("service=");
+        postData.append(service);
+        postData.append("&method=");
+        postData.append(method.getName());
+
+        List params = method.getParams();
+        Iterator itr = params.iterator();
+
+        while (itr.hasNext()) {
+            postData.append("&param=");
+            postData.append(new JSONWriter(itr.next()).write());
+        }
+
+        try {
+            // not using URLEncoder because it replaces ' ' with '+'.
+            uri = new URI("http", "", null, postData.toString(), null);
+        } catch (java.net.URISyntaxException ex) {
+            ex.printStackTrace(); 
+        }
+
+        return uri.getRawQuery();
+    }
+}
+
+
diff --git a/src/java/org/opensrf/net/http/HttpConnection.java b/src/java/org/opensrf/net/http/HttpConnection.java
new file mode 100644
index 0000000..32fdebc
--- /dev/null
+++ b/src/java/org/opensrf/net/http/HttpConnection.java
@@ -0,0 +1,97 @@
+package org.opensrf.net.http;
+
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import org.opensrf.*;
+import org.opensrf.util.*;
+
+
+/**
+ * Manages connection parameters and thread limiting for opensrf json gateway connections.
+ */
+
+public class HttpConnection {
+
+    /** Compiled URL object */
+    protected URL url;
+    /** Number of threads currently communicating with the server */
+    protected int activeThreads;
+    /** Queue of pending async requests */
+    protected Queue<HttpRequest> pendingThreadQueue;
+    /** maximum number of actively communicating threads allowed */
+    protected int maxThreads = 10;
+
+    public HttpConnection(String fullUrl) throws java.net.MalformedURLException {
+        activeThreads = 0;
+        pendingThreadQueue = new ConcurrentLinkedQueue();
+        url = new URL(fullUrl);
+    }
+
+    public int getMaxThreads() {
+        return maxThreads;
+    }
+
+    /** 
+     * Set the maximum number of actively communicating threads allowed 
+     */
+    public void setMaxThreads(int max) {
+        maxThreads = max;
+    }
+
+    /**
+     * Launches or queues an asynchronous request.
+     *
+     * If the maximum active thread count has not been reached,
+     * start a new thread and use it to send and receive the request.
+     * The response is passed to the request's HttpRequestHandler
+     * onComplete().  After complete, if the number of active threads
+     * is still lower than the max, one request will be pulled (if 
+     * present) from the async queue and fired.
+     *
+     * If there are too many active threads, the main request is
+     * pushed onto the async queue for later processing
+     */
+    protected void manageAsyncRequest(final HttpRequest request) {
+
+        if (activeThreads >= maxThreads) {
+            pendingThreadQueue.offer(request);
+            return;
+        }
+
+        activeThreads++;
+
+         //Send the request receive the response, fire off the next 
+         //thread if necessary, then pass the result to the handler
+        Runnable r = new Runnable() {
+            public void run() {
+
+                Object response;
+                request.send();
+
+                while ((response = request.recv()) != null) {
+                    if (request.handler != null) 
+                        request.handler.onResponse(request, response);
+                }
+
+                if (request.handler != null)
+                    request.handler.onComplete(request);
+
+                activeThreads--;
+
+                if (activeThreads < maxThreads) {
+                    try {
+                        manageAsyncRequest(pendingThreadQueue.remove());
+                    } catch (java.util.NoSuchElementException ex) {
+                        // may have been gobbled by another thread
+                    }
+                }
+            }
+        };
+
+        new Thread(r).start();
+    }
+}
+
+
diff --git a/src/java/org/opensrf/net/http/HttpRequest.java b/src/java/org/opensrf/net/http/HttpRequest.java
new file mode 100644
index 0000000..d91a127
--- /dev/null
+++ b/src/java/org/opensrf/net/http/HttpRequest.java
@@ -0,0 +1,66 @@
+package org.opensrf.net.http;
+import org.opensrf.*;
+import org.opensrf.util.*;
+
+import java.util.List;
+import java.util.LinkedList;
+import java.net.HttpURLConnection;
+
+public abstract class HttpRequest {
+
+    protected String service;
+    protected Method method;
+    protected HttpURLConnection urlConn;
+    protected HttpConnection httpConn;
+    protected HttpRequestHandler handler;
+    protected List<Object> responseList;
+    protected Exception failure;
+    protected boolean failed;
+    protected boolean complete;
+
+    public HttpRequest() {
+        failed = false;
+        complete = false;
+        handler = null;
+        urlConn = null;
+    }
+
+    public HttpRequest(HttpConnection conn, String service, Method method) {
+        this();
+        this.httpConn = conn;
+        this.service = service;
+        this.method = method;
+    }
+
+    public void sendAsync(final HttpRequestHandler handler) {
+        this.handler = handler;
+        httpConn.manageAsyncRequest(this);
+    }
+
+    protected void pushResponse(Object response) {
+        if (responseList == null)
+            responseList = new LinkedList<Object>();
+        responseList.add(response);
+    }
+
+    protected List responses() {
+        return responseList;
+    }
+    
+    protected Object nextResponse() {
+        if (complete || failed) return null;
+        if (responseList.size() > 0)
+            return responseList.remove(0);
+        return null;
+    }
+
+    public Exception getFailure() {
+        return failure;
+    }
+
+    public abstract HttpRequest send();
+
+    public abstract Object recv();
+}
+
+
diff --git a/src/java/org/opensrf/net/http/HttpRequestHandler.java b/src/java/org/opensrf/net/http/HttpRequestHandler.java
new file mode 100644
index 0000000..9c0f9e5
--- /dev/null
+++ b/src/java/org/opensrf/net/http/HttpRequestHandler.java
@@ -0,0 +1,25 @@
+package org.opensrf.net.http;
+
+import java.util.List;
+
+/*
+ * Handler for async gateway responses.
+ */
+public abstract class HttpRequestHandler {
+
+    /**
+     * Called when all responses have been received.
+     *
+     * If discardResponses() returns true, will be passed null.
+     */
+    public void onComplete(HttpRequest request) {
+    }
+
+    /**
+     * Called with each response received from the server.
+     * 
+     * @param payload the value returned from the server.
+     */
+    public void onResponse(HttpRequest request, Object response) {
+    }
+}

-----------------------------------------------------------------------

Summary of changes:
 .gitignore                                         |  181 ++++++++++++++++++++
 INSTALL                                            |    1 +
 README                                             |    2 +-
 src/java/Makefile.am                               |    7 +-
 src/java/deps.inc                                  |    5 -
 src/java/deps.sh                                   |    2 +-
 src/java/org/opensrf/net/http/GatewayRequest.java  |  135 +++++++++++++++
 src/java/org/opensrf/net/http/HttpConnection.java  |  105 +++++++++++
 src/java/org/opensrf/net/http/HttpRequest.java     |   95 ++++++++++
 .../org/opensrf/net/http/HttpRequestHandler.java   |   28 +++
 src/java/org/opensrf/test/TestGateway.java         |   78 +++++++++
 11 files changed, 629 insertions(+), 10 deletions(-)
 create mode 100644 .gitignore
 create mode 120000 INSTALL
 delete mode 100644 src/java/deps.inc
 create mode 100644 src/java/org/opensrf/net/http/GatewayRequest.java
 create mode 100644 src/java/org/opensrf/net/http/HttpConnection.java
 create mode 100644 src/java/org/opensrf/net/http/HttpRequest.java
 create mode 100644 src/java/org/opensrf/net/http/HttpRequestHandler.java
 create mode 100644 src/java/org/opensrf/test/TestGateway.java


hooks/post-receive
-- 
OpenSRF


More information about the opensrf-commits mailing list