Skip to content

Commit dfc654c

Browse files
committed
feat(java): add bridge to transformation on search
1 parent 63b7dad commit dfc654c

File tree

5 files changed

+233
-2
lines changed

5 files changed

+233
-2
lines changed

clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/ApiClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public abstract class ApiClient implements Closeable {
2828

2929
private final Requester requester;
3030
private final ExecutorService executor;
31-
private AuthInterceptor authInterceptor;
31+
public AuthInterceptor authInterceptor;
3232

3333
/** Constructs a new instance of the {@link ApiClient}. */
3434
protected ApiClient(

clients/algoliasearch-client-java/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 {

specs/search/helpers/saveObjectsWithTransformation.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ method:
55
- javascript
66
- go
77
- python
8+
- java
89
tags:
910
- Records
1011
operationId: saveObjectsWithTransformation

templates/java/api.mustache

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,21 @@ import java.util.Base64;
4545
import javax.annotation.Nonnull;
4646
import javax.crypto.Mac;
4747
import javax.crypto.spec.SecretKeySpec;
48+
import com.algolia.model.ingestion.PushTaskPayload;
49+
import com.algolia.model.ingestion.PushTaskRecords;
50+
import com.algolia.model.ingestion.WatchResponse;
4851
{{/isSearchClient}}
4952

5053
{{#operations}}
5154
public class {{classname}} extends ApiClient {
55+
{{#isSearchClient}}
56+
private IngestionClient ingestionTransporter;
57+
58+
public void setTransformationRegion(String region) {
59+
this.ingestionTransporter = new IngestionClient(this.authInterceptor.getApplicationId(), this.authInterceptor.getApiKey(), region);
60+
}
61+
{{/isSearchClient}}
62+
5263
{{#hasRegionalHost}}
5364
private static final String[] allowedRegions = { {{#allowedRegions}}"{{.}}"{{^-last}},{{/-last}}{{/allowedRegions}} };
5465

@@ -243,4 +254,4 @@ public class {{classname}} extends ApiClient {
243254

244255
{{> api_helpers}}
245256
}
246-
{{/operations}}
257+
{{/operations}}

templates/java/api_helpers.mustache

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,109 @@ public <T> List<BatchResponse> chunkedBatch(
653653
return chunkedBatch(indexName, objects, action, waitForTasks, 1000, requestOptions);
654654
}
655655
656+
/**
657+
* Helper: Similar to the `saveObjects` method but requires a Push connector
658+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
659+
* to be created first, in order to transform records before indexing them to Algolia. The
660+
* `region` must have been passed to the client instantiation method.
661+
*
662+
* @param indexName The `indexName` to replace `objects` in.
663+
* @param objects The array of `objects` to store in the given Algolia `indexName`.
664+
* @throws AlgoliaRetryException When the retry has failed on all hosts
665+
* @throws AlgoliaApiException When the API sends an http error code
666+
* @throws AlgoliaRuntimeException When an error occurred during the serialization
667+
*/
668+
public <T> WatchResponse saveObjectsWithTransformation(String indexName, Iterable<T> objects) {
669+
return saveObjectsWithTransformation(indexName, objects, null);
670+
}
671+
672+
/**
673+
* Helper: Similar to the `saveObjects` method but requires a Push connector
674+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
675+
* to be created first, in order to transform records before indexing them to Algolia. The
676+
* `region` must have been passed to the client instantiation method.
677+
*
678+
* @param indexName The `indexName` to replace `objects` in.
679+
* @param objects The array of `objects` to store in the given Algolia `indexName`.
680+
* @param requestOptions The requestOptions to send along with the query, they will be merged with
681+
* the transporter requestOptions. (optional)
682+
*/
683+
public <T> WatchResponse saveObjectsWithTransformation(String indexName, Iterable<T> objects, RequestOptions requestOptions) {
684+
return saveObjectsWithTransformation(indexName, objects, false, requestOptions);
685+
}
686+
687+
/**
688+
* Helper: Similar to the `saveObjects` method but requires a Push connector
689+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
690+
* to be created first, in order to transform records before indexing them to Algolia. The
691+
* `region` must have been passed to the client instantiation method.
692+
*
693+
* @param indexName The `indexName` to replace `objects` in.
694+
* @param objects The array of `objects` to store in the given Algolia `indexName`.
695+
* @param waitForTasks - Whether or not we should wait until every `batch` tasks has been
696+
* processed, this operation may slow the total execution time of this method but is more
697+
* reliable.
698+
* @param requestOptions The requestOptions to send along with the query, they will be merged with
699+
* the transporter requestOptions. (optional)
700+
*/
701+
public <T> WatchResponse saveObjectsWithTransformation(
702+
String indexName,
703+
Iterable<T> objects,
704+
boolean waitForTasks,
705+
RequestOptions requestOptions
706+
) {
707+
return saveObjectsWithTransformation(indexName, objects, waitForTasks, 1000, requestOptions);
708+
}
709+
710+
/**
711+
* Helper: Similar to the `saveObjects` method but requires a Push connector
712+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
713+
* to be created first, in order to transform records before indexing them to Algolia. The
714+
* `region` must have been passed to the client instantiation method.
715+
*
716+
* @param indexName The `indexName` to replace `objects` in.
717+
* @param objects The array of `objects` to store in the given Algolia `indexName`.
718+
* @param waitForTasks - Whether or not we should wait until every `batch` tasks has been
719+
* processed, this operation may slow the total execution time of this method but is more
720+
* reliable.
721+
* @param batchSize The size of the chunk of `objects`. The number of `batch` calls will be equal
722+
* to `length(objects) / batchSize`.
723+
* @param requestOptions The requestOptions to send along with the query, they will be merged with
724+
* the transporter requestOptions. (optional)
725+
*/
726+
public <T> WatchResponse saveObjectsWithTransformation(
727+
String indexName,
728+
Iterable<T> objects,
729+
boolean waitForTasks,
730+
int batchSize,
731+
RequestOptions requestOptions
732+
) {
733+
if (this.ingestionTransporter == null) {
734+
throw new AlgoliaRuntimeException("`setTransformationRegion` must have been called before calling this method.");
735+
}
736+
737+
return this.ingestionTransporter.push(
738+
indexName,
739+
new PushTaskPayload().setAction(com.algolia.model.ingestion.Action.ADD_OBJECT).setRecords(this.objectsToPushTaskRecords(objects)),
740+
waitForTasks,
741+
requestOptions
742+
);
743+
}
744+
745+
private <T> List<PushTaskRecords> objectsToPushTaskRecords(Iterable<T> iterable) {
746+
List<PushTaskRecords> payload = new ArrayList<>();
747+
for (T item : iterable) {
748+
if (item instanceof PushTaskRecords) {
749+
payload.add((PushTaskRecords) item);
750+
} else {
751+
throw new AlgoliaRuntimeException(
752+
"each object must have an `objectID` key in order to be used with the" + " WithTransformation methods"
753+
);
754+
}
755+
}
756+
return payload;
757+
}
758+
656759
/**
657760
* Helper: Saves the given array of objects in the given index. The `chunkedBatch` helper is used
658761
* under the hood, which creates a `batch` requests with at most 1000 objects in it.
@@ -777,6 +880,114 @@ public List<BatchResponse> deleteObjects(String indexName, List<String> objectID
777880
return chunkedBatch(indexName, objects, Action.DELETE_OBJECT, waitForTasks, batchSize, requestOptions);
778881
}
779882
883+
/**
884+
* Helper: Similar to the `partialUpdateObjects` method but requires a Push connector
885+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
886+
* to be created first, in order to transform records before indexing them to Algolia. The
887+
* `region` must have been passed to the client instantiation method.
888+
*
889+
* @param indexName The `indexName` to update `objects` in.
890+
* @param objects The array of `objects` to update in the given Algolia `indexName`.
891+
* @param createIfNotExists To be provided if non-existing objects are passed, otherwise, the call
892+
* will fail.
893+
*/
894+
public <T> WatchResponse partialUpdateObjectsWithTransformation(String indexName, Iterable<T> objects, boolean createIfNotExists) {
895+
return partialUpdateObjectsWithTransformation(indexName, objects, createIfNotExists, false, null);
896+
}
897+
898+
/**
899+
* Helper: Similar to the `partialUpdateObjects` method but requires a Push connector
900+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
901+
* to be created first, in order to transform records before indexing them to Algolia. The
902+
* `region` must have been passed to the client instantiation method.
903+
*
904+
* @param indexName The `indexName` to update `objects` in.
905+
* @param objects The array of `objects` to update in the given Algolia `indexName`.
906+
* @param createIfNotExists To be provided if non-existing objects are passed, otherwise, the call
907+
* will fail.
908+
* @param waitForTasks - Whether or not we should wait until every `batch` tasks has been
909+
* processed, this operation may slow the total execution time of this method but is more
910+
* reliable.
911+
*/
912+
public <T> WatchResponse partialUpdateObjectsWithTransformation(
913+
String indexName,
914+
Iterable<T> objects,
915+
boolean createIfNotExists,
916+
boolean waitForTasks
917+
) {
918+
return partialUpdateObjectsWithTransformation(indexName, objects, createIfNotExists, waitForTasks, null);
919+
}
920+
921+
/**
922+
* Helper: Similar to the `partialUpdateObjects` method but requires a Push connector
923+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
924+
* to be created first, in order to transform records before indexing them to Algolia. The
925+
* `region` must have been passed to the client instantiation method.
926+
*
927+
* @param indexName The `indexName` to update `objects` in.
928+
* @param objects The array of `objects` to update in the given Algolia `indexName`.
929+
* @param createIfNotExists To be provided if non-existing objects are passed, otherwise, the call
930+
* will fail.
931+
* @param waitForTasks - Whether or not we should wait until every `batch` tasks has been
932+
* processed, this operation may slow the total execution time of this method but is more
933+
* reliable.
934+
* @param requestOptions The requestOptions to send along with the query, they will be merged with
935+
* the transporter requestOptions. (optional)
936+
*/
937+
public <T> WatchResponse partialUpdateObjectsWithTransformation(
938+
String indexName,
939+
Iterable<T> objects,
940+
boolean createIfNotExists,
941+
boolean waitForTasks,
942+
RequestOptions requestOptions
943+
) {
944+
return partialUpdateObjectsWithTransformation(indexName, objects, createIfNotExists, waitForTasks, 1000, null);
945+
}
946+
947+
/**
948+
* Helper: Similar to the `partialUpdateObjects` method but requires a Push connector
949+
* (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/)
950+
* to be created first, in order to transform records before indexing them to Algolia. The
951+
* `region` must have been passed to the client instantiation method.
952+
*
953+
* @param indexName The `indexName` to update `objects` in.
954+
* @param objects The array of `objects` to update in the given Algolia `indexName`.
955+
* @param createIfNotExists To be provided if non-existing objects are passed, otherwise, the call
956+
* will fail.
957+
* @param waitForTasks - Whether or not we should wait until every `batch` tasks has been
958+
* processed, this operation may slow the total execution time of this method but is more
959+
* reliable.
960+
* @param batchSize The size of the chunk of `objects`. The number of `batch` calls will be equal
961+
* to `length(objects) / batchSize`.
962+
* @param requestOptions The requestOptions to send along with the query, they will be merged with
963+
* the transporter requestOptions. (optional)
964+
*/
965+
public <T> WatchResponse partialUpdateObjectsWithTransformation(
966+
String indexName,
967+
Iterable<T> objects,
968+
boolean createIfNotExists,
969+
boolean waitForTasks,
970+
int batchSize,
971+
RequestOptions requestOptions
972+
) {
973+
if (this.ingestionTransporter == null) {
974+
throw new AlgoliaRuntimeException("`setTransformationRegion` must have been called before calling this method.");
975+
}
976+
977+
return this.ingestionTransporter.push(
978+
indexName,
979+
new PushTaskPayload()
980+
.setAction(
981+
createIfNotExists
982+
? com.algolia.model.ingestion.Action.PARTIAL_UPDATE_OBJECT
983+
: com.algolia.model.ingestion.Action.PARTIAL_UPDATE_OBJECT_NO_CREATE
984+
)
985+
.setRecords(this.objectsToPushTaskRecords(objects)),
986+
waitForTasks,
987+
requestOptions
988+
);
989+
}
990+
780991
/**
781992
* Helper: Replaces object content of all the given objects according to their respective
782993
* `objectID` field. The `chunkedBatch` helper is used under the hood, which creates a `batch`

0 commit comments

Comments
 (0)