diff --git a/ChangeLog b/ChangeLog index 63f691452..acc7bc940 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,13 @@ Changelog ========= +1.3.4 (2015-04-09) +------------------------ +- Better retry strategy using two different provider (Improve high-availability of the solution, retry is done on algolianet.com) +- Read operations are performed to APPID-dsn.algolia.net domain first to leverage Distributed Search Network (select the closest location) +- Improved timeout strategy: increasse timeout after 2 trials & have a different read timeout for search operations + + 1.3.3 (2015-03-03) ------------------------ - Move to Maven Central diff --git a/src/main/java/com/algolia/search/saas/APIClient.java b/src/main/java/com/algolia/search/saas/APIClient.java index ffb45a941..d7f5c05c4 100644 --- a/src/main/java/com/algolia/search/saas/APIClient.java +++ b/src/main/java/com/algolia/search/saas/APIClient.java @@ -44,7 +44,7 @@ import org.json.JSONTokener; /* - * Copyright (c) 2013 Algolia + * Copyright (c) 2015 Algolia * http://www.algolia.com/ * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -73,8 +73,9 @@ */ public class APIClient { private int httpSocketTimeoutMS = 30000; - private int httpConnectTimeoutMS = 3000; - + private int httpConnectTimeoutMS = 2000; + private int httpSearchTimeoutMS = 5000; + private final static String version; static { String tmp = "N/A"; @@ -109,13 +110,11 @@ public class APIClient { * @param apiKey a valid API key for the service */ public APIClient(String applicationID, String apiKey) { - this(applicationID, apiKey, Arrays.asList(applicationID + "-1.algolia.net", - applicationID + "-2.algolia.net", - applicationID + "-3.algolia.net")); - Collections.shuffle(this.buildHostsArray); + this(applicationID, apiKey, Arrays.asList(applicationID + "-1.algolianet.com", + applicationID + "-2.algolianet.com", + applicationID + "-3.algolianet.com")); this.buildHostsArray.add(0, applicationID + ".algolia.net"); this.buildHostsEnabled.add(0L); - Collections.shuffle(this.queryHostsArray); this.queryHostsArray.add(0, applicationID + "-dsn.algolia.net"); this.queryHostsEnabled.add(0L); } @@ -235,7 +234,7 @@ public JSONObject moveIndex(String srcIndexName, String dstIndexName) throws Alg JSONObject content = new JSONObject(); content.put("operation", "move"); content.put("destination", dstIndexName); - return postRequest("/1/indexes/" + URLEncoder.encode(srcIndexName, "UTF-8") + "/operation", content.toString(), true); + return postRequest("/1/indexes/" + URLEncoder.encode(srcIndexName, "UTF-8") + "/operation", content.toString(), true, false); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); // $COVERAGE-IGNORE$ } catch (JSONException e) { @@ -253,7 +252,7 @@ public JSONObject copyIndex(String srcIndexName, String dstIndexName) throws Alg JSONObject content = new JSONObject(); content.put("operation", "copy"); content.put("destination", dstIndexName); - return postRequest("/1/indexes/" + URLEncoder.encode(srcIndexName, "UTF-8") + "/operation", content.toString(), true); + return postRequest("/1/indexes/" + URLEncoder.encode(srcIndexName, "UTF-8") + "/operation", content.toString(), true, false); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); // $COVERAGE-IGNORE$ } catch (JSONException e) { @@ -374,7 +373,7 @@ public JSONObject addUserKey(List acls) throws AlgoliaException { } catch (JSONException e) { throw new RuntimeException(e); // $COVERAGE-IGNORE$ } - return postRequest("/1/keys", jsonObject.toString(), true); + return postRequest("/1/keys", jsonObject.toString(), true, false); } /** @@ -468,7 +467,7 @@ public JSONObject addUserKey(List acls, int validity, int maxQueriesPerI } catch (JSONException e) { throw new RuntimeException(e); // $COVERAGE-IGNORE$ } - return postRequest("/1/keys", jsonObject.toString(), true); + return postRequest("/1/keys", jsonObject.toString(), true, false); } /** @@ -581,23 +580,23 @@ private static enum Method { GET, POST, PUT, DELETE, OPTIONS, TRACE, HEAD; } - protected JSONObject getRequest(String url, boolean build) throws AlgoliaException { - return _request(Method.GET, url, null, build); + protected JSONObject getRequest(String url, boolean search) throws AlgoliaException { + return _request(Method.GET, url, null, false, search); } protected JSONObject deleteRequest(String url, boolean build) throws AlgoliaException { - return _request(Method.DELETE, url, null, build); + return _request(Method.DELETE, url, null, build, false); } - protected JSONObject postRequest(String url, String obj, boolean build) throws AlgoliaException { - return _request(Method.POST, url, obj, build); + protected JSONObject postRequest(String url, String obj, boolean build, boolean search) throws AlgoliaException { + return _request(Method.POST, url, obj, build, search); } protected JSONObject putRequest(String url, String obj, boolean build) throws AlgoliaException { - return _request(Method.PUT, url, obj, build); + return _request(Method.PUT, url, obj, build, false); } - private JSONObject _requestByHost(HttpRequestBase req, String host, String url, String json, HashMap errors) throws AlgoliaException { + private JSONObject _requestByHost(HttpRequestBase req, String host, String url, String json, HashMap errors, boolean searchTimeout) throws AlgoliaException { req.reset(); // set URL @@ -640,7 +639,7 @@ private JSONObject _requestByHost(HttpRequestBase req, String host, String url, } RequestConfig config = RequestConfig.custom() - .setSocketTimeout(httpSocketTimeoutMS) + .setSocketTimeout(searchTimeout ? httpSearchTimeoutMS : httpSocketTimeoutMS) .setConnectTimeout(httpConnectTimeoutMS) .setConnectionRequestTimeout(httpConnectTimeoutMS) .build(); @@ -701,7 +700,7 @@ private JSONObject _requestByHost(HttpRequestBase req, String host, String url, } } - private JSONObject _request(Method m, String url, String json, boolean build) throws AlgoliaException { + private JSONObject _request(Method m, String url, String json, boolean build, boolean search) throws AlgoliaException { HttpRequestBase req; switch (m) { case DELETE: @@ -735,7 +734,7 @@ private JSONObject _request(Method m, String url, String json, boolean build) th String host = hosts.get(i); if (enabled.get(i) > System.currentTimeMillis()) continue; - JSONObject res = _requestByHost(req, host, url, json, errors); + JSONObject res = _requestByHost(req, host, url, json, errors, search); if (res != null) return res; enabled.set(i, System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(30, TimeUnit.SECONDS)); @@ -784,7 +783,7 @@ public JSONObject multipleQueries(List queries) throws AlgoliaExcept requests.put(new JSONObject().put("indexName", indexQuery.getIndex()).put("params", paramsString)); } JSONObject body = new JSONObject().put("requests", requests); - return postRequest("/1/indexes/*/queries", body.toString(), false); + return postRequest("/1/indexes/*/queries", body.toString(), false, true); } catch (JSONException e) { new AlgoliaException(e.getMessage()); } diff --git a/src/main/java/com/algolia/search/saas/AlgoliaException.java b/src/main/java/com/algolia/search/saas/AlgoliaException.java index ee41415a9..4de47fb0b 100644 --- a/src/main/java/com/algolia/search/saas/AlgoliaException.java +++ b/src/main/java/com/algolia/search/saas/AlgoliaException.java @@ -1,7 +1,7 @@ package com.algolia.search.saas; /* - * Copyright (c) 2013 Algolia + * Copyright (c) 2015 Algolia * http://www.algolia.com/ * * Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/src/main/java/com/algolia/search/saas/Index.java b/src/main/java/com/algolia/search/saas/Index.java index fdadd2338..9dc3361b3 100644 --- a/src/main/java/com/algolia/search/saas/Index.java +++ b/src/main/java/com/algolia/search/saas/Index.java @@ -16,7 +16,7 @@ /* - * Copyright (c) 2013 Algolia + * Copyright (c) 2015 Algolia * http://www.algolia.com/ * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -74,7 +74,7 @@ public String getIndexName() { * @param obj the object to add */ public JSONObject addObject(JSONObject obj) throws AlgoliaException { - return client.postRequest("/1/indexes/" + encodedIndexName, obj.toString(), true); + return client.postRequest("/1/indexes/" + encodedIndexName, obj.toString(), true, false); } /** @@ -102,7 +102,7 @@ public JSONObject batch(JSONArray actions) throws AlgoliaException { try { JSONObject content = new JSONObject(); content.put("requests", actions); - return client.postRequest("/1/indexes/" + encodedIndexName + "/batch", content.toString(), true); + return client.postRequest("/1/indexes/" + encodedIndexName + "/batch", content.toString(), true, false); } catch (JSONException e) { throw new AlgoliaException(e.getMessage()); } @@ -118,7 +118,7 @@ public JSONObject batch(List actions) throws AlgoliaException { try { JSONObject content = new JSONObject(); content.put("requests", actions); - return client.postRequest("/1/indexes/" + encodedIndexName + "/batch", content.toString(), true); + return client.postRequest("/1/indexes/" + encodedIndexName + "/batch", content.toString(), true, false); } catch (JSONException e) { throw new AlgoliaException(e.getMessage()); } @@ -221,7 +221,7 @@ public JSONObject getObjects(List objectIDs) throws AlgoliaException { } JSONObject body = new JSONObject(); body.put("requests", requests); - return client.postRequest("/1/indexes/*/objects", body.toString(), false); + return client.postRequest("/1/indexes/*/objects", body.toString(), false, false); } catch (JSONException e){ throw new AlgoliaException(e.getMessage()); } @@ -234,7 +234,7 @@ public JSONObject getObjects(List objectIDs) throws AlgoliaException { */ public JSONObject partialUpdateObject(JSONObject partialObject, String objectID) throws AlgoliaException { try { - return client.postRequest("/1/indexes/" + encodedIndexName + "/" + URLEncoder.encode(objectID, "UTF-8") + "/partial", partialObject.toString(), true); + return client.postRequest("/1/indexes/" + encodedIndexName + "/" + URLEncoder.encode(objectID, "UTF-8") + "/partial", partialObject.toString(), true, false); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } @@ -391,7 +391,7 @@ public void deleteByQuery(Query query) throws AlgoliaException { */ public JSONObject search(Query params) throws AlgoliaException { String paramsString = params.getQueryString(); - return client.getRequest("/1/indexes/" + encodedIndexName + ((paramsString.length() > 0) ? ("?" + paramsString) : ""), false); + return client.getRequest("/1/indexes/" + encodedIndexName + ((paramsString.length() > 0) ? ("?" + paramsString) : ""), true); } /** @@ -447,7 +447,7 @@ public JSONObject browse(int page, int hitsPerPage) throws AlgoliaException { public void waitTask(String taskID, long timeToWait) throws AlgoliaException { try { while (true) { - JSONObject obj = client.getRequest("/1/indexes/" + encodedIndexName + "/task/" + URLEncoder.encode(taskID, "UTF-8"), true); + JSONObject obj = client.getRequest("/1/indexes/" + encodedIndexName + "/task/" + URLEncoder.encode(taskID, "UTF-8"), false); if (obj.getString("status").equals("published")) return; try { @@ -485,7 +485,7 @@ public JSONObject getSettings() throws AlgoliaException { * Delete the index content without removing settings and index specific API keys. */ public JSONObject clearIndex() throws AlgoliaException { - return client.postRequest("/1/indexes/" + encodedIndexName + "/clear", "", true); + return client.postRequest("/1/indexes/" + encodedIndexName + "/clear", "", true, false); } /** @@ -577,7 +577,7 @@ public JSONObject addUserKey(List acls) throws AlgoliaException { } catch (JSONException e) { throw new RuntimeException(e); } - return client.postRequest("/1/indexes/" + encodedIndexName + "/keys", jsonObject.toString(), true); + return client.postRequest("/1/indexes/" + encodedIndexName + "/keys", jsonObject.toString(), true, false); } /** @@ -629,7 +629,7 @@ public JSONObject addUserKey(List acls, int validity, int maxQueriesPerI } catch (JSONException e) { throw new RuntimeException(e); } - return client.postRequest("/1/indexes/" + encodedIndexName + "/keys", jsonObject.toString(), true); + return client.postRequest("/1/indexes/" + encodedIndexName + "/keys", jsonObject.toString(), true, false); } /** diff --git a/src/main/java/com/algolia/search/saas/Query.java b/src/main/java/com/algolia/search/saas/Query.java index 00b4e845a..6b6778a16 100644 --- a/src/main/java/com/algolia/search/saas/Query.java +++ b/src/main/java/com/algolia/search/saas/Query.java @@ -8,7 +8,7 @@ import org.json.JSONArray; /* - * Copyright (c) 2013 Algolia + * Copyright (c) 2015 Algolia * http://www.algolia.com/ * * Permission is hereby granted, free of charge, to any person obtaining a copy