Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/main/java/com/coveo/pushapiclient/BatchUpdate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.coveo.pushapiclient;

import com.google.gson.JsonObject;

import java.util.List;

public record BatchUpdate(List<DocumentBuilder> addOrUpdate, List<DocumentBuilder> delete) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL about Records. (https://www.baeldung.com/java-record-keyword). It's quite a neat feature.

Do you think there's place in the code where we should have used it? (ngl, I don't think that'd be worth the hassle but just knowing is good :) )

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes !

The only problem is that it does not entirely play well with the GSON library we use to encode/decode to JSON.

So I can't apply it everywhere blindly.

Encoding record with GSON should (or seems to) work, decoding records would explode, however.

For example. the FileContainer class in this PR could not use record because we need to decode the platform response with it.

But, as I'll be moving to write some tests this week, I'll refactor in some places to use record instead of standard classes.

public BatchUpdateRecord marshal() {
return new BatchUpdateRecord(
this.addOrUpdate.stream().map(documentBuilder -> documentBuilder.marshalJsonObject()).toArray(JsonObject[]::new),
this.delete.stream().map(documentBuilder -> documentBuilder.marshalJsonObject()).toArray(JsonObject[]::new)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.coveo.pushapiclient;

import com.google.gson.JsonObject;

public record BatchUpdateRecord(JsonObject[] addOrUpdate, JsonObject[] delete) {
}
8 changes: 6 additions & 2 deletions src/main/java/com/coveo/pushapiclient/DocumentBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,17 @@ public DocumentBuilder withAllowAnonymousUsers(Boolean allowAnonymous) {
}

public String marshal() {
return this.marshalJsonObject().toString();
}

public JsonObject marshalJsonObject() {
JsonObject jsonDocument = new Gson().toJsonTree(this.document).getAsJsonObject();
this.document.metadata.forEach((key, value) -> {
jsonDocument.add(key, new Gson().toJsonTree(value));
});
jsonDocument.remove("metadata");
return jsonDocument.toString();

jsonDocument.addProperty("documentId", this.document.uri);
return jsonDocument;
}

private String dateFormat(DateTime dt) {
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/com/coveo/pushapiclient/FileContainer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.coveo.pushapiclient;

import java.util.Map;

public class FileContainer {
public String uploadUri;
public String fileId;
public Map<String, String> requiredHeaders;
}
43 changes: 37 additions & 6 deletions src/main/java/com/coveo/pushapiclient/PlatformClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,47 @@ public void deleteDocument(String sourceId, String documentId, Boolean deleteChi
// TODO
}

public void createFileContainer() {
// TODO
public HttpResponse<String> createFileContainer() throws IOException, InterruptedException {
String[] headers = this.getHeaders(this.getAuthorizationHeader(), this.getContentTypeApplicationJSONHeader());
URI uri = URI.create(this.getBasePushURL() + "/files");

HttpRequest request = HttpRequest.newBuilder()
.headers(headers)
.uri(uri)
.POST(HttpRequest.BodyPublishers.ofString(""))
.build();

return this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
}

public void uploadContentToFileContainer(String sourceId, Object fileContainer) {
// TODO
public HttpResponse<String> uploadContentToFileContainer(String sourceId, FileContainer fileContainer, BatchUpdateRecord batchUpdate) throws IOException, InterruptedException {
String[] headers = fileContainer.requiredHeaders.entrySet()
.stream()
.flatMap(entry -> Stream.of(entry.getKey(), entry.getValue()))
.toArray(String[]::new);
URI uri = URI.create(fileContainer.uploadUri);


HttpRequest request = HttpRequest.newBuilder()
.headers(headers)
.uri(uri)
.PUT(HttpRequest.BodyPublishers.ofString(new Gson().toJson(batchUpdate)))
.build();

return this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
}

public void pushFileContainerContent(String sourceId, Object fileContainer) {
// TODO
public HttpResponse<String> pushFileContainerContent(String sourceId, FileContainer fileContainer) throws IOException, InterruptedException {
String[] headers = this.getHeaders(this.getAuthorizationHeader(), this.getContentTypeApplicationJSONHeader());
URI uri = URI.create(this.getBasePushURL() + String.format("/sources/%s/documents/batch?fileId=%s", sourceId, fileContainer.fileId));

HttpRequest request = HttpRequest.newBuilder()
.headers(headers)
.uri(uri)
.PUT(HttpRequest.BodyPublishers.ofString(""))
.build();

return this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
}

private String getBaseSourceURL() {
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/com/coveo/pushapiclient/Source.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.coveo.pushapiclient;

import com.google.gson.Gson;

import java.io.IOException;
import java.net.http.HttpResponse;

Expand Down Expand Up @@ -37,4 +39,11 @@ public HttpResponse<String> manageSecurityIdentities(String securityProviderId,
public HttpResponse<String> addOrUpdateDocument(String sourceId, DocumentBuilder docBuilder) throws IOException, InterruptedException {
return this.platformClient.pushDocument(sourceId, docBuilder.marshal(), docBuilder.getDocument().uri);
}

public HttpResponse<String> batchUpdateDocuments(String sourceId, BatchUpdate batchUpdate) throws IOException, InterruptedException {
HttpResponse<String> resFileContainer = this.platformClient.createFileContainer();
FileContainer fileContainer = new Gson().fromJson(resFileContainer.body(), FileContainer.class);
this.platformClient.uploadContentToFileContainer(sourceId, fileContainer, batchUpdate.marshal());
return this.platformClient.pushFileContainerContent(sourceId, fileContainer);
}
}
14 changes: 13 additions & 1 deletion src/main/java/com/coveo/testlocally/TestingLocally.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.io.IOException;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

Expand Down Expand Up @@ -35,19 +36,30 @@ public static void testPushDocument(String sourceId, Source source) {
put("my_field_3", 1234);
put("my_field_4", new String[]{"a", "b", "c"});
}});
DocumentBuilder docWithSecurity = new DocumentBuilder("https://perdu.com/2", "the title 2")
DocumentBuilder docWithSecurity = new DocumentBuilder("https://perdu.com/2", "the title 2")
.withData("this is searchable also")
.withAllowAnonymousUsers(false)
.withAllowedPermissions(new UserSecurityIdentityBuilder("[email protected]"))
.withDeniedPermissions(new UserSecurityIdentityBuilder(new String[]{"[email protected]", "[email protected]"}));

ArrayList<DocumentBuilder> docToAdd = new ArrayList<>();
ArrayList<DocumentBuilder> docToRemove = new ArrayList<>();
for (int i = 0; i < 10; i++) {
docToAdd.add(new DocumentBuilder(String.format("https://perdu.com/%s", i), String.format("the title %s", i)).withData(String.format("this is searchable %s", i)));
}
for (int i = 10; i < 20; i++) {
docToRemove.add(new DocumentBuilder(String.format("https://perdu.com/%s", i), String.format("the title %s", i)).withData(String.format("this is searchable %s", i)));
}

try {
source.addOrUpdateDocument(sourceId, simpleDoc);
source.addOrUpdateDocument(sourceId, docWithMetadata);
source.batchUpdateDocuments(sourceId, new BatchUpdate(docToAdd, docToRemove));
source.addOrUpdateDocument(sourceId, docWithSecurity);
} catch (IOException | InterruptedException e) {
System.out.println(e);
}

}

public static void testManageIdentities(Source source) {
Expand Down