/** * This software is licensed to you under the Apache License, Version 2.0 (the * "Apache License"). * * LinkedIn's contributions are made under the Apache License. If you contribute * to the Software, the contributions will be deemed to have been made under the * Apache License, unless you expressly indicate otherwise. Please do not make any * contributions that would be inconsistent with the Apache License. * * You may obtain a copy of the Apache License at http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, this software * distributed under the Apache License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Apache * License for the specific language governing permissions and limitations for the * software governed under the Apache License. * * © 2012 LinkedIn Corp. All Rights Reserved. */ package com.senseidb.search.client; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.zip.GZIPInputStream; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.apache.log4j.Logger; import com.senseidb.search.client.json.JsonDeserializer; import com.senseidb.search.client.json.JsonSerializer; import com.senseidb.search.client.req.SenseiClientRequest; import com.senseidb.search.client.res.SenseiResult; public class SenseiServiceProxy { private static Logger LOG = Logger.getLogger(SenseiServiceProxy.class); private String host; private int port; private final String url; /*private static HttpClient httpclient; private static synchronized HttpClient getHttpClient() { if (httpclient == null) { ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(); cm.setMaxTotal(200); cm.setDefaultMaxPerRoute(100); HttpParams params = new BasicHttpParams(); params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 100); params.setParameter(CoreConnectionPNames.TCP_NODELAY, false); params.setParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false); params.setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.FALSE); //params.setParameter("http.protocol.version", HttpVersion.HTTP_1_1); httpclient = new DefaultHttpClient(cm, params); } return httpclient; }*/ public SenseiServiceProxy(String host, int port) { this.host = host; this.port = port; this.url = null; } public SenseiServiceProxy(String url) { this.url = url; } public SenseiResult sendSearchRequest( SenseiClientRequest request) { try { String requestStr = JsonSerializer.serialize(request).toString(); String output = sendPostRaw(getSearchUrl(), requestStr); //System.out.println("Output from Server = " + output); return JsonDeserializer.deserialize(SenseiResult.class, jsonResponse(output)); } catch (Exception ex) { throw new RuntimeException(ex); } } public SenseiResult sendBQL( String bql) { try { StringBuilder buffer = new StringBuilder(); buffer.append("{'bql':").append(bql).append("}"); String requestStr = buffer.toString(); String output = sendPostRaw(getSearchUrl(), requestStr); return JsonDeserializer.deserialize(SenseiResult.class, jsonResponse(output)); } catch (Exception ex) { throw new RuntimeException(ex); } } public Map<Long, JSONObject> sendGetRequest(long... uids) throws IOException, JSONException { Map<Long, JSONObject> ret = new LinkedHashMap<Long, JSONObject>(uids.length); String response = sendPostRaw(getStoreGetUrl(), new JSONArray(uids).toString()); if (response == null || response.length() == 0) { return ret; } JSONObject responseJson = new JSONObject(response); Iterator keys = responseJson.keys(); while (keys.hasNext()) { String key = (String) keys.next(); ret.put(Long.parseLong(key), responseJson.optJSONObject(key)); } return ret; } public String getSearchUrl() { if (url != null) return url; return "http://" + host + ":" + port + "/sensei"; } public String getStoreGetUrl() { if (url != null) return url + "/get"; return "http://" + host + ":" + port + "/sensei/get"; } /*public String sendPost(String path, String requestStr) { HttpPost httpPost = new HttpPost(path); try { httpPost.setHeader("Content-Type", "application/json; charset=utf-8"); httpPost.setHeader("Accept-Encoding", "gzip"); httpPost.setHeader("http.keepAlive", String.valueOf(true)); httpPost.setHeader("default", String.valueOf(true)); httpPost.setEntity(new StringEntity(requestStr)); if (LOG.isDebugEnabled()){ LOG.debug("Sending a post request to the server - " + path); } if (LOG.isDebugEnabled()){ LOG.debug("The request is - " + requestStr); } HttpResponse response = getHttpClient().execute(httpPost); int responseCode = response.getStatusLine().getStatusCode(); if (LOG.isDebugEnabled()){ LOG.debug("The http response code is " + responseCode); } if (responseCode != HttpURLConnection.HTTP_OK) { throw new IOException("Failed : HTTP error code : " + responseCode); } HttpEntity entity = response.getEntity(); byte[] bytes = drain(new GZIPInputStream(new BufferedInputStream( entity.getContent()))); String output = new String(bytes, "UTF-8"); if (LOG.isDebugEnabled()){ LOG.debug("The response from the server is - " + output); } return output; } catch (Exception ex) { httpPost.abort(); throw new RuntimeException(ex); } }*/ private JSONObject jsonResponse(String output) throws JSONException { return new JSONObject(output); } byte[] drain(InputStream inputStream) throws IOException { try { byte[] buf = new byte[1024]; int len; ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); while ((len = inputStream.read(buf)) > 0) { byteArrayOutputStream.write(buf, 0, len); } return byteArrayOutputStream.toByteArray(); } finally { inputStream.close(); } } public String sendPostRaw(String urlStr, String requestStr){ return this.sendPostRaw(urlStr, requestStr,null); } /*public void close() { getHttpClient().getConnectionManager().shutdown(); }*/ public String sendPostRaw(String urlStr, String requestStr,Map<String,String> headers){ HttpURLConnection conn = null; try { /*if (LOG.isInfoEnabled()){ LOG.info("Sending a post request to the server - " + urlStr); } if (LOG.isDebugEnabled()){ LOG.debug("The request is - " + requestStr); }*/ URL url = new URL(urlStr); conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setRequestMethod("POST"); // conn.setRequestProperty("Content-Type", "application/json; charset=utf-8"); conn.setRequestProperty("Accept-Encoding", "gzip"); String string = requestStr; byte[] requestBytes = string.getBytes("UTF-8"); conn.setRequestProperty("Content-Length", String.valueOf(requestBytes.length)); conn.setRequestProperty("http.keepAlive", String.valueOf(true)); conn.setRequestProperty("default", String.valueOf(true)); if (headers!=null && headers.size()>0){ Set<Entry<String,String>> entries = headers.entrySet(); for (Entry<String,String> entry : entries){ conn.setRequestProperty(entry.getKey(),entry.getValue()); } } //GZIPOutputStream zippedOutputStream = new GZIPOutputStream(conn.getOutputStream()); OutputStream os = new BufferedOutputStream( conn.getOutputStream()); os.write(requestBytes); os.flush(); os.close(); int responseCode = conn.getResponseCode(); /*if (LOG.isInfoEnabled()){ LOG.info("The http response code is " + responseCode); }*/ if (responseCode != HttpURLConnection.HTTP_OK) { throw new IOException("Failed : HTTP error code : " + responseCode); } byte[] bytes = drain(new GZIPInputStream(new BufferedInputStream( conn.getInputStream()))); String output = new String(bytes, "UTF-8"); /*if (LOG.isDebugEnabled()){ LOG.debug("The response from the server is - " + output); }*/ return output; } catch (Exception ex) { throw new RuntimeException (ex); } finally { if (conn != null) conn.disconnect(); } } }