Skip to content

Commit 150b97c

Browse files
feat(java): add bridge to transformation on search (generated)
algolia/api-clients-automation#4939 Co-authored-by: algolia-bot <[email protected]> Co-authored-by: Clément Vannicatte <[email protected]>
1 parent 94d8f35 commit 150b97c

File tree

3 files changed

+238
-4
lines changed

3 files changed

+238
-4
lines changed

algoliasearch/src/main/java/com/algolia/ApiClient.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public abstract class ApiClient implements Closeable {
2828

2929
private final Requester requester;
3030
private final ExecutorService executor;
31-
private AuthInterceptor authInterceptor;
31+
public final ClientOptions clientOptions;
32+
public AuthInterceptor authInterceptor;
3233

3334
/** Constructs a new instance of the {@link ApiClient}. */
3435
protected ApiClient(
@@ -47,9 +48,9 @@ protected ApiClient(
4748
if (apiKey == null || apiKey.isEmpty()) {
4849
throw new AlgoliaRuntimeException("`apiKey` is missing.");
4950
}
50-
final ClientOptions clientOptions = options != null ? options : new ClientOptions();
51-
this.executor = clientOptions.getExecutor();
52-
this.requester = clientOptions.getCustomRequester() != null
51+
clientOptions = options != null ? options : new ClientOptions();
52+
executor = clientOptions.getExecutor();
53+
requester = clientOptions.getCustomRequester() != null
5354
? clientOptions.getCustomRequester()
5455
: defaultRequester(appId, apiKey, clientName, clientOptions, defaultHosts, connectTimeout, readTimeout, writeTimeout);
5556
}

algoliasearch/src/main/java/com/algolia/api/SearchClient.java

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@
88
import com.algolia.config.ClientOptions;
99
import com.algolia.exceptions.*;
1010
import com.algolia.internal.JsonSerializer;
11+
import com.algolia.model.ingestion.PushTaskPayload;
12+
import com.algolia.model.ingestion.PushTaskRecords;
13+
import com.algolia.model.ingestion.WatchResponse;
1114
import com.algolia.model.search.*;
1215
import com.algolia.utils.*;
1316
import com.fasterxml.jackson.core.type.TypeReference;
17+
import com.fasterxml.jackson.databind.ObjectMapper;
1418
import java.nio.charset.Charset;
1519
import java.security.InvalidKeyException;
1620
import java.security.NoSuchAlgorithmException;
@@ -36,6 +40,17 @@
3640

3741
public class SearchClient extends ApiClient {
3842

43+
private IngestionClient ingestionTransporter;
44+
45+
public void setTransformationRegion(String region) {
46+
this.ingestionTransporter = new IngestionClient(
47+
this.authInterceptor.getApplicationId(),
48+
this.authInterceptor.getApiKey(),
49+
region,
50+
this.clientOptions
51+
);
52+
}
53+
3954
public SearchClient(String appId, String apiKey) {
4055
this(appId, apiKey, null);
4156
}
@@ -6731,6 +6746,108 @@ public <T> List<BatchResponse> chunkedBatch(
67316746
return chunkedBatch(indexName, objects, action, waitForTasks, 1000, requestOptions);
67326747
}
67336748

6749+
/**
6750+
* Helper: Similar to the `saveObjects` method but requires a Push connector
6751+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
6752+
* to be created first, in order to transform records before indexing them to Algolia. The
6753+
* `region` must have been passed to the client instantiation method.
6754+
*
6755+
* @param indexName The `indexName` to replace `objects` in.
6756+
* @param objects The array of `objects` to store in the given Algolia `indexName`.
6757+
* @throws AlgoliaRetryException When the retry has failed on all hosts
6758+
* @throws AlgoliaApiException When the API sends an http error code
6759+
* @throws AlgoliaRuntimeException When an error occurred during the serialization
6760+
*/
6761+
public <T> WatchResponse saveObjectsWithTransformation(String indexName, Iterable<T> objects) {
6762+
return saveObjectsWithTransformation(indexName, objects, null);
6763+
}
6764+
6765+
/**
6766+
* Helper: Similar to the `saveObjects` method but requires a Push connector
6767+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
6768+
* to be created first, in order to transform records before indexing them to Algolia. The
6769+
* `region` must have been passed to the client instantiation method.
6770+
*
6771+
* @param indexName The `indexName` to replace `objects` in.
6772+
* @param objects The array of `objects` to store in the given Algolia `indexName`.
6773+
* @param requestOptions The requestOptions to send along with the query, they will be merged with
6774+
* the transporter requestOptions. (optional)
6775+
*/
6776+
public <T> WatchResponse saveObjectsWithTransformation(String indexName, Iterable<T> objects, RequestOptions requestOptions) {
6777+
return saveObjectsWithTransformation(indexName, objects, false, requestOptions);
6778+
}
6779+
6780+
/**
6781+
* Helper: Similar to the `saveObjects` method but requires a Push connector
6782+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
6783+
* to be created first, in order to transform records before indexing them to Algolia. The
6784+
* `region` must have been passed to the client instantiation method.
6785+
*
6786+
* @param indexName The `indexName` to replace `objects` in.
6787+
* @param objects The array of `objects` to store in the given Algolia `indexName`.
6788+
* @param waitForTasks - Whether or not we should wait until every `batch` tasks has been
6789+
* processed, this operation may slow the total execution time of this method but is more
6790+
* reliable.
6791+
* @param requestOptions The requestOptions to send along with the query, they will be merged with
6792+
* the transporter requestOptions. (optional)
6793+
*/
6794+
public <T> WatchResponse saveObjectsWithTransformation(
6795+
String indexName,
6796+
Iterable<T> objects,
6797+
boolean waitForTasks,
6798+
RequestOptions requestOptions
6799+
) {
6800+
return saveObjectsWithTransformation(indexName, objects, waitForTasks, 1000, requestOptions);
6801+
}
6802+
6803+
/**
6804+
* Helper: Similar to the `saveObjects` method but requires a Push connector
6805+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
6806+
* to be created first, in order to transform records before indexing them to Algolia. The
6807+
* `region` must have been passed to the client instantiation method.
6808+
*
6809+
* @param indexName The `indexName` to replace `objects` in.
6810+
* @param objects The array of `objects` to store in the given Algolia `indexName`.
6811+
* @param waitForTasks - Whether or not we should wait until every `batch` tasks has been
6812+
* processed, this operation may slow the total execution time of this method but is more
6813+
* reliable.
6814+
* @param batchSize The size of the chunk of `objects`. The number of `batch` calls will be equal
6815+
* to `length(objects) / batchSize`.
6816+
* @param requestOptions The requestOptions to send along with the query, they will be merged with
6817+
* the transporter requestOptions. (optional)
6818+
*/
6819+
public <T> WatchResponse saveObjectsWithTransformation(
6820+
String indexName,
6821+
Iterable<T> objects,
6822+
boolean waitForTasks,
6823+
int batchSize,
6824+
RequestOptions requestOptions
6825+
) {
6826+
if (this.ingestionTransporter == null) {
6827+
throw new AlgoliaRuntimeException("`setTransformationRegion` must have been called before calling this method.");
6828+
}
6829+
6830+
return this.ingestionTransporter.push(
6831+
indexName,
6832+
new PushTaskPayload().setAction(com.algolia.model.ingestion.Action.ADD_OBJECT).setRecords(this.objectsToPushTaskRecords(objects)),
6833+
waitForTasks,
6834+
requestOptions
6835+
);
6836+
}
6837+
6838+
private <T> List<PushTaskRecords> objectsToPushTaskRecords(Iterable<T> objects) {
6839+
try {
6840+
ObjectMapper mapper = new ObjectMapper();
6841+
String json = mapper.writeValueAsString(objects);
6842+
6843+
return mapper.readValue(json, new TypeReference<List<PushTaskRecords>>() {});
6844+
} catch (Exception e) {
6845+
throw new AlgoliaRuntimeException(
6846+
"each object must have an `objectID` key in order to be used with the" + " WithTransformation methods"
6847+
);
6848+
}
6849+
}
6850+
67346851
/**
67356852
* Helper: Saves the given array of objects in the given index. The `chunkedBatch` helper is used
67366853
* under the hood, which creates a `batch` requests with at most 1000 objects in it.
@@ -6867,6 +6984,114 @@ public List<BatchResponse> deleteObjects(
68676984
return chunkedBatch(indexName, objects, Action.DELETE_OBJECT, waitForTasks, batchSize, requestOptions);
68686985
}
68696986

6987+
/**
6988+
* Helper: Similar to the `partialUpdateObjects` method but requires a Push connector
6989+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
6990+
* to be created first, in order to transform records before indexing them to Algolia. The
6991+
* `region` must have been passed to the client instantiation method.
6992+
*
6993+
* @param indexName The `indexName` to update `objects` in.
6994+
* @param objects The array of `objects` to update in the given Algolia `indexName`.
6995+
* @param createIfNotExists To be provided if non-existing objects are passed, otherwise, the call
6996+
* will fail.
6997+
*/
6998+
public <T> WatchResponse partialUpdateObjectsWithTransformation(String indexName, Iterable<T> objects, boolean createIfNotExists) {
6999+
return partialUpdateObjectsWithTransformation(indexName, objects, createIfNotExists, false, null);
7000+
}
7001+
7002+
/**
7003+
* Helper: Similar to the `partialUpdateObjects` method but requires a Push connector
7004+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
7005+
* to be created first, in order to transform records before indexing them to Algolia. The
7006+
* `region` must have been passed to the client instantiation method.
7007+
*
7008+
* @param indexName The `indexName` to update `objects` in.
7009+
* @param objects The array of `objects` to update in the given Algolia `indexName`.
7010+
* @param createIfNotExists To be provided if non-existing objects are passed, otherwise, the call
7011+
* will fail.
7012+
* @param waitForTasks - Whether or not we should wait until every `batch` tasks has been
7013+
* processed, this operation may slow the total execution time of this method but is more
7014+
* reliable.
7015+
*/
7016+
public <T> WatchResponse partialUpdateObjectsWithTransformation(
7017+
String indexName,
7018+
Iterable<T> objects,
7019+
boolean createIfNotExists,
7020+
boolean waitForTasks
7021+
) {
7022+
return partialUpdateObjectsWithTransformation(indexName, objects, createIfNotExists, waitForTasks, null);
7023+
}
7024+
7025+
/**
7026+
* Helper: Similar to the `partialUpdateObjects` method but requires a Push connector
7027+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
7028+
* to be created first, in order to transform records before indexing them to Algolia. The
7029+
* `region` must have been passed to the client instantiation method.
7030+
*
7031+
* @param indexName The `indexName` to update `objects` in.
7032+
* @param objects The array of `objects` to update in the given Algolia `indexName`.
7033+
* @param createIfNotExists To be provided if non-existing objects are passed, otherwise, the call
7034+
* will fail.
7035+
* @param waitForTasks - Whether or not we should wait until every `batch` tasks has been
7036+
* processed, this operation may slow the total execution time of this method but is more
7037+
* reliable.
7038+
* @param requestOptions The requestOptions to send along with the query, they will be merged with
7039+
* the transporter requestOptions. (optional)
7040+
*/
7041+
public <T> WatchResponse partialUpdateObjectsWithTransformation(
7042+
String indexName,
7043+
Iterable<T> objects,
7044+
boolean createIfNotExists,
7045+
boolean waitForTasks,
7046+
RequestOptions requestOptions
7047+
) {
7048+
return partialUpdateObjectsWithTransformation(indexName, objects, createIfNotExists, waitForTasks, 1000, null);
7049+
}
7050+
7051+
/**
7052+
* Helper: Similar to the `partialUpdateObjects` method but requires a Push connector
7053+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
7054+
* to be created first, in order to transform records before indexing them to Algolia. The
7055+
* `region` must have been passed to the client instantiation method.
7056+
*
7057+
* @param indexName The `indexName` to update `objects` in.
7058+
* @param objects The array of `objects` to update in the given Algolia `indexName`.
7059+
* @param createIfNotExists To be provided if non-existing objects are passed, otherwise, the call
7060+
* will fail.
7061+
* @param waitForTasks - Whether or not we should wait until every `batch` tasks has been
7062+
* processed, this operation may slow the total execution time of this method but is more
7063+
* reliable.
7064+
* @param batchSize The size of the chunk of `objects`. The number of `batch` calls will be equal
7065+
* to `length(objects) / batchSize`.
7066+
* @param requestOptions The requestOptions to send along with the query, they will be merged with
7067+
* the transporter requestOptions. (optional)
7068+
*/
7069+
public <T> WatchResponse partialUpdateObjectsWithTransformation(
7070+
String indexName,
7071+
Iterable<T> objects,
7072+
boolean createIfNotExists,
7073+
boolean waitForTasks,
7074+
int batchSize,
7075+
RequestOptions requestOptions
7076+
) {
7077+
if (this.ingestionTransporter == null) {
7078+
throw new AlgoliaRuntimeException("`setTransformationRegion` must have been called before calling this method.");
7079+
}
7080+
7081+
return this.ingestionTransporter.push(
7082+
indexName,
7083+
new PushTaskPayload()
7084+
.setAction(
7085+
createIfNotExists
7086+
? com.algolia.model.ingestion.Action.PARTIAL_UPDATE_OBJECT
7087+
: com.algolia.model.ingestion.Action.PARTIAL_UPDATE_OBJECT_NO_CREATE
7088+
)
7089+
.setRecords(this.objectsToPushTaskRecords(objects)),
7090+
waitForTasks,
7091+
requestOptions
7092+
);
7093+
}
7094+
68707095
/**
68717096
* Helper: Replaces object content of all the given objects according to their respective
68727097
* `objectID` field. The `chunkedBatch` helper is used under the hood, which creates a `batch`

algoliasearch/src/main/java/com/algolia/internal/interceptors/AuthInterceptor.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ public void setApiKey(String apiKey) {
2323
this.apiKey = apiKey;
2424
}
2525

26+
public String getApiKey() {
27+
return this.apiKey;
28+
}
29+
30+
public String getApplicationId() {
31+
return this.applicationId;
32+
}
33+
2634
@Nonnull
2735
@Override
2836
public Response intercept(Chain chain) throws IOException {

0 commit comments

Comments
 (0)