Skip to content
This repository was archived by the owner on Jan 31, 2022. It is now read-only.

Commit 57e9ab1

Browse files
author
Clément Le Provost
committed
[offline] Add support for getObject() in MirroredIndex
1 parent 1994db3 commit 57e9ab1

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed

algoliasearch/src/offline/java/com/algolia/search/saas/MirroredIndex.java

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import java.io.Writer;
4444
import java.util.ArrayList;
4545
import java.util.Arrays;
46+
import java.util.Collections;
4647
import java.util.Date;
4748
import java.util.HashSet;
4849
import java.util.List;
@@ -1249,6 +1250,117 @@ private JSONObject _browseMirror(@NonNull Query query) throws AlgoliaException
12491250
// Getting individual objects
12501251
// ----------------------------------------------------------------------
12511252

1253+
/**
1254+
* Get an individual object from the online API, falling back to the local mirror in case of error (when enabled).
1255+
*
1256+
* @param objectID Identifier of the object to retrieve.
1257+
* @param attributesToRetrieve Attributes to retrieve. If `null` or if at least one item is `*`, all retrievable
1258+
* attributes will be retrieved.
1259+
* @param completionHandler The listener that will be notified of the request's outcome.
1260+
* @return A cancellable request.
1261+
*/
1262+
@Override
1263+
public Request getObjectAsync(final @NonNull String objectID, final @Nullable List<String> attributesToRetrieve, @NonNull CompletionHandler completionHandler) {
1264+
if (!mirrored) {
1265+
return super.getObjectAsync(objectID, attributesToRetrieve, completionHandler);
1266+
} else {
1267+
return new OnlineOfflineGetObjectRequest(objectID, attributesToRetrieve, completionHandler).start();
1268+
}
1269+
}
1270+
1271+
private class OnlineOfflineGetObjectRequest extends OnlineOfflineRequest {
1272+
private final String objectID;
1273+
private final List<String> attributesToRetrieve;
1274+
1275+
public OnlineOfflineGetObjectRequest(@NonNull String objectID, final @Nullable List<String> attributesToRetrieve, @NonNull CompletionHandler completionHandler) {
1276+
super(completionHandler);
1277+
this.objectID = objectID;
1278+
this.attributesToRetrieve = attributesToRetrieve;
1279+
}
1280+
1281+
@Override
1282+
protected Request startOnlineRequest(CompletionHandler completionHandler) {
1283+
return getObjectOnlineAsync(objectID, attributesToRetrieve, completionHandler);
1284+
}
1285+
1286+
@Override
1287+
protected Request startOfflineRequest(CompletionHandler completionHandler) {
1288+
return getObjectOfflineAsync(objectID, attributesToRetrieve, completionHandler);
1289+
}
1290+
}
1291+
1292+
/**
1293+
* Get an individual object, explicitly targeting the online API, not the offline mirror.
1294+
*
1295+
* @param objectID Identifier of the object to retrieve.
1296+
* @param attributesToRetrieve Attributes to retrieve. If `null` or if at least one item is `*`, all retrievable
1297+
* attributes will be retrieved.
1298+
* @param completionHandler The listener that will be notified of the request's outcome.
1299+
* @return A cancellable request.
1300+
*/
1301+
public Request getObjectOnlineAsync(@NonNull final String objectID, final @Nullable List<String> attributesToRetrieve, @NonNull final CompletionHandler completionHandler) {
1302+
// TODO: Cannot perform origin tagging because it could conflict with the object's attributes
1303+
return super.getObjectAsync(objectID, attributesToRetrieve, completionHandler);
1304+
}
1305+
1306+
/**
1307+
* Get an individual object, explicitly targeting the online API, not the offline mirror.
1308+
*
1309+
* @param objectID Identifier of the object to retrieve.
1310+
* @param completionHandler The listener that will be notified of the request's outcome.
1311+
* @return A cancellable request.
1312+
*/
1313+
public Request getObjectOnlineAsync(@NonNull final String objectID, @NonNull final CompletionHandler completionHandler) {
1314+
return getObjectOnlineAsync(objectID, null, completionHandler);
1315+
}
1316+
1317+
/**
1318+
* Get an individual object, explicitly targeting the offline mirror, not the online API.
1319+
*
1320+
* @param objectID Identifier of the object to retrieve.
1321+
* @param attributesToRetrieve Attributes to retrieve. If `null` or if at least one item is `*`, all retrievable
1322+
* attributes will be retrieved.
1323+
* @param completionHandler The listener that will be notified of the request's outcome.
1324+
* @return A cancellable request.
1325+
* @throws IllegalStateException if mirroring is not activated on this index.
1326+
*/
1327+
public Request getObjectOfflineAsync(@NonNull final String objectID, final @Nullable List<String> attributesToRetrieve, @NonNull CompletionHandler completionHandler) {
1328+
if (!mirrored) {
1329+
throw new IllegalStateException("Mirroring not activated on this index");
1330+
}
1331+
return getClient().new AsyncTaskRequest(completionHandler, getClient().localSearchExecutorService) {
1332+
@NonNull
1333+
@Override
1334+
protected JSONObject run() throws AlgoliaException {
1335+
return _getObjectOffline(objectID, attributesToRetrieve);
1336+
}
1337+
}.start();
1338+
}
1339+
1340+
/**
1341+
* Get an individual object, explicitly targeting the offline mirror, not the online API.
1342+
*
1343+
* @param objectID Identifier of the object to retrieve.
1344+
* @param completionHandler The listener that will be notified of the request's outcome.
1345+
* @return A cancellable request.
1346+
* @throws IllegalStateException if mirroring is not activated on this index.
1347+
*/
1348+
public Request getObjectOfflineAsync(@NonNull final String objectID, @NonNull final CompletionHandler completionHandler) {
1349+
return getObjectOfflineAsync(objectID, null, completionHandler);
1350+
}
1351+
1352+
private JSONObject _getObjectOffline(@NonNull final String objectID, final @Nullable List<String> attributesToRetrieve) throws AlgoliaException
1353+
{
1354+
try {
1355+
JSONObject content = _getObjectsOffline(Collections.singletonList(objectID), attributesToRetrieve);
1356+
JSONArray results = content.getJSONArray("results");
1357+
return results.getJSONObject(0);
1358+
}
1359+
catch (JSONException e) {
1360+
throw new AlgoliaException("Invalid response returned", e); // should never happen
1361+
}
1362+
}
1363+
12521364
/**
12531365
* Get individual objects from the online API, falling back to the local mirror in case of error (when enabled).
12541366
*

algoliasearch/src/testOffline/java/com/algolia/search/saas/MirroredIndexTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,54 @@ public void doRequestCompleted(JSONObject content, AlgoliaException error) {
314314
});
315315
}
316316

317+
@Test
318+
public void testGetObject() {
319+
final CountDownLatch signal = new CountDownLatch(4);
320+
321+
// Populate the online index & sync the offline mirror.
322+
final MirroredIndex index = client.getIndex(Helpers.safeIndexName(Helpers.getMethodName()));
323+
sync(index, new SyncCompletionHandler() {
324+
@Override
325+
public void syncCompleted(@Nullable Throwable error) {
326+
assertNull(error);
327+
328+
// Query the online index explicitly.
329+
index.getObjectOnlineAsync("1", new AssertCompletionHandler() {
330+
@Override
331+
public void doRequestCompleted(JSONObject content, AlgoliaException error) {
332+
assertNull(error);
333+
assertEquals("Snoopy", content.optString("name"));
334+
335+
// Test offline fallback.
336+
client.setReadHosts("unknown.algolia.com");
337+
index.setRequestStrategy(MirroredIndex.Strategy.FALLBACK_ON_FAILURE);
338+
index.getObjectAsync("3", new AssertCompletionHandler() {
339+
@Override
340+
public void doRequestCompleted(JSONObject content, AlgoliaException error) {
341+
assertNull(error);
342+
assertEquals("Charlie Brown", content.optString("name"));
343+
signal.countDown();
344+
}
345+
});
346+
signal.countDown();
347+
}
348+
});
349+
350+
// Query the offline index explicitly.
351+
index.getObjectOfflineAsync("2", new AssertCompletionHandler() {
352+
@Override
353+
public void doRequestCompleted(JSONObject content, AlgoliaException error) {
354+
assertNull(error);
355+
assertEquals("Woodstock", content.optString("name"));
356+
signal.countDown();
357+
}
358+
});
359+
360+
signal.countDown();
361+
}
362+
});
363+
}
364+
317365
@Test
318366
public void testGetObjects() {
319367
final CountDownLatch signal = new CountDownLatch(4);

0 commit comments

Comments
 (0)