You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by si...@apache.org on 2012/03/25 18:30:59 UTC

svn commit: r1305074 [1/2] - in /lucene/dev/branches/branch_3x: dev-tools/eclipse/ dev-tools/maven/ dev-tools/maven/solr/solrj/ solr/ solr/lib/ solr/solrj/src/java/org/apache/solr/client/solrj/impl/ solr/solrj/src/test/org/apache/solr/client/solrj/ sol...

Author: siren
Date: Sun Mar 25 16:30:58 2012
New Revision: 1305074

URL: http://svn.apache.org/viewvc?rev=1305074&view=rev
Log:
SOLR-2020: Add Java client that uses Apache Http Components http client (4.x)

Added:
    lucene/dev/branches/branch_3x/solr/lib/httpclient-4.1.3.jar   (with props)
    lucene/dev/branches/branch_3x/solr/lib/httpclient-LICENSE-ASL.txt
    lucene/dev/branches/branch_3x/solr/lib/httpclient-NOTICE.txt
    lucene/dev/branches/branch_3x/solr/lib/httpcore-4.1.4.jar   (with props)
    lucene/dev/branches/branch_3x/solr/lib/httpcore-LICENSE-ASL.txt
    lucene/dev/branches/branch_3x/solr/lib/httpcore-NOTICE.txt
    lucene/dev/branches/branch_3x/solr/lib/httpmime-4.1.3.jar   (with props)
    lucene/dev/branches/branch_3x/solr/lib/httpmime-LICENSE-ASL.txt
    lucene/dev/branches/branch_3x/solr/lib/httpmime-NOTICE.txt
    lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrServer.java
    lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java
    lucene/dev/branches/branch_3x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTestHttpSolrServer.java
    lucene/dev/branches/branch_3x/solr/solrj/src/test/org/apache/solr/client/solrj/TestBatchUpdateHttpSolrServer.java
    lucene/dev/branches/branch_3x/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleConcurrentUpdateSolrServerTest.java
Modified:
    lucene/dev/branches/branch_3x/dev-tools/eclipse/dot.classpath
    lucene/dev/branches/branch_3x/dev-tools/maven/pom.xml.template
    lucene/dev/branches/branch_3x/dev-tools/maven/solr/solrj/pom.xml.template
    lucene/dev/branches/branch_3x/solr/CHANGES.txt
    lucene/dev/branches/branch_3x/solr/build.xml
    lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CommonsHttpSolrServer.java
    lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/StreamingUpdateSolrServer.java

Modified: lucene/dev/branches/branch_3x/dev-tools/eclipse/dot.classpath
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/dev-tools/eclipse/dot.classpath?rev=1305074&r1=1305073&r2=1305074&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/dev-tools/eclipse/dot.classpath (original)
+++ lucene/dev/branches/branch_3x/dev-tools/eclipse/dot.classpath Sun Mar 25 16:30:58 2012
@@ -160,6 +160,9 @@
 	<classpathentry kind="lib" path="solr/contrib/velocity/lib/commons-collections-3.2.1.jar"/>
 	<classpathentry kind="lib" path="solr/contrib/velocity/lib/velocity-1.6.4.jar"/>
 	<classpathentry kind="lib" path="solr/contrib/velocity/lib/velocity-tools-2.0.jar"/>
+	<classpathentry kind="lib" path="solr/lib/httpclient-4.1.3.jar"/>
+	<classpathentry kind="lib" path="solr/lib/httpcore-4.1.4.jar"/>
+	<classpathentry kind="lib" path="solr/lib/httpmime-4.1.3.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>

Modified: lucene/dev/branches/branch_3x/dev-tools/maven/pom.xml.template
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/dev-tools/maven/pom.xml.template?rev=1305074&r1=1305073&r2=1305074&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/dev-tools/maven/pom.xml.template (original)
+++ lucene/dev/branches/branch_3x/dev-tools/maven/pom.xml.template Sun Mar 25 16:30:58 2012
@@ -155,6 +155,16 @@
         <version>3.1</version>
       </dependency>
       <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpclient</artifactId>
+        <version>4.1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpmime</artifactId>
+        <version>4.1.3</version>
+      </dependency>
+      <dependency>
         <groupId>commons-lang</groupId>
         <artifactId>commons-lang</artifactId>
         <version>2.6</version>

Modified: lucene/dev/branches/branch_3x/dev-tools/maven/solr/solrj/pom.xml.template
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/dev-tools/maven/solr/solrj/pom.xml.template?rev=1305074&r1=1305073&r2=1305074&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/dev-tools/maven/solr/solrj/pom.xml.template (original)
+++ lucene/dev/branches/branch_3x/dev-tools/maven/solr/solrj/pom.xml.template Sun Mar 25 16:30:58 2012
@@ -55,6 +55,24 @@
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpclient</artifactId>
+      <scope>runtime</scope>
+      <optional>true</optional>
+      <exclusions>
+        <exclusion>
+          <groupId>commons-logging</groupId>
+          <artifactId>commons-logging</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpmime</artifactId>
+      <scope>runtime</scope>
+      <optional>true</optional>
+    </dependency>
     <!-- Technically, this is optional in SolrJ; but it's fast. SOLR-2852 -->
     <dependency>
       <groupId>org.codehaus.woodstox</groupId>

Modified: lucene/dev/branches/branch_3x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/CHANGES.txt?rev=1305074&r1=1305073&r2=1305074&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_3x/solr/CHANGES.txt Sun Mar 25 16:30:58 2012
@@ -49,6 +49,9 @@ Upgrading from Solr 3.5
 
 New Features
 ----------------------
+* SOLR-2020: Add Java client that uses Apache Http Components http client (4.x).
+  (Chantal Ackermann, Ryan McKinley, Yonik Seeley, siren)
+
 * SOLR-2854: Now load URL content stream data (via stream.url) when called for during request handling,
   rather than loading URL content streams automatically regardless of use.
   (David Smiley and Ryan McKinley via ehatcher)

Modified: lucene/dev/branches/branch_3x/solr/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/build.xml?rev=1305074&r1=1305073&r2=1305074&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/build.xml (original)
+++ lucene/dev/branches/branch_3x/solr/build.xml Sun Mar 25 16:30:58 2012
@@ -313,6 +313,7 @@
           description="Creates the Solr WAR Distribution file.">
     <ant dir="webapp" target="dist" inheritall="false">
       <propertyset refid="uptodate.and.compiled.properties"/>
+      <property name="exclude.from.war" value="httpclient-*,httpcore-*,httpmime-*" />
     </ant>
   </target>
   
@@ -320,7 +321,7 @@
           description="Creates a Solr WAR Distribution file, excluding slf4j bindings.">
     <ant dir="webapp" target="dist" inheritall="false">
       <propertyset refid="uptodate.and.compiled.properties"/>
-      <property name="exclude.from.war" value="*over-slf4j*,slf4j-jdk14*" />
+      <property name="exclude.from.war" value="*over-slf4j*,slf4j-jdk14*,httpclient-*,httpcore-*,httpmime-*" />
       <property name="solr.war.suffix" value="-excl-slf4j" />
     </ant>
   </target>

Added: lucene/dev/branches/branch_3x/solr/lib/httpclient-4.1.3.jar
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/lib/httpclient-4.1.3.jar?rev=1305074&view=auto
==============================================================================
Binary file - no diff available.

Added: lucene/dev/branches/branch_3x/solr/lib/httpclient-LICENSE-ASL.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/lib/httpclient-LICENSE-ASL.txt?rev=1305074&view=auto
==============================================================================
--- lucene/dev/branches/branch_3x/solr/lib/httpclient-LICENSE-ASL.txt (added)
+++ lucene/dev/branches/branch_3x/solr/lib/httpclient-LICENSE-ASL.txt Sun Mar 25 16:30:58 2012
@@ -0,0 +1,182 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+   
+This project contains annotations derived from JCIP-ANNOTATIONS
+Copyright (c) 2005 Brian Goetz and Tim Peierls.
+See http://www.jcip.net and the Creative Commons Attribution License 
+(http://creativecommons.org/licenses/by/2.5)
+

Added: lucene/dev/branches/branch_3x/solr/lib/httpclient-NOTICE.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/lib/httpclient-NOTICE.txt?rev=1305074&view=auto
==============================================================================
--- lucene/dev/branches/branch_3x/solr/lib/httpclient-NOTICE.txt (added)
+++ lucene/dev/branches/branch_3x/solr/lib/httpclient-NOTICE.txt Sun Mar 25 16:30:58 2012
@@ -0,0 +1,8 @@
+Apache HttpComponents Client
+Copyright 1999-2011 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+This project contains annotations derived from JCIP-ANNOTATIONS
+Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net
\ No newline at end of file

Added: lucene/dev/branches/branch_3x/solr/lib/httpcore-4.1.4.jar
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/lib/httpcore-4.1.4.jar?rev=1305074&view=auto
==============================================================================
Binary file - no diff available.

Added: lucene/dev/branches/branch_3x/solr/lib/httpcore-LICENSE-ASL.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/lib/httpcore-LICENSE-ASL.txt?rev=1305074&view=auto
==============================================================================
--- lucene/dev/branches/branch_3x/solr/lib/httpcore-LICENSE-ASL.txt (added)
+++ lucene/dev/branches/branch_3x/solr/lib/httpcore-LICENSE-ASL.txt Sun Mar 25 16:30:58 2012
@@ -0,0 +1,182 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+   
+This project contains annotations derived from JCIP-ANNOTATIONS
+Copyright (c) 2005 Brian Goetz and Tim Peierls.
+See http://www.jcip.net and the Creative Commons Attribution License 
+(http://creativecommons.org/licenses/by/2.5)
+

Added: lucene/dev/branches/branch_3x/solr/lib/httpcore-NOTICE.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/lib/httpcore-NOTICE.txt?rev=1305074&view=auto
==============================================================================
--- lucene/dev/branches/branch_3x/solr/lib/httpcore-NOTICE.txt (added)
+++ lucene/dev/branches/branch_3x/solr/lib/httpcore-NOTICE.txt Sun Mar 25 16:30:58 2012
@@ -0,0 +1,8 @@
+Apache HttpComponents Client
+Copyright 1999-2011 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+This project contains annotations derived from JCIP-ANNOTATIONS
+Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net
\ No newline at end of file

Added: lucene/dev/branches/branch_3x/solr/lib/httpmime-4.1.3.jar
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/lib/httpmime-4.1.3.jar?rev=1305074&view=auto
==============================================================================
Binary file - no diff available.

Added: lucene/dev/branches/branch_3x/solr/lib/httpmime-LICENSE-ASL.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/lib/httpmime-LICENSE-ASL.txt?rev=1305074&view=auto
==============================================================================
--- lucene/dev/branches/branch_3x/solr/lib/httpmime-LICENSE-ASL.txt (added)
+++ lucene/dev/branches/branch_3x/solr/lib/httpmime-LICENSE-ASL.txt Sun Mar 25 16:30:58 2012
@@ -0,0 +1,182 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+   
+This project contains annotations derived from JCIP-ANNOTATIONS
+Copyright (c) 2005 Brian Goetz and Tim Peierls.
+See http://www.jcip.net and the Creative Commons Attribution License 
+(http://creativecommons.org/licenses/by/2.5)
+

Added: lucene/dev/branches/branch_3x/solr/lib/httpmime-NOTICE.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/lib/httpmime-NOTICE.txt?rev=1305074&view=auto
==============================================================================
--- lucene/dev/branches/branch_3x/solr/lib/httpmime-NOTICE.txt (added)
+++ lucene/dev/branches/branch_3x/solr/lib/httpmime-NOTICE.txt Sun Mar 25 16:30:58 2012
@@ -0,0 +1,8 @@
+Apache HttpComponents Client
+Copyright 1999-2011 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+This project contains annotations derived from JCIP-ANNOTATIONS
+Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net
\ No newline at end of file

Modified: lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CommonsHttpSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CommonsHttpSolrServer.java?rev=1305074&r1=1305073&r2=1305074&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CommonsHttpSolrServer.java (original)
+++ lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CommonsHttpSolrServer.java Sun Mar 25 16:30:58 2012
@@ -61,6 +61,7 @@ import org.slf4j.LoggerFactory;
  * 
  * @version $Id$
  * @since solr 1.3
+ * @deprecated Use {@link HttpSolrServer} instead.
  */
 public class CommonsHttpSolrServer extends SolrServer 
 {

Added: lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrServer.java?rev=1305074&view=auto
==============================================================================
--- lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrServer.java (added)
+++ lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrServer.java Sun Mar 25 16:30:58 2012
@@ -0,0 +1,371 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.client.solrj.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentProducer;
+import org.apache.http.entity.EntityTemplate;
+import org.apache.solr.client.solrj.ResponseParser;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.request.RequestWriter;
+import org.apache.solr.client.solrj.request.UpdateRequest;
+import org.apache.solr.client.solrj.util.ClientUtils;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.params.UpdateParams;
+import org.apache.solr.common.util.NamedList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ConcurrentUpdateSolrServer buffers all added documents and writes
+ * them into open HTTP connections. This class is thread safe.
+ * 
+ * Although any SolrServer request can be made with this implementation, it is
+ * only recommended to use ConcurrentUpdateSolrServer with /update
+ * requests. The class {@link HttpSolrServer} is better suited for the
+ * query interface.
+ */
+public class ConcurrentUpdateSolrServer extends SolrServer {
+  private static final long serialVersionUID = 1L;
+  static final Logger log = LoggerFactory
+      .getLogger(ConcurrentUpdateSolrServer.class);
+  private HttpSolrServer server;
+  final BlockingQueue<UpdateRequest> queue;
+  final ExecutorService scheduler = Executors.newCachedThreadPool();
+  final String updateUrl = "/update";
+  final Queue<Runner> runners;
+  volatile CountDownLatch lock = null; // used to block everything
+  final int threadCount;
+
+  /**
+   * Uses an internal ThreadSafeClientConnManager to manage http
+   * connections.
+   * 
+   * @param solrServerUrl
+   *          The Solr server URL
+   * @param queueSize
+   *          The buffer size before the documents are sent to the server
+   * @param threadCount
+   *          The number of background threads used to empty the queue
+   * @throws MalformedURLException
+   */
+  public ConcurrentUpdateSolrServer(String solrServerUrl, int queueSize,
+      int threadCount) throws MalformedURLException {
+    this(solrServerUrl, null, queueSize, threadCount);
+  }
+
+  /**
+   * Uses the supplied HttpClient to send documents to the Solr server, the
+   * HttpClient should be instantiated using a 
+   * ThreadSafeClientConnManager.
+   */
+  public ConcurrentUpdateSolrServer(String solrServerUrl,
+      HttpClient client, int queueSize, int threadCount)
+      throws MalformedURLException {
+    this.server = new HttpSolrServer(solrServerUrl, client);
+    this.server.setFollowRedirects(false);
+    queue = new LinkedBlockingQueue<UpdateRequest>(queueSize);
+    this.threadCount = threadCount;
+    runners = new LinkedList<Runner>();
+  }
+
+  /**
+   * Opens a connection and sends everything...
+   */
+  class Runner implements Runnable {
+    final Lock runnerLock = new ReentrantLock();
+
+    public void run() {
+      runnerLock.lock();
+
+      // info is ok since this should only happen once for each thread
+      log.info("starting runner: {}", this);
+      HttpPost method = null;
+      HttpResponse response = null;
+      try {
+        while (!queue.isEmpty()) {
+          try {
+            final UpdateRequest updateRequest = queue.poll(250,
+                TimeUnit.MILLISECONDS);
+            if (updateRequest == null)
+              break;
+
+            EntityTemplate template = new EntityTemplate(new ContentProducer() {
+
+              public void writeTo(OutputStream out) throws IOException {
+                try {
+                  if (ClientUtils.TEXT_XML.equals(server.requestWriter
+                      .getUpdateContentType())) {
+                    out.write("<stream>".getBytes("UTF-8")); // can be anything
+                  }
+                  UpdateRequest req = updateRequest;
+                  while (req != null) {
+                    server.requestWriter.write(req, out);
+                    if (ClientUtils.TEXT_XML.equals(server.requestWriter
+                        .getUpdateContentType())) {
+                      // check for commit or optimize
+                      SolrParams params = req.getParams();
+                      if (params != null) {
+                        String fmt = null;
+                        if (params.getBool(UpdateParams.OPTIMIZE, false)) {
+                          fmt = "<optimize waitSearcher=\"%s\" waitFlush=\"%s\" />";
+                        } else if (params.getBool(UpdateParams.COMMIT, false)) {
+                          fmt = "<commit waitSearcher=\"%s\" waitFlush=\"%s\" />";
+                        }
+                        if (fmt != null) {
+                          byte[] content = String.format(
+                              fmt,
+                              params.getBool(UpdateParams.WAIT_SEARCHER, false)
+                                  + "").getBytes("UTF-8");
+                          out.write(content);
+                        }
+                      }
+                    }
+                    out.flush();
+                    req = queue.poll(250, TimeUnit.MILLISECONDS);
+                  }
+                  if (ClientUtils.TEXT_XML.equals(server.requestWriter
+                      .getUpdateContentType())) {
+                    out.write("</stream>".getBytes("UTF-8"));
+                  }
+
+                } catch (InterruptedException e) {
+                  e.printStackTrace();
+                }
+              }
+            });
+
+            String path = ClientUtils.TEXT_XML.equals(server.requestWriter
+                .getUpdateContentType()) ? "/update" : "/update/javabin";
+
+            method = new HttpPost(server.getBaseURL() + path);
+            method.setEntity(template);
+            method.addHeader("User-Agent", HttpSolrServer.AGENT);
+            response = server.getHttpClient().execute(method);
+            int statusCode = response.getStatusLine().getStatusCode();
+            log.info("Status for: "
+                + updateRequest.getDocuments().get(0).getFieldValue("id")
+                + " is " + statusCode);
+            if (statusCode != HttpStatus.SC_OK) {
+              StringBuilder msg = new StringBuilder();
+              msg.append(response.getStatusLine().getReasonPhrase());
+              msg.append("\n\n");
+              msg.append("\n\n");
+              msg.append("request: ").append(method.getURI());
+              handleError(new Exception(msg.toString()));
+            }
+          } finally {
+            try {
+              if (response != null) {
+                response.getEntity().getContent().close();
+              }
+            } catch (Exception ex) {
+            }
+          }
+        }
+      } catch (Throwable e) {
+        handleError(e);
+      } finally {
+
+        // remove it from the list of running things unless we are the last
+        // runner and the queue is full...
+        // in which case, the next queue.put() would block and there would be no
+        // runners to handle it.
+        // This case has been further handled by using offer instead of put, and
+        // using a retry loop
+        // to avoid blocking forever (see request()).
+        synchronized (runners) {
+          if (runners.size() == 1 && queue.remainingCapacity() == 0) {
+            // keep this runner alive
+            scheduler.execute(this);
+          } else {
+            runners.remove(this);
+          }
+        }
+
+        log.info("finished: {}", this);
+        runnerLock.unlock();
+      }
+    }
+  }
+
+  public NamedList<Object> request(final SolrRequest request)
+      throws SolrServerException, IOException {
+    if (!(request instanceof UpdateRequest)) {
+      return server.request(request);
+    }
+    UpdateRequest req = (UpdateRequest) request;
+
+    // this happens for commit...
+    if (req.getDocuments() == null || req.getDocuments().isEmpty()) {
+      blockUntilFinished();
+      return server.request(request);
+    }
+
+    SolrParams params = req.getParams();
+    if (params != null) {
+      // check if it is waiting for the searcher
+      if (params.getBool(UpdateParams.WAIT_SEARCHER, false)) {
+        log.info("blocking for commit/optimize");
+        blockUntilFinished(); // empty the queue
+        return server.request(request);
+      }
+    }
+
+    try {
+      CountDownLatch tmpLock = lock;
+      if (tmpLock != null) {
+        tmpLock.await();
+      }
+
+      boolean success = queue.offer(req);
+
+      for (;;) {
+        synchronized (runners) {
+          if (runners.isEmpty() || (queue.remainingCapacity() < queue.size() // queue
+                                                                             // is
+                                                                             // half
+                                                                             // full
+                                                                             // and
+                                                                             // we
+                                                                             // can
+                                                                             // add
+                                                                             // more
+                                                                             // runners
+              && runners.size() < threadCount)) {
+            // We need more runners, so start a new one.
+            Runner r = new Runner();
+            runners.add(r);
+            scheduler.execute(r);
+          } else {
+            // break out of the retry loop if we added the element to the queue
+            // successfully, *and*
+            // while we are still holding the runners lock to prevent race
+            // conditions.
+            // race conditions.
+            if (success)
+              break;
+          }
+        }
+
+        // Retry to add to the queue w/o the runners lock held (else we risk
+        // temporary deadlock)
+        // This retry could also fail because
+        // 1) existing runners were not able to take off any new elements in the
+        // queue
+        // 2) the queue was filled back up since our last try
+        // If we succeed, the queue may have been completely emptied, and all
+        // runners stopped.
+        // In all cases, we should loop back to the top to see if we need to
+        // start more runners.
+        //
+        if (!success) {
+          success = queue.offer(req, 100, TimeUnit.MILLISECONDS);
+        }
+
+      }
+
+    } catch (InterruptedException e) {
+      log.error("interrupted", e);
+      throw new IOException(e.getLocalizedMessage());
+    }
+
+    // RETURN A DUMMY result
+    NamedList<Object> dummy = new NamedList<Object>();
+    dummy.add("NOTE", "the request is processed in a background stream");
+    return dummy;
+  }
+
+  public synchronized void blockUntilFinished() {
+    lock = new CountDownLatch(1);
+    try {
+      // Wait until no runners are running
+      for (;;) {
+        Runner runner;
+        synchronized (runners) {
+          runner = runners.peek();
+        }
+        if (runner == null)
+          break;
+        runner.runnerLock.lock();
+        runner.runnerLock.unlock();
+      }
+    } finally {
+      lock.countDown();
+      lock = null;
+    }
+  }
+
+  public void handleError(Throwable ex) {
+    log.error("error", ex);
+  }
+
+  public void shutdown() {
+    server.shutdown();
+    scheduler.shutdown();
+    try {
+      if (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) {
+        scheduler.shutdownNow();
+        if (!scheduler.awaitTermination(60, TimeUnit.SECONDS))
+          log.error("ExecutorService did not terminate");
+      }
+    } catch (InterruptedException ie) {
+      scheduler.shutdownNow();
+      Thread.currentThread().interrupt();
+    }
+  }
+
+  public void shutdownNow() {
+    server.shutdown();
+    scheduler.shutdownNow(); // Cancel currently executing tasks
+    try {
+      if (!scheduler.awaitTermination(30, TimeUnit.SECONDS))
+        log.error("ExecutorService did not terminate");
+    } catch (InterruptedException ie) {
+      scheduler.shutdownNow();
+      Thread.currentThread().interrupt();
+    }
+  }
+
+  public void setParser(ResponseParser responseParser) {
+    server.setParser(responseParser);
+  }
+
+  public void setRequestWriter(RequestWriter requestWriter) {
+    server.setRequestWriter(requestWriter);
+  }
+}

Added: lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java?rev=1305074&view=auto
==============================================================================
--- lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java (added)
+++ lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java Sun Mar 25 16:30:58 2012
@@ -0,0 +1,630 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.client.solrj.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.ConnectException;
+import java.net.SocketTimeoutException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.InflaterInputStream;
+
+import org.apache.http.Header;
+import org.apache.http.HeaderElement;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpResponseInterceptor;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.client.params.ClientParamBean;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.entity.HttpEntityWrapper;
+import org.apache.http.entity.mime.FormBodyPart;
+import org.apache.http.entity.mime.HttpMultipartMode;
+import org.apache.http.entity.mime.MultipartEntity;
+import org.apache.http.entity.mime.content.InputStreamBody;
+import org.apache.http.entity.mime.content.StringBody;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
+import org.apache.solr.client.solrj.ResponseParser;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.request.RequestWriter;
+import org.apache.solr.client.solrj.request.UpdateRequest;
+import org.apache.solr.client.solrj.response.UpdateResponse;
+import org.apache.solr.client.solrj.util.ClientUtils;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.ContentStream;
+import org.apache.solr.common.util.NamedList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link HttpSolrServer} uses the Apache HTTP Client 4.x to connect to solr. 
+ * <pre class="prettyprint" >SolrServer server = new HttpSolrServer( url );</pre>
+ */
+public class HttpSolrServer extends SolrServer {
+  private static final String UTF_8 = "UTF-8";
+  private static final String DEFAULT_PATH = "/select";
+  private static final long serialVersionUID = 1L;
+  /**
+   * User-Agent String.
+   */
+  public static final String AGENT = "Solr[" + HttpSolrServer.class.getName()
+      + "] 1.0";
+  
+  private static Logger log = LoggerFactory.getLogger(HttpSolrServer.class);
+  
+  /**
+   * The URL of the Solr server.
+   */
+  protected String baseUrl;
+  
+  /**
+   * Default value: null / empty.
+   * <p/>
+   * Parameters that are added to every request regardless. This may be a place
+   * to add something like an authentication token.
+   */
+  protected ModifiableSolrParams invariantParams;
+  
+  /**
+   * Default response parser is BinaryResponseParser
+   * <p/>
+   * This parser represents the default Response Parser chosen to parse the
+   * response if the parser were not specified as part of the request.
+   * 
+   * @see org.apache.solr.client.solrj.impl.BinaryResponseParser
+   */
+  protected ResponseParser parser;
+  
+  /**
+   * The RequestWriter used to write all requests to Solr
+   * 
+   * @see org.apache.solr.client.solrj.request.RequestWriter
+   */
+  protected RequestWriter requestWriter = new RequestWriter();
+  
+  private final HttpClient httpClient;
+  
+  /**
+   * This defaults to false under the assumption that if you are following a
+   * redirect to get to a Solr installation, something is misconfigured
+   * somewhere.
+   */
+  private boolean followRedirects = false;
+  
+  /**
+   * Maximum number of retries to attempt in the event of transient errors.
+   * Default: 0 (no) retries. No more than 1 recommended.
+   */
+  private int maxRetries = 0;
+  
+  private ThreadSafeClientConnManager ccm;
+  
+  /**
+   * @param baseURL
+   *          The URL of the Solr server. For example, "
+   *          <code>http://localhost:8983/solr/</code>" if you are using the
+   *          standard distribution Solr webapp on your local machine.
+   */
+  public HttpSolrServer(String baseURL) {
+    this(baseURL, null, new BinaryResponseParser());
+  }
+  
+  public HttpSolrServer(String baseURL, HttpClient client) {
+    this(baseURL, client, new BinaryResponseParser());
+  }
+  
+  public HttpSolrServer(String baseURL, HttpClient client, ResponseParser parser) {
+    this.baseUrl = baseURL;
+    if (baseUrl.endsWith("/")) {
+      baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
+    }
+    if (baseUrl.indexOf('?') >= 0) {
+      throw new RuntimeException(
+          "Invalid base url for solrj.  The base URL must not contain parameters: "
+              + baseUrl);
+    }
+    
+    if (client != null) {
+      httpClient = client;
+    } else {
+      httpClient = createClient();
+    }
+    
+    this.parser = parser;
+  }
+  
+  private DefaultHttpClient createClient() {
+    SchemeRegistry schemeRegistry = new SchemeRegistry();
+    schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory
+        .getSocketFactory()));
+    schemeRegistry.register(new Scheme("https", 443, SSLSocketFactory
+        .getSocketFactory()));
+    
+    ccm = new ThreadSafeClientConnManager(schemeRegistry);
+    // Increase default max connection per route to 32
+    ccm.setDefaultMaxPerRoute(32);
+    // Increase max total connection to 128
+    ccm.setMaxTotal(128);
+    DefaultHttpClient httpClient = new DefaultHttpClient(ccm);
+    httpClient.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS,
+        followRedirects);
+    return httpClient;
+  }
+  
+  /**
+   * Process the request. If
+   * {@link org.apache.solr.client.solrj.SolrRequest#getResponseParser()} is
+   * null, then use {@link #getParser()}
+   * 
+   * @param request
+   *          The {@link org.apache.solr.client.solrj.SolrRequest} to process
+   * @return The {@link org.apache.solr.common.util.NamedList} result
+   * @throws SolrServerException
+   * @throws IOException
+   * 
+   * @see #request(org.apache.solr.client.solrj.SolrRequest,
+   *      org.apache.solr.client.solrj.ResponseParser)
+   */
+  public NamedList<Object> request(final SolrRequest request)
+      throws SolrServerException, IOException {
+    ResponseParser responseParser = request.getResponseParser();
+    if (responseParser == null) {
+      responseParser = parser;
+    }
+    return request(request, responseParser);
+  }
+  
+  public NamedList<Object> request(final SolrRequest request,
+      final ResponseParser processor) throws SolrServerException {
+    HttpRequestBase method = null;
+    SolrParams params = request.getParams();
+    String path = requestWriter.getPath(request);
+    if (path == null || !path.startsWith("/")) {
+      path = DEFAULT_PATH;
+    }
+    
+    ResponseParser parser = request.getResponseParser();
+    if (parser == null) {
+      parser = this.parser;
+    }
+    
+    // The parser 'wt=' and 'version=' params are used instead of the original
+    // params
+    ModifiableSolrParams wparams = new ModifiableSolrParams(params);
+    wparams.set(CommonParams.WT, parser.getWriterType());
+    wparams.set(CommonParams.VERSION, parser.getVersion());
+    if (invariantParams != null) {
+      wparams.add(invariantParams);
+    }
+    params = wparams;
+    
+    int tries = maxRetries + 1;
+    try {
+      while (tries-- > 0) { // XXX this retry thing seems noop to me
+        Collection<ContentStream> streams = requestWriter
+            .getContentStreams(request);
+        // Note: since we aren't doing intermittent time keeping
+        // ourselves, the potential non-timeout latency could be as
+        // much as tries-times (plus scheduling effects) the given
+        // timeAllowed.
+        try {
+          if (SolrRequest.METHOD.GET == request.getMethod()) {
+            if (streams != null) {
+              throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
+                  "GET can't send streams!");
+            }
+            method = new HttpGet(baseUrl + path
+                + ClientUtils.toQueryString(params, false));
+          } else if (SolrRequest.METHOD.POST == request.getMethod()) {
+            String url = baseUrl + path;
+            
+            MultipartEntity entity = new MultipartEntity(
+                HttpMultipartMode.BROWSER_COMPATIBLE);
+            
+            final HttpPost post = new HttpPost(url);
+            
+            final Iterator<String> iter = params.getParameterNamesIterator();
+            if (iter.hasNext()) {
+              
+              while (iter.hasNext()) {
+                final String name = iter.next();
+                final String[] vals = params.getParams(name);
+                if (vals != null) {
+                  for (String value : vals) {
+                    entity.addPart(name, new StringBody(value));
+                  }
+                }
+              }
+            }
+            addParts(streams, entity);
+            post.setEntity(entity);
+            method = post;
+          } else {
+            throw new SolrServerException("Unsupported method: "
+                + request.getMethod());
+          }
+        } catch (RuntimeException r) {
+          // If out of tries then just rethrow (as normal error).
+          if ((tries < 1)) {
+            throw r;
+          }
+          // log.warn( "Caught: " + r + ". Retrying..." );
+        }
+      }
+    } catch (IOException ex) {
+      throw new SolrServerException("error reading streams", ex);
+    }
+    
+    // TODO: move to a interceptor?
+    method.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS,
+        followRedirects);
+    method.addHeader("User-Agent", AGENT);
+    method.setHeader("Content-Charset", UTF_8);
+    method.setHeader("Accept-Charset", UTF_8);
+    
+    InputStream respBody = null;
+    
+    try {
+      // Execute the method.
+      final HttpResponse response = httpClient.execute(method);
+      int httpStatus = response.getStatusLine().getStatusCode();
+      
+      // Read the contents
+      String charset = EntityUtils.getContentCharSet(response.getEntity());
+      respBody = response.getEntity().getContent();
+      
+      // handle some http level checks before trying to parse the response
+      switch (httpStatus) {
+        case HttpStatus.SC_OK:
+          break;
+        case HttpStatus.SC_MOVED_PERMANENTLY:
+        case HttpStatus.SC_MOVED_TEMPORARILY:
+          if (!followRedirects) {
+            throw new SolrServerException("Server at " + getBaseURL()
+                + " sent back a redirect (" + httpStatus + ").");
+          }
+          break;
+        case HttpStatus.SC_NOT_FOUND:
+          throw new SolrServerException("Server at " + getBaseURL()
+              + " was not found (404).");
+        default:
+          throw new SolrServerException("Server at " + getBaseURL()
+              + " returned non ok status:" + httpStatus + ", message:"
+              + response.getStatusLine().getReasonPhrase());
+          
+      }
+      NamedList<Object> rsp = processor.processResponse(respBody, charset);
+      if (httpStatus != HttpStatus.SC_OK) {
+        String reason = null;
+        try {
+          NamedList err = (NamedList) rsp.get("error");
+          if (err != null) {
+            reason = (String) err.get("msg");
+            // TODO? get the trace?
+          }
+        } catch (Exception ex) {}
+        if (reason == null) {
+          StringBuilder msg = new StringBuilder();
+          msg.append(response.getStatusLine().getReasonPhrase());
+          msg.append("\n\n");
+          msg.append("request: " + method.getURI());
+          reason = java.net.URLDecoder.decode(msg.toString(), UTF_8);
+        }
+        throw new SolrException(
+            SolrException.ErrorCode.getErrorCode(httpStatus), reason);
+      }
+      return rsp;
+    } catch (ConnectException e) {
+      throw new SolrServerException("Server refused connection at: "
+          + getBaseURL(), e);
+    } catch (SocketTimeoutException e) {
+      throw new SolrServerException(
+          "Timeout occured while waiting response from server at: "
+              + getBaseURL(), e);
+    } catch (IOException e) {
+      throw new SolrServerException(
+          "IOException occured when talking to server at: " + getBaseURL(), e);
+    } finally {
+      if (respBody != null) {
+        try {
+          respBody.close();
+        } catch (Throwable t) {} // ignore
+      }
+    }
+  }
+  
+  private void addParts(Collection<ContentStream> streams,
+      MultipartEntity entity) throws IOException {
+    if (streams != null) {
+      for (ContentStream content : streams) {
+        entity.addPart(new FormBodyPart(CommonParams.STREAM_BODY,
+            new InputStreamBody(content.getStream(), "")));
+      }
+    }
+  }
+  
+  // -------------------------------------------------------------------
+  // -------------------------------------------------------------------
+  
+  /**
+   * Retrieve the default list of parameters are added to every request
+   * regardless.
+   * 
+   * @see #invariantParams
+   */
+  public ModifiableSolrParams getInvariantParams() {
+    return invariantParams;
+  }
+  
+  public String getBaseURL() {
+    return baseUrl;
+  }
+  
+  public void setBaseURL(String baseURL) {
+    this.baseUrl = baseURL;
+  }
+  
+  public ResponseParser getParser() {
+    return parser;
+  }
+  
+  /**
+   * Note: This setter method is <b>not thread-safe</b>.
+   * 
+   * @param processor
+   *          Default Response Parser chosen to parse the response if the parser
+   *          were not specified as part of the request.
+   * @see org.apache.solr.client.solrj.SolrRequest#getResponseParser()
+   */
+  public void setParser(ResponseParser processor) {
+    parser = processor;
+  }
+  
+  public HttpClient getHttpClient() {
+    return httpClient;
+  }
+  
+  /**
+   * HttpConnectionParams.setConnectionTimeout
+   * 
+   * @param timeout
+   *          Timeout in milliseconds
+   **/
+  public void setConnectionTimeout(int timeout) {
+    HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), timeout);
+  }
+  
+  /**
+   * Sets HttpConnectionParams.setSoTimeout (read timeout). This is desirable
+   * for queries, but probably not for indexing.
+   * 
+   * @param timeout
+   *          Timeout in milliseconds
+   **/
+  public void setSoTimeout(int timeout) {
+    HttpConnectionParams.setSoTimeout(httpClient.getParams(), timeout);
+  }
+  
+  /**
+   * HttpClientParams.setRedirecting
+   * 
+   * @see #followRedirects
+   */
+  public void setFollowRedirects(boolean followRedirects) {
+    this.followRedirects = followRedirects;
+    new ClientParamBean(httpClient.getParams())
+        .setHandleRedirects(followRedirects);
+  }
+  
+  private static class UseCompressionRequestInterceptor implements
+      HttpRequestInterceptor {
+    
+    public void process(HttpRequest request, HttpContext context)
+        throws HttpException, IOException {
+      if (!request.containsHeader("Accept-Encoding")) {
+        request.addHeader("Accept-Encoding", "gzip, deflate");
+      }
+    }
+  }
+  
+  private static class UseCompressionResponseInterceptor implements
+      HttpResponseInterceptor {
+    
+    public void process(final HttpResponse response, final HttpContext context)
+        throws HttpException, IOException {
+      
+      HttpEntity entity = response.getEntity();
+      Header ceheader = entity.getContentEncoding();
+      if (ceheader != null) {
+        HeaderElement[] codecs = ceheader.getElements();
+        for (int i = 0; i < codecs.length; i++) {
+          if (codecs[i].getName().equalsIgnoreCase("gzip")) {
+            response
+                .setEntity(new GzipDecompressingEntity(response.getEntity()));
+            return;
+          }
+          if (codecs[i].getName().equalsIgnoreCase("deflate")) {
+            response.setEntity(new DeflateDecompressingEntity(response
+                .getEntity()));
+            return;
+          }
+        }
+      }
+    }
+  }
+  
+  private static class GzipDecompressingEntity extends HttpEntityWrapper {
+    public GzipDecompressingEntity(final HttpEntity entity) {
+      super(entity);
+    }
+    
+    public InputStream getContent() throws IOException, IllegalStateException {
+      return new GZIPInputStream(wrappedEntity.getContent());
+    }
+    
+    public long getContentLength() {
+      return -1;
+    }
+  }
+  
+  private static class DeflateDecompressingEntity extends
+      GzipDecompressingEntity {
+    public DeflateDecompressingEntity(final HttpEntity entity) {
+      super(entity);
+    }
+    
+    public InputStream getContent() throws IOException, IllegalStateException {
+      return new InflaterInputStream(wrappedEntity.getContent());
+    }
+  }
+  
+  /**
+   * Allow server->client communication to be compressed. Currently gzip and
+   * deflate are supported. If the server supports compression the response will
+   * be compressed.
+   */
+  public void setAllowCompression(boolean allowCompression) {
+    if (httpClient instanceof DefaultHttpClient) {
+      final DefaultHttpClient client = (DefaultHttpClient) httpClient;
+      client
+          .removeRequestInterceptorByClass(UseCompressionRequestInterceptor.class);
+      client
+          .removeResponseInterceptorByClass(UseCompressionResponseInterceptor.class);
+      if (allowCompression) {
+        client.addRequestInterceptor(new UseCompressionRequestInterceptor());
+        client.addResponseInterceptor(new UseCompressionResponseInterceptor());
+      }
+    } else {
+      throw new UnsupportedOperationException(
+          "HttpClient instance was not of type DefaultHttpClient");
+    }
+  }
+  
+  /**
+   * Set maximum number of retries to attempt in the event of transient errors.
+   * 
+   * @param maxRetries
+   *          No more than 1 recommended
+   * @see #maxRetries
+   */
+  public void setMaxRetries(int maxRetries) {
+    if (maxRetries > 1) {
+      log.warn("CommonsHttpSolrServer: maximum Retries " + maxRetries
+          + " > 1. Maximum recommended retries is 1.");
+    }
+    this.maxRetries = maxRetries;
+  }
+  
+  public void setRequestWriter(RequestWriter requestWriter) {
+    this.requestWriter = requestWriter;
+  }
+  
+  /**
+   * Adds the documents supplied by the given iterator.
+   * 
+   * @param docIterator
+   *          the iterator which returns SolrInputDocument instances
+   * 
+   * @return the response from the SolrServer
+   */
+  public UpdateResponse add(Iterator<SolrInputDocument> docIterator)
+      throws SolrServerException, IOException {
+    UpdateRequest req = new UpdateRequest();
+    req.setDocIterator(docIterator);
+    return req.process(this);
+  }
+  
+  /**
+   * Adds the beans supplied by the given iterator.
+   * 
+   * @param beanIterator
+   *          the iterator which returns Beans
+   * 
+   * @return the response from the SolrServer
+   */
+  public UpdateResponse addBeans(final Iterator<?> beanIterator)
+      throws SolrServerException, IOException {
+    UpdateRequest req = new UpdateRequest();
+    req.setDocIterator(new Iterator<SolrInputDocument>() {
+      
+      public boolean hasNext() {
+        return beanIterator.hasNext();
+      }
+      
+      public SolrInputDocument next() {
+        Object o = beanIterator.next();
+        if (o == null) return null;
+        return getBinder().toSolrInputDocument(o);
+      }
+      
+      public void remove() {
+        beanIterator.remove();
+      }
+    });
+    return req.process(this);
+  }
+  
+  public void shutdown() {
+    if (httpClient != null) {
+      httpClient.getConnectionManager().shutdown();
+    }
+  }
+  
+  public void setDefaultMaxConnectionsPerHost(int max) {
+    if (ccm != null) {
+      ccm.setDefaultMaxPerRoute(max);
+    } else {
+      throw new UnsupportedOperationException(
+          "Client was created outside of HttpSolrServer");
+    }
+  }
+  
+  /**
+   * Set the maximum number of connections that can be open at any given time.
+   */
+  public void setMaxTotalConnections(int max) {
+    if (ccm != null) {
+      ccm.setMaxTotal(max);
+    } else {
+      throw new UnsupportedOperationException(
+          "Client was created outside of HttpSolrServer");
+    }
+  }
+}

Modified: lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/StreamingUpdateSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/StreamingUpdateSolrServer.java?rev=1305074&r1=1305073&r2=1305074&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/StreamingUpdateSolrServer.java (original)
+++ lucene/dev/branches/branch_3x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/StreamingUpdateSolrServer.java Sun Mar 25 16:30:58 2012
@@ -52,7 +52,9 @@ import org.slf4j.LoggerFactory;
  * 
  * @version $Id: CommonsHttpSolrServer.java 724175 2008-12-07 19:07:11Z ryan $
  * @since solr 1.4
+ * @deprecated use {@link ConcurrentUpdateSolrServer} instead.
  */
+@Deprecated
 public class StreamingUpdateSolrServer extends CommonsHttpSolrServer
 {
   static final Logger log = LoggerFactory.getLogger( StreamingUpdateSolrServer.class );

Added: lucene/dev/branches/branch_3x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTestHttpSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTestHttpSolrServer.java?rev=1305074&view=auto
==============================================================================
--- lucene/dev/branches/branch_3x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTestHttpSolrServer.java (added)
+++ lucene/dev/branches/branch_3x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTestHttpSolrServer.java Sun Mar 25 16:30:58 2012
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.client.solrj;
+
+import org.apache.solr.client.solrj.impl.BinaryRequestWriter;
+import org.apache.solr.client.solrj.impl.BinaryResponseParser;
+import org.apache.solr.client.solrj.impl.HttpSolrServer;
+import org.apache.solr.util.ExternalPaths;
+import org.junit.BeforeClass;
+
+/**
+ * A subclass of SolrExampleTests that uses {@link HttpSolrServer} randomly
+ * toggles binary/xml wire format.
+ */
+public class SolrExampleTestHttpSolrServer extends SolrExampleTests {
+  @BeforeClass
+  public static void beforeTest() throws Exception {
+    createJetty(ExternalPaths.EXAMPLE_HOME, null, null);
+  }
+
+  @Override
+  public SolrServer createNewSolrServer() {
+    try {
+      // setup the server...
+      String url = "http://localhost:" + port + context;
+      HttpSolrServer s = new HttpSolrServer(url);
+      s.setConnectionTimeout(100); // 1/10th sec
+      s.setDefaultMaxConnectionsPerHost(100);
+      s.setMaxTotalConnections(100);
+
+      if (random.nextBoolean()) {
+        s.setParser(new BinaryResponseParser());
+        s.setRequestWriter(new BinaryRequestWriter());
+      }
+
+      return s;
+    } catch (Exception ex) {
+      throw new RuntimeException(ex);
+    }
+  }
+}