Last active
August 29, 2015 14:20
-
-
Save hardikamal/7821c75ff3f689ad201c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.io.InputStream; | |
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.auth.AuthScope; | |
import org.apache.http.auth.UsernamePasswordCredentials; | |
import org.apache.http.client.HttpClient; | |
import org.apache.http.client.params.ClientParamBean; | |
import org.apache.http.entity.HttpEntityWrapper; | |
import org.apache.http.impl.client.DefaultHttpClient; | |
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; | |
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; // jdoc | |
import org.apache.http.params.HttpConnectionParams; | |
import org.apache.http.protocol.HttpContext; | |
import org.apache.solr.client.solrj.impl.HttpClientConfigurer; | |
import org.apache.solr.common.params.ModifiableSolrParams; | |
import org.apache.solr.common.params.SolrParams; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import android.content.Context; | |
import android.net.http.AndroidHttpClient; | |
/** | |
* Utility class for creating/configuring httpclient instances. | |
*/ | |
public class HttpClientUtil { | |
// socket timeout measured in ms, closes a socket if read | |
// takes longer than x ms to complete. throws | |
// java.net.SocketTimeoutException: Read timed out exception | |
public static final String PROP_SO_TIMEOUT = "socketTimeout"; | |
// connection timeout measures in ms, closes a socket if connection | |
// cannot be established within x ms. with a | |
// java.net.SocketTimeoutException: Connection timed out | |
public static final String PROP_CONNECTION_TIMEOUT = "connTimeout"; | |
// Maximum connections allowed per host | |
public static final String PROP_MAX_CONNECTIONS_PER_HOST = "maxConnectionsPerHost"; | |
// Maximum total connections allowed | |
public static final String PROP_MAX_CONNECTIONS = "maxConnections"; | |
// Retry http requests on error | |
public static final String PROP_USE_RETRY = "retry"; | |
// Allow compression (deflate,gzip) if server supports it | |
public static final String PROP_ALLOW_COMPRESSION = "allowCompression"; | |
// Follow redirects | |
public static final String PROP_FOLLOW_REDIRECTS = "followRedirects"; | |
// Basic auth username | |
public static final String PROP_BASIC_AUTH_USER = "httpBasicAuthUser"; | |
// Basic auth password | |
public static final String PROP_BASIC_AUTH_PASS = "httpBasicAuthPassword"; | |
private static final Logger logger = LoggerFactory | |
.getLogger(HttpClientUtil.class); | |
static final DefaultHttpRequestRetryHandler NO_RETRY = new DefaultHttpRequestRetryHandler( | |
0, false); | |
private static HttpClientConfigurer configurer = new HttpClientConfigurer(); | |
private HttpClientUtil(){} | |
/** | |
* Replace the {@link HttpClientConfigurer} class used in configuring the http | |
* clients with a custom implementation. | |
*/ | |
public static void setConfigurer(HttpClientConfigurer newConfigurer) { | |
configurer = newConfigurer; | |
} | |
/** | |
* Creates new http client by using the provided configuration. | |
* | |
* @param params | |
* http client configuration, if null a client with default | |
* configuration (no additional configuration) is created. | |
*/ | |
public static AndroidHttpClient createClient(final SolrParams params) { | |
final ModifiableSolrParams config = new ModifiableSolrParams(params); | |
if (logger.isDebugEnabled()) { | |
logger.debug("Creating new http client, config:" + config); | |
} | |
final String AGENT = "Solr[" + HttpSolrServer.class.getName() + "] 1.0"; | |
final AndroidHttpClient httpClient = AndroidHttpClient.newInstance( AGENT , null) ; | |
configureClient(httpClient, config); | |
return httpClient; | |
} | |
/** | |
* Configures {@link DefaultHttpClient}, only sets parameters if they are | |
* present in config. | |
*/ | |
public static void configureClient(final AndroidHttpClient httpClient, | |
SolrParams config) { | |
// configurer.configure(httpClient, config); | |
} | |
/** | |
* Control HTTP payload compression. | |
* | |
* @param allowCompression | |
* true will enable compression (needs support from server), false | |
* will disable compression. | |
*/ | |
public static void setAllowCompression(DefaultHttpClient httpClient, | |
boolean allowCompression) { | |
httpClient | |
.removeRequestInterceptorByClass(UseCompressionRequestInterceptor.class); | |
httpClient | |
.removeResponseInterceptorByClass(UseCompressionResponseInterceptor.class); | |
if (allowCompression) { | |
httpClient.addRequestInterceptor(new UseCompressionRequestInterceptor()); | |
httpClient | |
.addResponseInterceptor(new UseCompressionResponseInterceptor()); | |
} | |
} | |
/** | |
* Set http basic auth information. If basicAuthUser or basicAuthPass is null | |
* the basic auth configuration is cleared. Currently this is not preemtive | |
* authentication. So it is not currently possible to do a post request while | |
* using this setting. | |
*/ | |
public static void setBasicAuth(DefaultHttpClient httpClient, | |
String basicAuthUser, String basicAuthPass) { | |
if (basicAuthUser != null && basicAuthPass != null) { | |
httpClient.getCredentialsProvider().setCredentials(AuthScope.ANY, | |
new UsernamePasswordCredentials(basicAuthUser, basicAuthPass)); | |
} else { | |
httpClient.getCredentialsProvider().clear(); | |
} | |
} | |
/** | |
* Set max connections allowed per host. This call will only work when | |
* {@link ThreadSafeClientConnManager} or | |
* {@link PoolingClientConnectionManager} is used. | |
*/ | |
public static void setMaxConnectionsPerHost(HttpClient httpClient, | |
int max) { | |
// would have been nice if there was a common interface | |
// if (httpClient.getConnectionManager() instanceof ThreadSafeClientConnManager) { | |
// ThreadSafeClientConnManager mgr = (ThreadSafeClientConnManager)httpClient.getConnectionManager(); | |
// mgr.setDefaultMaxPerRoute(max); | |
// } else if (httpClient.getConnectionManager() instanceof PoolingClientConnectionManager) { | |
// PoolingClientConnectionManager mgr = (PoolingClientConnectionManager)httpClient.getConnectionManager(); | |
// mgr.setDefaultMaxPerRoute(max); | |
// } | |
} | |
/** | |
* Set max total connections allowed. This call will only work when | |
* {@link ThreadSafeClientConnManager} or | |
* {@link PoolingClientConnectionManager} is used. | |
*/ | |
public static void setMaxConnections(final HttpClient httpClient, | |
int max) { | |
// would have been nice if there was a common interface | |
// if (httpClient.getConnectionManager() instanceof ThreadSafeClientConnManager) { | |
// ThreadSafeClientConnManager mgr = (ThreadSafeClientConnManager)httpClient.getConnectionManager(); | |
// mgr.setMaxTotal(max); | |
// } else if (httpClient.getConnectionManager() instanceof PoolingClientConnectionManager) { | |
// PoolingClientConnectionManager mgr = (PoolingClientConnectionManager)httpClient.getConnectionManager(); | |
// mgr.setMaxTotal(max); | |
// } | |
} | |
/** | |
* Defines the socket timeout (SO_TIMEOUT) in milliseconds. A timeout value of | |
* zero is interpreted as an infinite timeout. | |
* | |
* @param timeout timeout in milliseconds | |
*/ | |
public static void setSoTimeout(HttpClient httpClient, int timeout) { | |
HttpConnectionParams.setSoTimeout(httpClient.getParams(), | |
timeout); | |
} | |
/** | |
* Control retry handler | |
* @param useRetry when false the client will not try to retry failed requests. | |
*/ | |
public static void setUseRetry(final DefaultHttpClient httpClient, | |
boolean useRetry) { | |
if (!useRetry) { | |
httpClient.setHttpRequestRetryHandler(NO_RETRY); | |
} else { | |
httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler()); | |
} | |
} | |
/** | |
* Set connection timeout. A timeout value of zero is interpreted as an | |
* infinite timeout. | |
* | |
* @param timeout | |
* connection Timeout in milliseconds | |
*/ | |
public static void setConnectionTimeout(final HttpClient httpClient, | |
int timeout) { | |
HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), | |
timeout); | |
} | |
/** | |
* Set follow redirects. | |
* | |
* @param followRedirects When true the client will follow redirects. | |
*/ | |
public static void setFollowRedirects(HttpClient httpClient, | |
boolean followRedirects) { | |
new ClientParamBean(httpClient.getParams()).setHandleRedirects(followRedirects); | |
} | |
private static class UseCompressionRequestInterceptor implements | |
HttpRequestInterceptor { | |
@Override | |
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 { | |
@Override | |
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); | |
} | |
@Override | |
public InputStream getContent() throws IOException, IllegalStateException { | |
return new GZIPInputStream(wrappedEntity.getContent()); | |
} | |
@Override | |
public long getContentLength() { | |
return -1; | |
} | |
} | |
private static class DeflateDecompressingEntity extends | |
GzipDecompressingEntity { | |
public DeflateDecompressingEntity(final HttpEntity entity) { | |
super(entity); | |
} | |
@Override | |
public InputStream getContent() throws IOException, IllegalStateException { | |
return new InflaterInputStream(wrappedEntity.getContent()); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.io.InputStream; | |
import java.net.ConnectException; | |
import java.net.SocketTimeoutException; | |
import java.nio.charset.Charset; | |
import java.util.Collection; | |
import java.util.Collections; | |
import java.util.Iterator; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.Set; | |
import org.apache.commons.io.IOUtils; | |
import org.apache.http.Header; | |
import org.apache.http.HttpResponse; | |
import org.apache.http.HttpStatus; | |
import org.apache.http.NameValuePair; | |
import org.apache.http.NoHttpResponseException; | |
import org.apache.http.client.HttpClient; | |
import org.apache.http.client.entity.UrlEncodedFormEntity; | |
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.conn.ClientConnectionManager; | |
import org.apache.http.entity.InputStreamEntity; | |
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.message.BasicHeader; | |
import org.apache.http.message.BasicNameValuePair; | |
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.impl.BinaryResponseParser; | |
import tv.yo.search.HttpClientUtil; | |
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; | |
import android.net.http.AndroidHttpClient; | |
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 = -946812319974801896L; | |
/** | |
* 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 volatile ResponseParser parser; | |
/** | |
* The RequestWriter used to write all requests to Solr | |
* | |
* @see org.apache.solr.client.solrj.request.RequestWriter | |
*/ | |
protected volatile RequestWriter requestWriter = new RequestWriter(); | |
private final AndroidHttpClient httpClient; | |
private boolean followRedirects = false; | |
private int maxRetries = 0; | |
private boolean useMultiPartPost; | |
private final boolean internalClient; | |
private Set<String> queryParams = Collections.emptySet(); | |
/** | |
* @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, AndroidHttpClient client) { | |
this(baseURL, client, new BinaryResponseParser()); | |
} | |
public HttpSolrServer(String baseURL, AndroidHttpClient 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 = (AndroidHttpClient) client; | |
internalClient = false; | |
} else { | |
internalClient = true; | |
ModifiableSolrParams params = new ModifiableSolrParams(); | |
params.set(HttpClientUtil.PROP_MAX_CONNECTIONS, 128); | |
params.set(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST, 32); | |
params.set(HttpClientUtil.PROP_FOLLOW_REDIRECTS, followRedirects); | |
httpClient = (AndroidHttpClient) HttpClientUtil.createClient(params); | |
} | |
this.parser = parser; | |
} | |
public Set<String> getQueryParams() { | |
return queryParams; | |
} | |
/** | |
* Expert Method. | |
* @param queryParams set of param keys to only send via the query string | |
*/ | |
public void setQueryParams(Set<String> queryParams) { | |
this.queryParams = queryParams; | |
} | |
/** | |
* 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 IOException If there is a low-level I/O error. | |
* | |
* @see #request(org.apache.solr.client.solrj.SolrRequest, | |
* org.apache.solr.client.solrj.ResponseParser) | |
*/ | |
@Override | |
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, IOException { | |
HttpRequestBase method = null; | |
InputStream is = null; | |
SolrParams params = request.getParams(); | |
Collection<ContentStream> streams = requestWriter.getContentStreams(request); | |
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); | |
if (parser != null) { | |
wparams.set(CommonParams.WT, parser.getWriterType()); | |
wparams.set(CommonParams.VERSION, parser.getVersion()); | |
} | |
if (invariantParams != null) { | |
wparams.add(invariantParams); | |
} | |
int tries = maxRetries + 1; | |
try { | |
while( tries-- > 0 ) { | |
// Note: since we aren't do 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( wparams, false ) ); | |
} | |
else if( SolrRequest.METHOD.POST == request.getMethod() ) { | |
String url = baseUrl + path; | |
boolean hasNullStreamName = false; | |
if (streams != null) { | |
for (ContentStream cs : streams) { | |
if (cs.getName() == null) { | |
hasNullStreamName = true; | |
break; | |
} | |
} | |
} | |
boolean isMultipart = (this.useMultiPartPost || ( streams != null && streams.size() > 1 )) && !hasNullStreamName; | |
// only send this list of params as query string params | |
ModifiableSolrParams queryParams = new ModifiableSolrParams(); | |
for (String param : this.queryParams) { | |
String[] value = wparams.getParams(param) ; | |
if (value != null) { | |
for (String v : value) { | |
queryParams.add(param, v); | |
} | |
wparams.remove(param); | |
} | |
} | |
LinkedList<NameValuePair> postParams = new LinkedList<NameValuePair>(); | |
if (streams == null || isMultipart) { | |
HttpPost post = new HttpPost(url + ClientUtils.toQueryString( queryParams, false )); | |
post.setHeader("Content-Charset", "UTF-8"); | |
if (!isMultipart) { | |
post.addHeader("Content-Type", | |
"application/x-www-form-urlencoded; charset=UTF-8"); | |
} | |
List<FormBodyPart> parts = new LinkedList<FormBodyPart>(); | |
Iterator<String> iter = wparams.getParameterNamesIterator(); | |
while (iter.hasNext()) { | |
String p = iter.next(); | |
String[] vals = wparams.getParams(p); | |
if (vals != null) { | |
for (String v : vals) { | |
if (isMultipart) { | |
parts.add(new FormBodyPart(p, new StringBody(v, Charset.forName("UTF-8")))); | |
} else { | |
postParams.add(new BasicNameValuePair(p, v)); | |
} | |
} | |
} | |
} | |
if (isMultipart && streams != null) { | |
for (ContentStream content : streams) { | |
String contentType = content.getContentType(); | |
if(contentType==null) { | |
contentType = BinaryResponseParser.BINARY_CONTENT_TYPE; // default | |
} | |
String name = content.getName(); | |
if(name==null) { | |
name = ""; | |
} | |
parts.add(new FormBodyPart(name, | |
new InputStreamBody( | |
content.getStream(), | |
contentType, | |
content.getName()))); | |
} | |
} | |
if (parts.size() > 0) { | |
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.STRICT); | |
for(FormBodyPart p: parts) { | |
entity.addPart(p); | |
} | |
post.setEntity(entity); | |
} else { | |
//not using multipart | |
post.setEntity(new UrlEncodedFormEntity(postParams, "UTF-8")); | |
} | |
method = post; | |
} | |
// It is has one stream, it is the post body, put the params in the URL | |
else { | |
String pstr = ClientUtils.toQueryString(wparams, false); | |
HttpPost post = new HttpPost(url + pstr); | |
// Single stream as body | |
// Using a loop just to get the first one | |
final ContentStream[] contentStream = new ContentStream[1]; | |
for (ContentStream content : streams) { | |
contentStream[0] = content; | |
break; | |
} | |
if (contentStream[0] instanceof RequestWriter.LazyContentStream) { | |
post.setEntity(new InputStreamEntity(contentStream[0].getStream(), -1) { | |
@Override | |
public Header getContentType() { | |
return new BasicHeader("Content-Type", contentStream[0].getContentType()); | |
} | |
@Override | |
public boolean isRepeatable() { | |
return false; | |
} | |
}); | |
} else { | |
post.setEntity(new InputStreamEntity(contentStream[0].getStream(), -1) { | |
@Override | |
public Header getContentType() { | |
return new BasicHeader("Content-Type", contentStream[0].getContentType()); | |
} | |
@Override | |
public boolean isRepeatable() { | |
return false; | |
} | |
}); | |
} | |
method = post; | |
} | |
} | |
else { | |
throw new SolrServerException("Unsupported method: "+request.getMethod() ); | |
} | |
} | |
catch( NoHttpResponseException r ) { | |
method = null; | |
if(is != null) { | |
is.close(); | |
} | |
// If out of tries then just rethrow (as normal error). | |
if (tries < 1) { | |
throw r; | |
} | |
} | |
} | |
} catch (IOException ex) { | |
throw new SolrServerException("error reading streams", ex); | |
} | |
// XXX client already has this set, is this needed? | |
method.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, | |
followRedirects); | |
method.addHeader("User-Agent", AGENT); | |
InputStream respBody = null; | |
boolean shouldClose = true; | |
boolean success = false; | |
try { | |
// Execute the method. | |
final HttpResponse response = httpClient.execute(method); | |
int httpStatus = response.getStatusLine().getStatusCode(); | |
// Read the contents | |
respBody = response.getEntity().getContent(); | |
Header ctHeader = response.getLastHeader("content-type"); | |
String contentType; | |
if (ctHeader != null) { | |
contentType = ctHeader.getValue(); | |
} else { | |
contentType = ""; | |
} | |
// handle some http level checks before trying to parse the response | |
switch (httpStatus) { | |
case HttpStatus.SC_OK: | |
case HttpStatus.SC_BAD_REQUEST: | |
case HttpStatus.SC_CONFLICT: // 409 | |
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; | |
default: | |
if (processor == null) { | |
throw new RemoteSolrException(httpStatus, "Server at " | |
+ getBaseURL() + " returned non ok status:" + httpStatus | |
+ ", message:" + response.getStatusLine().getReasonPhrase(), | |
null); | |
} | |
} | |
if (processor == null) { | |
// no processor specified, return raw stream | |
NamedList<Object> rsp = new NamedList<Object>(); | |
rsp.add("stream", respBody); | |
// Only case where stream should not be closed | |
shouldClose = false; | |
success = true; | |
return rsp; | |
} | |
String procCt = processor.getContentType(); | |
if (procCt != null) { | |
if (!contentType.equals(procCt)) { | |
// unexpected content type | |
String msg = "Expected content type " + procCt + " but got " + contentType + "."; | |
Header encodingHeader = response.getEntity().getContentEncoding(); | |
String encoding; | |
if (encodingHeader != null) { | |
encoding = encodingHeader.getValue(); | |
} else { | |
encoding = "UTF-8"; // try UTF-8 | |
} | |
try { | |
msg = msg + " " + IOUtils.toString(respBody, encoding); | |
} catch (IOException e) { | |
throw new RemoteSolrException(httpStatus, "Could not parse response with encoding " + encoding, e); | |
} | |
RemoteSolrException e = new RemoteSolrException(httpStatus, msg, null); | |
throw e; | |
} | |
} | |
// if(true) { | |
// ByteArrayOutputStream copy = new ByteArrayOutputStream(); | |
// IOUtils.copy(respBody, copy); | |
// String val = new String(copy.toByteArray()); | |
// System.out.println(">RESPONSE>"+val+"<"+val.length()); | |
// respBody = new ByteArrayInputStream(copy.toByteArray()); | |
// } | |
NamedList<Object> rsp = null; | |
String charset = EntityUtils.getContentCharSet(response.getEntity()); | |
try { | |
rsp = processor.processResponse(respBody, charset); | |
} catch (Exception e) { | |
throw new RemoteSolrException(httpStatus, e.getMessage(), e); | |
} | |
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 RemoteSolrException(httpStatus, reason, null); | |
} | |
success = true; | |
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 && shouldClose) { | |
try { | |
respBody.close(); | |
} catch (Throwable t) {} // ignore | |
if (!success) { | |
method.abort(); | |
} | |
} | |
} | |
} | |
// ------------------------------------------------------------------- | |
// ------------------------------------------------------------------- | |
/** | |
* 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; | |
} | |
/** | |
* Return the HttpClient this instance uses. | |
*/ | |
public HttpClient getHttpClient() { | |
return httpClient; | |
} | |
/** | |
* HttpConnectionParams.setConnectionTimeout | |
* | |
* @param timeout | |
* Timeout in milliseconds | |
**/ | |
public void setConnectionTimeout(int timeout) { | |
HttpClientUtil.setConnectionTimeout(httpClient, timeout); | |
} | |
/** | |
* Set SoTimeout (read timeout). This is desirable | |
* for queries, but probably not for indexing. | |
* | |
* @param timeout | |
* Timeout in milliseconds | |
**/ | |
public void setSoTimeout(int timeout) { | |
HttpClientUtil.setSoTimeout(httpClient, timeout); | |
} | |
/** | |
* Configure whether the client should follow redirects or not. | |
* <p> | |
* This defaults to false under the assumption that if you are following a | |
* redirect to get to a Solr installation, something is misconfigured | |
* somewhere. | |
* </p> | |
*/ | |
public void setFollowRedirects(boolean followRedirects) { | |
this.followRedirects = true; | |
HttpClientUtil.setFollowRedirects(httpClient, followRedirects); | |
} | |
/** | |
* Allow server->client communication to be compressed. Currently gzip and | |
* deflate are supported. If the server supports compression the response will | |
* be compressed. This method is only allowed if the http client is of type | |
* DefatulHttpClient. | |
*/ | |
public void setAllowCompression(boolean allowCompression) { | |
if (httpClient instanceof AndroidHttpClient) { | |
// HttpClientUtil.setAllowCompression( httpClient, allowCompression); | |
} else { | |
throw new UnsupportedOperationException( | |
"HttpClient instance was not of type DefaultHttpClient"); | |
} | |
} | |
/** | |
* Set maximum number of retries to attempt in the event of transient errors. | |
* <p> | |
* Maximum number of retries to attempt in the event of transient errors. | |
* Default: 0 (no) retries. No more than 1 recommended. | |
* </p> | |
* @param maxRetries | |
* No more than 1 recommended | |
*/ | |
public void setMaxRetries(int maxRetries) { | |
if (maxRetries > 1) { | |
log.warn("HttpSolrServer: 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>() { | |
@Override | |
public boolean hasNext() { | |
return beanIterator.hasNext(); | |
} | |
@Override | |
public SolrInputDocument next() { | |
Object o = beanIterator.next(); | |
if (o == null) return null; | |
return getBinder().toSolrInputDocument(o); | |
} | |
@Override | |
public void remove() { | |
beanIterator.remove(); | |
} | |
}); | |
return req.process(this); | |
} | |
/** | |
* Close the {@link ClientConnectionManager} from the internal client. | |
*/ | |
@Override | |
public void shutdown() { | |
if (httpClient != null && internalClient) { | |
httpClient.getConnectionManager().shutdown(); | |
} | |
} | |
/** | |
* Set the maximum number of connections that can be open to a single host at | |
* any given time. If http client was created outside the operation is not | |
* allowed. | |
*/ | |
public void setDefaultMaxConnectionsPerHost(int max) { | |
if (internalClient) { | |
HttpClientUtil.setMaxConnectionsPerHost(httpClient, 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. | |
* If http client was created outside the operation is not allowed. | |
*/ | |
public void setMaxTotalConnections(int max) { | |
if (internalClient) { | |
HttpClientUtil.setMaxConnections(httpClient, max); | |
} else { | |
throw new UnsupportedOperationException( | |
"Client was created outside of HttpSolrServer"); | |
} | |
} | |
public boolean isUseMultiPartPost() { | |
return useMultiPartPost; | |
} | |
/** | |
* Set the multipart connection properties | |
*/ | |
public void setUseMultiPartPost(boolean useMultiPartPost) { | |
this.useMultiPartPost = useMultiPartPost; | |
} | |
/** | |
* Subclass of SolrException that allows us to capture an arbitrary HTTP | |
* status code that may have been returned by the remote server or a | |
* proxy along the way. | |
*/ | |
public static class RemoteSolrException extends SolrException { | |
/** | |
* @param code Arbitrary HTTP status code | |
* @param msg Exception Message | |
* @param th Throwable to wrap with this Exception | |
*/ | |
public RemoteSolrException(int code, String msg, Throwable th) { | |
super(code, msg, th); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import org.apache.solr.client.solrj.SolrQuery; | |
import org.apache.solr.client.solrj.SolrQuery.ORDER; | |
import org.apache.solr.client.solrj.response.QueryResponse; | |
import org.apache.solr.common.params.SolrParams; | |
import org.apache.solr.common.util.NamedList; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import android.net.http.AndroidHttpClient; | |
import android.os.AsyncTask; | |
import android.util.Log; | |
public class SOLRRequestTask extends AsyncTask<Integer, Void, QueryResponse> { | |
private static final Logger logger = LoggerFactory.getLogger(SOLRQueryUtil.class); | |
private Exception exception; | |
private AndroidHttpClient ahtp ; | |
@Override | |
protected QueryResponse doInBackground(Integer... params) { | |
ArrayList<String> arl = new ArrayList<String>(); | |
try { | |
HttpSolrServer server = new HttpSolrServer("http://your.solr.url/stub", ahtp); | |
// NamedList nml = new NamedList(); | |
// nml.add("bq", "Language:en^10"); | |
// nml.add("bq", "Title:Some*Title*^100"); | |
// nml.add("bq", "Title:Some*Title*^10"); | |
// SolrParams slrp = SolrParams.toSolrParams(nml); | |
// SolrQuery query = new SolrQuery(); | |
// query.add(slrp); | |
query.setQuery("*"); | |
query.setRequestHandler("/search"); // your request type | |
query.add("bq","Language:en^10"); | |
query.addFacetQuery("Title:*Some*Title*"); | |
query.addSort("score", ORDER.desc); | |
query.setRows(params[0]); | |
query.setStart(params[1]); | |
return server.query(query); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
return null; | |
} | |
} | |
@Override | |
protected void onPostExecute(QueryResponse response) { | |
if(Util.isEmpty(response)){ | |
logger.debug("@******* SOLR RESPONSE EMPTY" + String.valueOf(response) ); | |
Log.d("@******* SOLR RESPONSE EMPTY" , String.valueOf(response)); | |
}else{ | |
logger.debug("@******* SOLR RESPONSE" + String.valueOf(response) ); | |
Log.d("@******* SOLR RESPONSE " , String.valueOf(response)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment