From 31b442c3b20e7d4eb78894ec8929ee281899cae9 Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Thu, 7 Nov 2024 16:02:08 +0100 Subject: [PATCH 1/8] chore: add export ID endpoint --- src/main/java/io/getstream/client/Client.java | 5 ++ .../io/getstream/client/ExportIDsClient.java | 26 +++++++ .../java/io/getstream/core/ExportIDs.java | 53 +++++++++++++++ src/main/java/io/getstream/core/Stream.java | 4 ++ .../core/models/ExportIDsResponse.java | 35 ++++++++++ .../core/models/ExportIDsResult.java | 62 +++++++++++++++++ .../java/io/getstream/core/utils/Auth.java | 7 +- .../java/io/getstream/core/utils/Routes.java | 5 ++ .../io/getstream/client/ExportIDsTest.java | 67 +++++++++++++++++++ 9 files changed, 263 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/getstream/client/ExportIDsClient.java create mode 100644 src/main/java/io/getstream/core/ExportIDs.java create mode 100644 src/main/java/io/getstream/core/models/ExportIDsResponse.java create mode 100644 src/main/java/io/getstream/core/models/ExportIDsResult.java create mode 100644 src/test/java/io/getstream/client/ExportIDsTest.java diff --git a/src/main/java/io/getstream/client/Client.java b/src/main/java/io/getstream/client/Client.java index aef62d5a..7a948dd8 100644 --- a/src/main/java/io/getstream/client/Client.java +++ b/src/main/java/io/getstream/client/Client.java @@ -5,6 +5,7 @@ import static io.getstream.core.utils.Auth.*; import com.google.common.collect.Iterables; +import io.getstream.core.ExportIDs; import io.getstream.core.Region; import io.getstream.core.Stream; import io.getstream.core.exceptions.StreamException; @@ -254,6 +255,10 @@ public ModerationClient moderation() { return new ModerationClient(secret, stream.moderation()); } + public ExportIDsClient exportIDs() { + return new ExportIDsClient(secret, stream.exportIDs()); + } + public FileStorageClient files() { return new FileStorageClient(secret, stream.files()); } diff --git a/src/main/java/io/getstream/client/ExportIDsClient.java b/src/main/java/io/getstream/client/ExportIDsClient.java new file mode 100644 index 00000000..6a16de46 --- /dev/null +++ b/src/main/java/io/getstream/client/ExportIDsClient.java @@ -0,0 +1,26 @@ +package io.getstream.client; + +import static io.getstream.core.utils.Auth.buildDataPrivacy; +import static io.getstream.core.utils.Serialization.deserialize; + +import io.getstream.core.ExportIDs; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.models.ExportIDsResponse; +import io.getstream.core.utils.Auth; +import java8.util.concurrent.CompletableFuture; + +public class ExportIDsClient { + private final String secret; + private final ExportIDs exportIDs; + + ExportIDsClient(String secret, ExportIDs exportIDs) { + this.secret = secret; + this.exportIDs = exportIDs; + } + + public CompletableFuture exportUserActivities(String userId) throws StreamException { + final Token token = buildDataPrivacy(secret, Auth.TokenAction.READ); + return exportIDs.exportUserActivities(token, userId); + } +} \ No newline at end of file diff --git a/src/main/java/io/getstream/core/ExportIDs.java b/src/main/java/io/getstream/core/ExportIDs.java new file mode 100644 index 00000000..69439b87 --- /dev/null +++ b/src/main/java/io/getstream/core/ExportIDs.java @@ -0,0 +1,53 @@ +package io.getstream.core; + +import static io.getstream.core.utils.Request.buildGet; +import static io.getstream.core.utils.Serialization.deserialize; + +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.HTTPClient; +import io.getstream.core.http.Token; +import io.getstream.core.models.ExportIDsResponse; +import static io.getstream.core.utils.Routes.*; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java8.util.concurrent.CompletableFuture; +import java8.util.concurrent.CompletionException; + +public class ExportIDs { + private final String key; + private final URL baseURL; + private final HTTPClient httpClient; + + public ExportIDs(String key, URL baseURL, HTTPClient httpClient) { + this.key = key; + this.baseURL = baseURL; + this.httpClient = httpClient; + } + + public CompletableFuture exportUserActivities(Token token, String userId) throws StreamException { + if (userId == null || userId.isEmpty()) { + throw new IllegalArgumentException("User ID can't be null or empty"); + } + + try { +// final URL url = buildExportIDsURL(baseURL, userId); + final URL url = buildExportIDsURL(new URL("https://oregon-api.stream-io-api.com"), userId);//$$ need to deploy proxy + io.getstream.core.http.Request request = buildGet(url, key, token); + return httpClient + .execute(request) + .thenApply( + response -> { + try { + return deserialize(response, ExportIDsResponse.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } +} \ No newline at end of file diff --git a/src/main/java/io/getstream/core/Stream.java b/src/main/java/io/getstream/core/Stream.java index 0eb9d413..38505802 100644 --- a/src/main/java/io/getstream/core/Stream.java +++ b/src/main/java/io/getstream/core/Stream.java @@ -63,6 +63,10 @@ public Moderation moderation() { return new Moderation(key, baseURL, httpClient); } + public ExportIDs exportIDs() { + return new ExportIDs(key, baseURL, httpClient); + } + public StreamFiles files() { return new StreamFiles(key, baseURL, httpClient); } diff --git a/src/main/java/io/getstream/core/models/ExportIDsResponse.java b/src/main/java/io/getstream/core/models/ExportIDsResponse.java new file mode 100644 index 00000000..190f6ddb --- /dev/null +++ b/src/main/java/io/getstream/core/models/ExportIDsResponse.java @@ -0,0 +1,35 @@ +package io.getstream.core.models; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ExportIDsResponse { + @JsonProperty("export") + private ExportIDsResult export; + + @JsonProperty("duration") + private String duration; + + // No-argument constructor + public ExportIDsResponse() { + } + + // Constructor with parameters + public ExportIDsResponse(String duration) { + this.duration = duration; + } + + public ExportIDsResult getExport() { + return export; + } + + public void setExport(ExportIDsResult export) { + this.export = export; + } + + public String getDuration() { + return duration; + } + + public void setDuration(String duration) { + this.duration = duration; + } +} \ No newline at end of file diff --git a/src/main/java/io/getstream/core/models/ExportIDsResult.java b/src/main/java/io/getstream/core/models/ExportIDsResult.java new file mode 100644 index 00000000..043c673b --- /dev/null +++ b/src/main/java/io/getstream/core/models/ExportIDsResult.java @@ -0,0 +1,62 @@ +package io.getstream.core.models; + +import java.util.List; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ExportIDsResult { + @JsonProperty("user_id") + private String userId; + + @JsonProperty("activity_count") + private int activityCount; + + @JsonProperty("activity_ids") + private List activityIds; + + @JsonProperty("reaction_count") + private int reactionCount; + + @JsonProperty("reaction_ids") + private List reactionIds; + + // Getters and Setters + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public int getActivityCount() { + return activityCount; + } + + public void setActivityCount(int activityCount) { + this.activityCount = activityCount; + } + + public List getActivityIds() { + return activityIds; + } + + public void setActivityIds(List activityIds) { + this.activityIds = activityIds; + } + + public int getReactionCount() { + return reactionCount; + } + + public void setReactionCount(int reactionCount) { + this.reactionCount = reactionCount; + } + + public List getReactionIds() { + return reactionIds; + } + + public void setReactionIds(List reactionIds) { + this.reactionIds = reactionIds; + } +} \ No newline at end of file diff --git a/src/main/java/io/getstream/core/utils/Auth.java b/src/main/java/io/getstream/core/utils/Auth.java index 3fdcada3..b5c44d64 100644 --- a/src/main/java/io/getstream/core/utils/Auth.java +++ b/src/main/java/io/getstream/core/utils/Auth.java @@ -42,7 +42,8 @@ public enum TokenResource { PERSONALIZATION("personalization"), REACTIONS("reactions"), USERS("users"), - MODERATION("moderation"); + MODERATION("moderation"), + DATAPRIVACY("data_privacy"); private final String resource; @@ -103,6 +104,10 @@ public static Token buildModerationToken(String secret, TokenAction action) { return buildBackendToken(secret, TokenResource.MODERATION, action, "*"); } + public static Token buildDataPrivacy(String secret, TokenAction action) { + return buildBackendToken(secret, TokenResource.DATAPRIVACY, action, "*"); + } + public static Token buildAnalyticsToken(String secret, TokenAction action) { return buildBackendToken(secret, TokenResource.ANALYTICS, action, "*"); } diff --git a/src/main/java/io/getstream/core/utils/Routes.java b/src/main/java/io/getstream/core/utils/Routes.java index 0d29cf8a..28b0cf36 100644 --- a/src/main/java/io/getstream/core/utils/Routes.java +++ b/src/main/java/io/getstream/core/utils/Routes.java @@ -19,6 +19,7 @@ public final class Routes { private static final String followManyPath = "follow_many/"; private static final String unfollowManyPath = "unfollow_many/"; private static final String moderationFlagPath = "moderation/flag/"; + private static final String exportIDsPath = "data_privacy/export_ids/"; private static final String collectionsPath = "collections/"; private static final String filesPath = "files/"; private static final String imagesPath = "images/"; @@ -118,6 +119,10 @@ public static URL buildModerationFlagURL(URL baseURL) throws MalformedURLExcepti return new URL(baseURL, basePath + moderationFlagPath); } + public static URL buildExportIDsURL(URL baseURL, String userID) throws MalformedURLException { + return new URL(baseURL, basePath + exportIDsPath+userID); + } + public static URL followStatsPath(URL baseURL) throws MalformedURLException { return new URL(baseURL, basePath + followStatsPath); } diff --git a/src/test/java/io/getstream/client/ExportIDsTest.java b/src/test/java/io/getstream/client/ExportIDsTest.java new file mode 100644 index 00000000..68430f80 --- /dev/null +++ b/src/test/java/io/getstream/client/ExportIDsTest.java @@ -0,0 +1,67 @@ +package io.getstream.client; + +import static org.junit.Assert.*; + +import io.getstream.core.models.Activity; +import io.getstream.core.models.ExportIDsResponse; +import io.getstream.core.models.ExportIDsResult; +import org.junit.*; + +import java.util.Date; + +public class ExportIDsTest { + + private static final String apiKey = + System.getenv("STREAM_KEY") != null + ? System.getenv("STREAM_KEY") + : System.getProperty("STREAM_KEY"); + private static final String secret = + System.getenv("STREAM_SECRET") != null + ? System.getenv("STREAM_SECRET") + : System.getProperty("STREAM_SECRET"); + + Client client; + + @Before + public void setUp() throws Exception { + client = Client.builder(apiKey, secret).build(); + } + + @Test + public void testExportUserActivities() throws Exception { + ExportIDsClient exportIDsClient = client.exportIDs(); + + String userId = "test-user"; + + // Insert some activities + Activity activity1 = Activity.builder() + .actor(userId) + .verb("post") + .object("object1") + .time(new Date()) + .build(); + Activity activity1Res = client.flatFeed("user", userId).addActivity(activity1).join(); + + Activity activity2 = Activity.builder() + .actor(userId) + .verb("like") + .object("object2") + .time(new Date()) + .build(); + Activity activity2Res =client.flatFeed("user", userId).addActivity(activity2).join(); + + // Export user activities + ExportIDsResponse exportResult = exportIDsClient.exportUserActivities(userId).join(); + ExportIDsResult exports = exportResult.getExport(); + + // Test the output + assertNotNull(exportResult); + assertEquals(userId, exports.getUserId()); + assertTrue(exports.getActivityCount() >= 0); + assertNotNull(exports.getActivityIds()); + assertTrue(exports.getActivityIds().contains(activity1Res.getID())); + assertTrue(exports.getActivityIds().contains(activity2Res.getID())); + assertTrue(exports.getReactionCount() >= 0); + assertNotNull(exports.getReactionIds()); + } +} \ No newline at end of file From 46a1a57dd47eb398e6b2e64b58e52ccf559b3f1c Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Thu, 7 Nov 2024 16:57:29 +0100 Subject: [PATCH 2/8] chore: add batch delete activities endpoint --- .../client/BatchDeleteActivitiesClient.java | 27 ++++++ src/main/java/io/getstream/client/Client.java | 4 + .../io/getstream/client/ExportIDsClient.java | 6 +- .../getstream/core/BatchDeleteActivities.java | 41 +++++++++ src/main/java/io/getstream/core/Stream.java | 4 + .../models/BatchDeleteActivitiesRequest.java | 39 +++++++++ .../java/io/getstream/core/utils/Auth.java | 2 +- .../java/io/getstream/core/utils/Routes.java | 8 +- .../client/BatchDeleteActivitiesTest.java | 83 +++++++++++++++++++ 9 files changed, 209 insertions(+), 5 deletions(-) create mode 100644 src/main/java/io/getstream/client/BatchDeleteActivitiesClient.java create mode 100644 src/main/java/io/getstream/core/BatchDeleteActivities.java create mode 100644 src/main/java/io/getstream/core/models/BatchDeleteActivitiesRequest.java create mode 100644 src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java diff --git a/src/main/java/io/getstream/client/BatchDeleteActivitiesClient.java b/src/main/java/io/getstream/client/BatchDeleteActivitiesClient.java new file mode 100644 index 00000000..e5959b27 --- /dev/null +++ b/src/main/java/io/getstream/client/BatchDeleteActivitiesClient.java @@ -0,0 +1,27 @@ +package io.getstream.client; + +import io.getstream.core.BatchDeleteActivities; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.models.BatchDeleteActivitiesRequest; +import io.getstream.core.utils.Auth; +import java8.util.concurrent.CompletableFuture; + +import static io.getstream.core.utils.Auth.buildDataPrivacyToken; +import static io.getstream.core.utils.Auth.buildModerationToken; + +public class BatchDeleteActivitiesClient { + private final String secret; + private final BatchDeleteActivities batchDeleteActivities; + + public BatchDeleteActivitiesClient(String secret, BatchDeleteActivities batchDeleteActivities) { + this.secret = secret; + this.batchDeleteActivities = batchDeleteActivities; + } + + public CompletableFuture deleteActivities(BatchDeleteActivitiesRequest request) throws StreamException { + final Token token =buildDataPrivacyToken(secret, Auth.TokenAction.WRITE); // Assuming Token can be created with a secret + + return batchDeleteActivities.deleteActivities(token, request); + } +} \ No newline at end of file diff --git a/src/main/java/io/getstream/client/Client.java b/src/main/java/io/getstream/client/Client.java index 7a948dd8..e1853b43 100644 --- a/src/main/java/io/getstream/client/Client.java +++ b/src/main/java/io/getstream/client/Client.java @@ -259,6 +259,10 @@ public ExportIDsClient exportIDs() { return new ExportIDsClient(secret, stream.exportIDs()); } + public BatchDeleteActivitiesClient batchDeleteActivities() { + return new BatchDeleteActivitiesClient(secret, stream.batchDeleteActivities()); + } + public FileStorageClient files() { return new FileStorageClient(secret, stream.files()); } diff --git a/src/main/java/io/getstream/client/ExportIDsClient.java b/src/main/java/io/getstream/client/ExportIDsClient.java index 6a16de46..c311ae36 100644 --- a/src/main/java/io/getstream/client/ExportIDsClient.java +++ b/src/main/java/io/getstream/client/ExportIDsClient.java @@ -1,6 +1,6 @@ package io.getstream.client; -import static io.getstream.core.utils.Auth.buildDataPrivacy; +import static io.getstream.core.utils.Auth.buildDataPrivacyToken; import static io.getstream.core.utils.Serialization.deserialize; import io.getstream.core.ExportIDs; @@ -20,7 +20,7 @@ public class ExportIDsClient { } public CompletableFuture exportUserActivities(String userId) throws StreamException { - final Token token = buildDataPrivacy(secret, Auth.TokenAction.READ); + final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.READ); return exportIDs.exportUserActivities(token, userId); } -} \ No newline at end of file +} diff --git a/src/main/java/io/getstream/core/BatchDeleteActivities.java b/src/main/java/io/getstream/core/BatchDeleteActivities.java new file mode 100644 index 00000000..363909d1 --- /dev/null +++ b/src/main/java/io/getstream/core/BatchDeleteActivities.java @@ -0,0 +1,41 @@ +package io.getstream.core; + +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.HTTPClient; +import io.getstream.core.http.Token; +import io.getstream.core.models.BatchDeleteActivitiesRequest; +import java8.util.concurrent.CompletableFuture; +import static io.getstream.core.utils.Routes.*; +import static io.getstream.core.utils.Request.buildPost; +import static io.getstream.core.utils.Serialization.toJSON; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.Map; + +public class BatchDeleteActivities { + private final String key; + private final URL baseURL; + private final HTTPClient httpClient; + + public BatchDeleteActivities(String key, URL baseURL, HTTPClient httpClient) { + this.key = key; + this.baseURL = baseURL; + this.httpClient = httpClient; + } + + public CompletableFuture deleteActivities(Token token, BatchDeleteActivitiesRequest request) throws StreamException { + try { +// final URL url = deleteActivitiesURL(baseURL); + final URL url = deleteActivitiesURL(new URL("https://oregon-api.stream-io-api.com"));//$$ need to deploy proxy + + final byte[] payload = toJSON(request); + io.getstream.core.http.Request httpRequest = buildPost(url, key, token, payload); + return httpClient.execute(httpRequest).thenApply(response -> null); + } catch (Exception e) { + throw new StreamException(e); + } + } +} \ No newline at end of file diff --git a/src/main/java/io/getstream/core/Stream.java b/src/main/java/io/getstream/core/Stream.java index 38505802..334d241d 100644 --- a/src/main/java/io/getstream/core/Stream.java +++ b/src/main/java/io/getstream/core/Stream.java @@ -67,6 +67,10 @@ public ExportIDs exportIDs() { return new ExportIDs(key, baseURL, httpClient); } + public BatchDeleteActivities batchDeleteActivities() { + return new BatchDeleteActivities(key, baseURL, httpClient); + } + public StreamFiles files() { return new StreamFiles(key, baseURL, httpClient); } diff --git a/src/main/java/io/getstream/core/models/BatchDeleteActivitiesRequest.java b/src/main/java/io/getstream/core/models/BatchDeleteActivitiesRequest.java new file mode 100644 index 00000000..b0e41757 --- /dev/null +++ b/src/main/java/io/getstream/core/models/BatchDeleteActivitiesRequest.java @@ -0,0 +1,39 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class BatchDeleteActivitiesRequest { + + private final List activities; + + public BatchDeleteActivitiesRequest(List activities) { + this.activities = activities; + } + + public List getActivities() { + return activities; + } + + public static class ActivityToDelete { + private final String id; + private final List removeFromFeeds; + + public ActivityToDelete( + @JsonProperty("id") String id, + @JsonProperty("remove_from_feeds") List removeFromFeeds) { + this.id = id; + this.removeFromFeeds = removeFromFeeds; + } + + public String getId() { + return id; + } + + public List getRemoveFromFeeds() { + return removeFromFeeds; + } + } +} \ No newline at end of file diff --git a/src/main/java/io/getstream/core/utils/Auth.java b/src/main/java/io/getstream/core/utils/Auth.java index b5c44d64..0c4ece57 100644 --- a/src/main/java/io/getstream/core/utils/Auth.java +++ b/src/main/java/io/getstream/core/utils/Auth.java @@ -104,7 +104,7 @@ public static Token buildModerationToken(String secret, TokenAction action) { return buildBackendToken(secret, TokenResource.MODERATION, action, "*"); } - public static Token buildDataPrivacy(String secret, TokenAction action) { + public static Token buildDataPrivacyToken(String secret, TokenAction action) { return buildBackendToken(secret, TokenResource.DATAPRIVACY, action, "*"); } diff --git a/src/main/java/io/getstream/core/utils/Routes.java b/src/main/java/io/getstream/core/utils/Routes.java index 28b0cf36..9be0f251 100644 --- a/src/main/java/io/getstream/core/utils/Routes.java +++ b/src/main/java/io/getstream/core/utils/Routes.java @@ -19,7 +19,6 @@ public final class Routes { private static final String followManyPath = "follow_many/"; private static final String unfollowManyPath = "unfollow_many/"; private static final String moderationFlagPath = "moderation/flag/"; - private static final String exportIDsPath = "data_privacy/export_ids/"; private static final String collectionsPath = "collections/"; private static final String filesPath = "files/"; private static final String imagesPath = "images/"; @@ -29,6 +28,9 @@ public final class Routes { private static final String usersPath = "user/"; private static final String followStatsPath = "stats/follow/"; + private static final String exportIDsPath = "data_privacy/export_ids/"; + private static final String deleteActivitiesPath = "data_privacy/delete_activities/"; + private Routes() { /* nothing to see here */ } @@ -123,6 +125,10 @@ public static URL buildExportIDsURL(URL baseURL, String userID) throws Malformed return new URL(baseURL, basePath + exportIDsPath+userID); } + public static URL deleteActivitiesURL(URL baseURL) throws MalformedURLException { + return new URL(baseURL, basePath + deleteActivitiesPath); + } + public static URL followStatsPath(URL baseURL) throws MalformedURLException { return new URL(baseURL, basePath + followStatsPath); } diff --git a/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java b/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java new file mode 100644 index 00000000..e2b9b0cf --- /dev/null +++ b/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java @@ -0,0 +1,83 @@ +package io.getstream.client; + +import static org.junit.Assert.*; + +import io.getstream.core.BatchDeleteActivities; +import io.getstream.core.http.HTTPClient; +import io.getstream.core.models.BatchDeleteActivitiesRequest; +import io.getstream.core.models.BatchDeleteActivitiesRequest.ActivityToDelete; +import io.getstream.core.models.Activity; +import java8.util.concurrent.CompletableFuture; +import org.junit.*; + +import java.net.URL; +import java.util.Arrays; +import java.util.List; + +public class BatchDeleteActivitiesTest { + + private static final String apiKey = + System.getenv("STREAM_KEY") != null + ? System.getenv("STREAM_KEY") + : System.getProperty("STREAM_KEY"); + private static final String secret = + System.getenv("STREAM_SECRET") != null + ? System.getenv("STREAM_SECRET") + : System.getProperty("STREAM_SECRET"); + + private Client client; + + @Before + public void setUp() throws Exception { + client = Client.builder(apiKey, secret).build(); + } + + @Test + public void testDeleteActivities() throws Exception { + BatchDeleteActivitiesClient batchDeleteClient = client.batchDeleteActivities(); + + // Insert some activities + Activity activity1 = Activity.builder() + .actor("user1") + .verb("post") + .object("object1") + .build(); + Activity activity1Res = client.flatFeed("user", "user1").addActivity(activity1).join(); + + Activity activity2 = Activity.builder() + .actor("user1") + .verb("like") + .object("object2") + .build(); + Activity activity2Res = client.flatFeed("user", "user1").addActivity(activity2).join(); + + // Create delete request + List activities = Arrays.asList( + new ActivityToDelete(activity1Res.getID(), Arrays.asList("user1")), + new ActivityToDelete(activity2Res.getID(), Arrays.asList("user1")) + ); + BatchClient clientBatch = Client.builder(apiKey, secret).build().batch(); + + // Verify activities are inserted + List activity1Resp = clientBatch.getActivitiesByID(activity1Res.getID()).join(); + assertEquals(1, activity1Resp.size()); + + List activity2Resp = clientBatch.getActivitiesByID(activity2Res.getID()).join(); + assertEquals(1, activity2Resp.size()); + + BatchDeleteActivitiesRequest request = new BatchDeleteActivitiesRequest(activities); + + // Delete activities + CompletableFuture future = batchDeleteClient.deleteActivities(request); + future.join(); + + assertTrue(future.isDone()); + + // Verify activities are deleted + List deletedActivity1 = clientBatch.getActivitiesByID(activity1Res.getID()).join(); + assertEquals(0, deletedActivity1.size()); + + List deletedActivity2 = clientBatch.getActivitiesByID(activity2Res.getID()).join(); + assertEquals(0, deletedActivity2.size()); + } +} \ No newline at end of file From da3c48d36ba0d848a40d79b216ab7afcb6ca09fd Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Thu, 7 Nov 2024 17:00:12 +0100 Subject: [PATCH 3/8] chore: remove comments --- .../java/io/getstream/client/BatchDeleteActivitiesClient.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/io/getstream/client/BatchDeleteActivitiesClient.java b/src/main/java/io/getstream/client/BatchDeleteActivitiesClient.java index e5959b27..5e670df9 100644 --- a/src/main/java/io/getstream/client/BatchDeleteActivitiesClient.java +++ b/src/main/java/io/getstream/client/BatchDeleteActivitiesClient.java @@ -20,8 +20,7 @@ public BatchDeleteActivitiesClient(String secret, BatchDeleteActivities batchDel } public CompletableFuture deleteActivities(BatchDeleteActivitiesRequest request) throws StreamException { - final Token token =buildDataPrivacyToken(secret, Auth.TokenAction.WRITE); // Assuming Token can be created with a secret - + final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.WRITE); return batchDeleteActivities.deleteActivities(token, request); } } \ No newline at end of file From 25a178d46cbe73bce6228119d155883e0bd302d4 Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Thu, 7 Nov 2024 17:58:50 +0100 Subject: [PATCH 4/8] chore: add support for discard_deleted_activities --- .../io/getstream/core/options/Filter.java | 8 +- .../client/BatchDeleteActivitiesTest.java | 77 ++++++++++++++++++- 2 files changed, 80 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/getstream/core/options/Filter.java b/src/main/java/io/getstream/core/options/Filter.java index a0b0c2a0..55c98043 100644 --- a/src/main/java/io/getstream/core/options/Filter.java +++ b/src/main/java/io/getstream/core/options/Filter.java @@ -10,7 +10,8 @@ enum OpType { ID_GREATER_THAN("id_gt"), ID_LESS_THAN_OR_EQUAL("id_lte"), ID_LESS_THAN("id_lt"), - REFRESH("refresh"); + REFRESH("refresh"), + DISCARD_DELETED_ACTIVITIES("discard_deleted_activities"); private String operator; @@ -46,6 +47,11 @@ public Filter idGreaterThanEqual(String id) { return this; } + public Filter discardDeletedActivities() { + ops.add(new OpEntry(OpType.DISCARD_DELETED_ACTIVITIES, "true")); + return this; + } + public Filter idLessThan(String id) { ops.add(new OpEntry(OpType.ID_LESS_THAN, id)); return this; diff --git a/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java b/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java index e2b9b0cf..2a05792f 100644 --- a/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java +++ b/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java @@ -2,17 +2,22 @@ import static org.junit.Assert.*; +import com.google.common.collect.Lists; import io.getstream.core.BatchDeleteActivities; import io.getstream.core.http.HTTPClient; import io.getstream.core.models.BatchDeleteActivitiesRequest; import io.getstream.core.models.BatchDeleteActivitiesRequest.ActivityToDelete; import io.getstream.core.models.Activity; +import io.getstream.core.models.FeedID; +import io.getstream.core.options.Filter; +import io.getstream.core.options.Limit; import java8.util.concurrent.CompletableFuture; import org.junit.*; import java.net.URL; import java.util.Arrays; import java.util.List; +import java.util.UUID; public class BatchDeleteActivitiesTest { @@ -35,6 +40,8 @@ public void setUp() throws Exception { @Test public void testDeleteActivities() throws Exception { BatchDeleteActivitiesClient batchDeleteClient = client.batchDeleteActivities(); + String uuid1 = UUID.randomUUID().toString().replace("-", ""); + FlatFeed feed = client.flatFeed("flat", uuid1); // Insert some activities Activity activity1 = Activity.builder() @@ -42,19 +49,19 @@ public void testDeleteActivities() throws Exception { .verb("post") .object("object1") .build(); - Activity activity1Res = client.flatFeed("user", "user1").addActivity(activity1).join(); + Activity activity1Res = feed.addActivity(activity1).join(); Activity activity2 = Activity.builder() .actor("user1") .verb("like") .object("object2") .build(); - Activity activity2Res = client.flatFeed("user", "user1").addActivity(activity2).join(); + Activity activity2Res = feed.addActivity(activity2).join(); // Create delete request List activities = Arrays.asList( - new ActivityToDelete(activity1Res.getID(), Arrays.asList("user1")), - new ActivityToDelete(activity2Res.getID(), Arrays.asList("user1")) + new ActivityToDelete(activity1Res.getID(), Arrays.asList("user:user1", "user:alice")), + new ActivityToDelete(activity2Res.getID(), Arrays.asList("user:user1")) ); BatchClient clientBatch = Client.builder(apiKey, secret).build().batch(); @@ -80,4 +87,66 @@ public void testDeleteActivities() throws Exception { List deletedActivity2 = clientBatch.getActivitiesByID(activity2Res.getID()).join(); assertEquals(0, deletedActivity2.size()); } + + @Test + public void testDeleteActivitis() throws Exception { + BatchDeleteActivitiesClient batchDeleteClient = client.batchDeleteActivities(); + + // Insert some activities + String uuid1 = UUID.randomUUID().toString().replace("-", ""); + String uuid2 = UUID.randomUUID().toString().replace("-", ""); + + FlatFeed feed = client.flatFeed("flat", uuid1); + FlatFeed feedAlice = client.flatFeed("flat", uuid2); + Activity activity1 = Activity.builder() + .actor("user1") + .verb("post") + .to(Lists.newArrayList(feedAlice.getID())) + .object("object1") + .build(); + Activity activity1Res = feed.addActivity(activity1).join(); + + Activity activity2 = Activity.builder() + .actor("user1") + .verb("like") + .to(Lists.newArrayList(feedAlice.getID())) + .object("object2") + .build(); + Activity activity2Res = feed.addActivity(activity2).join(); + + // Verify activities are inserted + List activities =feed.getActivities( + new Limit(69), new Filter()).join(); + assertEquals(2, activities.size()); + + // Create delete request + List activitiesToDelete = Arrays.asList( + new ActivityToDelete(activity1Res.getID(), Arrays.asList(feed.getID().toString())), + new ActivityToDelete(activity2Res.getID(), Arrays.asList(feedAlice.getID().toString())) + ); + BatchDeleteActivitiesRequest request = new BatchDeleteActivitiesRequest(activitiesToDelete); + CompletableFuture future = batchDeleteClient.deleteActivities(request); + future.join(); + + + // Verify activities are deleted by fetching by ID + BatchClient clientBatch = Client.builder(apiKey, secret).build().batch(); + List deletedActivity1 = clientBatch.getActivitiesByID(activity1Res.getID()).join(); + assertEquals(0, deletedActivity1.size()); + + // read feeds + // without discardDeletedActivities + activities =feed.getActivities( + new Limit(69), new Filter()).join(); + assertEquals(2, activities.size()); + + + activities =feed.getActivities( + new Limit(10), new Filter().discardDeletedActivities()).join(); + assertEquals(0, activities.size()); + + activities =feedAlice.getActivities( + new Limit(10), new Filter().discardDeletedActivities()).join(); + assertEquals(1, activities.size()); + } } \ No newline at end of file From 8fed5ae68bb2ec270ae7bc7ad925ba3b08579756 Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Fri, 8 Nov 2024 17:20:40 +0100 Subject: [PATCH 5/8] chore: remove unnecessary client --- .../client/BatchDeleteActivitiesClient.java | 26 --------- src/main/java/io/getstream/client/Client.java | 21 ++++---- .../io/getstream/client/ExportIDsClient.java | 26 --------- .../getstream/core/BatchDeleteActivities.java | 41 -------------- .../java/io/getstream/core/ExportIDs.java | 53 ------------------- src/main/java/io/getstream/core/Stream.java | 45 +++++++++++++--- .../client/BatchDeleteActivitiesTest.java | 28 ++++++---- .../io/getstream/client/ExportIDsTest.java | 5 +- 8 files changed, 70 insertions(+), 175 deletions(-) delete mode 100644 src/main/java/io/getstream/client/BatchDeleteActivitiesClient.java delete mode 100644 src/main/java/io/getstream/client/ExportIDsClient.java delete mode 100644 src/main/java/io/getstream/core/BatchDeleteActivities.java delete mode 100644 src/main/java/io/getstream/core/ExportIDs.java diff --git a/src/main/java/io/getstream/client/BatchDeleteActivitiesClient.java b/src/main/java/io/getstream/client/BatchDeleteActivitiesClient.java deleted file mode 100644 index 5e670df9..00000000 --- a/src/main/java/io/getstream/client/BatchDeleteActivitiesClient.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.getstream.client; - -import io.getstream.core.BatchDeleteActivities; -import io.getstream.core.exceptions.StreamException; -import io.getstream.core.http.Token; -import io.getstream.core.models.BatchDeleteActivitiesRequest; -import io.getstream.core.utils.Auth; -import java8.util.concurrent.CompletableFuture; - -import static io.getstream.core.utils.Auth.buildDataPrivacyToken; -import static io.getstream.core.utils.Auth.buildModerationToken; - -public class BatchDeleteActivitiesClient { - private final String secret; - private final BatchDeleteActivities batchDeleteActivities; - - public BatchDeleteActivitiesClient(String secret, BatchDeleteActivities batchDeleteActivities) { - this.secret = secret; - this.batchDeleteActivities = batchDeleteActivities; - } - - public CompletableFuture deleteActivities(BatchDeleteActivitiesRequest request) throws StreamException { - final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.WRITE); - return batchDeleteActivities.deleteActivities(token, request); - } -} \ No newline at end of file diff --git a/src/main/java/io/getstream/client/Client.java b/src/main/java/io/getstream/client/Client.java index e1853b43..23f5951f 100644 --- a/src/main/java/io/getstream/client/Client.java +++ b/src/main/java/io/getstream/client/Client.java @@ -5,7 +5,6 @@ import static io.getstream.core.utils.Auth.*; import com.google.common.collect.Iterables; -import io.getstream.core.ExportIDs; import io.getstream.core.Region; import io.getstream.core.Stream; import io.getstream.core.exceptions.StreamException; @@ -20,6 +19,8 @@ import java.util.Date; import java.util.List; import java.util.Map; + +import io.getstream.core.utils.Auth; import java8.util.concurrent.CompletableFuture; public final class Client { @@ -255,14 +256,6 @@ public ModerationClient moderation() { return new ModerationClient(secret, stream.moderation()); } - public ExportIDsClient exportIDs() { - return new ExportIDsClient(secret, stream.exportIDs()); - } - - public BatchDeleteActivitiesClient batchDeleteActivities() { - return new BatchDeleteActivitiesClient(secret, stream.batchDeleteActivities()); - } - public FileStorageClient files() { return new FileStorageClient(secret, stream.files()); } @@ -372,4 +365,14 @@ CompletableFuture userProfile(String id) throws StreamException { final Token token = buildUsersToken(secret, TokenAction.READ); return stream.getUser(token, id, true); } + + public CompletableFuture deleteActivities(BatchDeleteActivitiesRequest request) throws StreamException { + final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.WRITE); + return stream.deleteActivities(token, request); + } + + public CompletableFuture exportUserActivities(String userId) throws StreamException { + final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.READ); + return stream.exportUserActivities(token, userId); + } } diff --git a/src/main/java/io/getstream/client/ExportIDsClient.java b/src/main/java/io/getstream/client/ExportIDsClient.java deleted file mode 100644 index c311ae36..00000000 --- a/src/main/java/io/getstream/client/ExportIDsClient.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.getstream.client; - -import static io.getstream.core.utils.Auth.buildDataPrivacyToken; -import static io.getstream.core.utils.Serialization.deserialize; - -import io.getstream.core.ExportIDs; -import io.getstream.core.exceptions.StreamException; -import io.getstream.core.http.Token; -import io.getstream.core.models.ExportIDsResponse; -import io.getstream.core.utils.Auth; -import java8.util.concurrent.CompletableFuture; - -public class ExportIDsClient { - private final String secret; - private final ExportIDs exportIDs; - - ExportIDsClient(String secret, ExportIDs exportIDs) { - this.secret = secret; - this.exportIDs = exportIDs; - } - - public CompletableFuture exportUserActivities(String userId) throws StreamException { - final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.READ); - return exportIDs.exportUserActivities(token, userId); - } -} diff --git a/src/main/java/io/getstream/core/BatchDeleteActivities.java b/src/main/java/io/getstream/core/BatchDeleteActivities.java deleted file mode 100644 index 363909d1..00000000 --- a/src/main/java/io/getstream/core/BatchDeleteActivities.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.getstream.core; - -import io.getstream.core.exceptions.StreamException; -import io.getstream.core.http.HTTPClient; -import io.getstream.core.http.Token; -import io.getstream.core.models.BatchDeleteActivitiesRequest; -import java8.util.concurrent.CompletableFuture; -import static io.getstream.core.utils.Routes.*; -import static io.getstream.core.utils.Request.buildPost; -import static io.getstream.core.utils.Serialization.toJSON; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.Map; - -public class BatchDeleteActivities { - private final String key; - private final URL baseURL; - private final HTTPClient httpClient; - - public BatchDeleteActivities(String key, URL baseURL, HTTPClient httpClient) { - this.key = key; - this.baseURL = baseURL; - this.httpClient = httpClient; - } - - public CompletableFuture deleteActivities(Token token, BatchDeleteActivitiesRequest request) throws StreamException { - try { -// final URL url = deleteActivitiesURL(baseURL); - final URL url = deleteActivitiesURL(new URL("https://oregon-api.stream-io-api.com"));//$$ need to deploy proxy - - final byte[] payload = toJSON(request); - io.getstream.core.http.Request httpRequest = buildPost(url, key, token, payload); - return httpClient.execute(httpRequest).thenApply(response -> null); - } catch (Exception e) { - throw new StreamException(e); - } - } -} \ No newline at end of file diff --git a/src/main/java/io/getstream/core/ExportIDs.java b/src/main/java/io/getstream/core/ExportIDs.java deleted file mode 100644 index 69439b87..00000000 --- a/src/main/java/io/getstream/core/ExportIDs.java +++ /dev/null @@ -1,53 +0,0 @@ -package io.getstream.core; - -import static io.getstream.core.utils.Request.buildGet; -import static io.getstream.core.utils.Serialization.deserialize; - -import io.getstream.core.exceptions.StreamException; -import io.getstream.core.http.HTTPClient; -import io.getstream.core.http.Token; -import io.getstream.core.models.ExportIDsResponse; -import static io.getstream.core.utils.Routes.*; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URISyntaxException; -import java.net.URL; -import java8.util.concurrent.CompletableFuture; -import java8.util.concurrent.CompletionException; - -public class ExportIDs { - private final String key; - private final URL baseURL; - private final HTTPClient httpClient; - - public ExportIDs(String key, URL baseURL, HTTPClient httpClient) { - this.key = key; - this.baseURL = baseURL; - this.httpClient = httpClient; - } - - public CompletableFuture exportUserActivities(Token token, String userId) throws StreamException { - if (userId == null || userId.isEmpty()) { - throw new IllegalArgumentException("User ID can't be null or empty"); - } - - try { -// final URL url = buildExportIDsURL(baseURL, userId); - final URL url = buildExportIDsURL(new URL("https://oregon-api.stream-io-api.com"), userId);//$$ need to deploy proxy - io.getstream.core.http.Request request = buildGet(url, key, token); - return httpClient - .execute(request) - .thenApply( - response -> { - try { - return deserialize(response, ExportIDsResponse.class); - } catch (StreamException | IOException e) { - throw new CompletionException(e); - } - }); - } catch (MalformedURLException | URISyntaxException e) { - throw new StreamException(e); - } - } -} \ No newline at end of file diff --git a/src/main/java/io/getstream/core/Stream.java b/src/main/java/io/getstream/core/Stream.java index 334d241d..a9779fa7 100644 --- a/src/main/java/io/getstream/core/Stream.java +++ b/src/main/java/io/getstream/core/Stream.java @@ -63,14 +63,6 @@ public Moderation moderation() { return new Moderation(key, baseURL, httpClient); } - public ExportIDs exportIDs() { - return new ExportIDs(key, baseURL, httpClient); - } - - public BatchDeleteActivities batchDeleteActivities() { - return new BatchDeleteActivities(key, baseURL, httpClient); - } - public StreamFiles files() { return new StreamFiles(key, baseURL, httpClient); } @@ -533,4 +525,41 @@ public CompletableFuture updateUser(Token token, String userID, Data u throw new StreamException(e); } } + + public CompletableFuture deleteActivities(Token token, BatchDeleteActivitiesRequest request) throws StreamException { + try { +// final URL url = deleteActivitiesURL(baseURL); + final URL url = deleteActivitiesURL(new URL("https://oregon-api.stream-io-api.com"));//$$ need to deploy proxy + + final byte[] payload = toJSON(request); + io.getstream.core.http.Request httpRequest = buildPost(url, key, token, payload); + return httpClient.execute(httpRequest).thenApply(response -> null); + } catch (Exception e) { + throw new StreamException(e); + } + } + + public CompletableFuture exportUserActivities(Token token, String userId) throws StreamException { + if (userId == null || userId.isEmpty()) { + throw new IllegalArgumentException("User ID can't be null or empty"); + } + + try { +// final URL url = buildExportIDsURL(baseURL, userId); + final URL url = buildExportIDsURL(new URL("https://oregon-api.stream-io-api.com"), userId);//$$ need to deploy proxy + io.getstream.core.http.Request request = buildGet(url, key, token); + return httpClient + .execute(request) + .thenApply( + response -> { + try { + return deserialize(response, ExportIDsResponse.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } } diff --git a/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java b/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java index 2a05792f..efddf4c0 100644 --- a/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java +++ b/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java @@ -3,18 +3,14 @@ import static org.junit.Assert.*; import com.google.common.collect.Lists; -import io.getstream.core.BatchDeleteActivities; -import io.getstream.core.http.HTTPClient; import io.getstream.core.models.BatchDeleteActivitiesRequest; import io.getstream.core.models.BatchDeleteActivitiesRequest.ActivityToDelete; import io.getstream.core.models.Activity; -import io.getstream.core.models.FeedID; import io.getstream.core.options.Filter; import io.getstream.core.options.Limit; import java8.util.concurrent.CompletableFuture; import org.junit.*; -import java.net.URL; import java.util.Arrays; import java.util.List; import java.util.UUID; @@ -39,7 +35,6 @@ public void setUp() throws Exception { @Test public void testDeleteActivities() throws Exception { - BatchDeleteActivitiesClient batchDeleteClient = client.batchDeleteActivities(); String uuid1 = UUID.randomUUID().toString().replace("-", ""); FlatFeed feed = client.flatFeed("flat", uuid1); @@ -75,7 +70,7 @@ public void testDeleteActivities() throws Exception { BatchDeleteActivitiesRequest request = new BatchDeleteActivitiesRequest(activities); // Delete activities - CompletableFuture future = batchDeleteClient.deleteActivities(request); + CompletableFuture future = client.deleteActivities(request); future.join(); assertTrue(future.isDone()); @@ -90,7 +85,6 @@ public void testDeleteActivities() throws Exception { @Test public void testDeleteActivitis() throws Exception { - BatchDeleteActivitiesClient batchDeleteClient = client.batchDeleteActivities(); // Insert some activities String uuid1 = UUID.randomUUID().toString().replace("-", ""); @@ -124,8 +118,18 @@ public void testDeleteActivitis() throws Exception { new ActivityToDelete(activity1Res.getID(), Arrays.asList(feed.getID().toString())), new ActivityToDelete(activity2Res.getID(), Arrays.asList(feedAlice.getID().toString())) ); + + activities =feedAlice.getActivities( + new Limit(10), new Filter()).join(); + assertEquals(2, activities.size());//0 + + activities =feedAlice.getActivities( + new Limit(10), new Filter().discardDeletedActivities()).join(); + assertEquals(2, activities.size());//1 + + BatchDeleteActivitiesRequest request = new BatchDeleteActivitiesRequest(activitiesToDelete); - CompletableFuture future = batchDeleteClient.deleteActivities(request); + CompletableFuture future = client.deleteActivities(request); future.join(); @@ -145,8 +149,14 @@ public void testDeleteActivitis() throws Exception { new Limit(10), new Filter().discardDeletedActivities()).join(); assertEquals(0, activities.size()); + activities =feedAlice.getActivities( + new Limit(10), new Filter()).join(); + assertEquals(2, activities.size());//0 + activities =feedAlice.getActivities( new Limit(10), new Filter().discardDeletedActivities()).join(); - assertEquals(1, activities.size()); + assertEquals(0, activities.size());//1 + + } } \ No newline at end of file diff --git a/src/test/java/io/getstream/client/ExportIDsTest.java b/src/test/java/io/getstream/client/ExportIDsTest.java index 68430f80..a388ef5f 100644 --- a/src/test/java/io/getstream/client/ExportIDsTest.java +++ b/src/test/java/io/getstream/client/ExportIDsTest.java @@ -29,7 +29,6 @@ public void setUp() throws Exception { @Test public void testExportUserActivities() throws Exception { - ExportIDsClient exportIDsClient = client.exportIDs(); String userId = "test-user"; @@ -48,10 +47,10 @@ public void testExportUserActivities() throws Exception { .object("object2") .time(new Date()) .build(); - Activity activity2Res =client.flatFeed("user", userId).addActivity(activity2).join(); + Activity activity2Res = client.flatFeed("user", userId).addActivity(activity2).join(); // Export user activities - ExportIDsResponse exportResult = exportIDsClient.exportUserActivities(userId).join(); + ExportIDsResponse exportResult = client.exportUserActivities(userId).join(); ExportIDsResult exports = exportResult.getExport(); // Test the output From da635eb4974a97b9b472fc613a41de3e2ad56ded Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Mon, 11 Nov 2024 16:25:33 +0100 Subject: [PATCH 6/8] chore: delete batch reactions --- src/main/java/io/getstream/client/Client.java | 5 ++ src/main/java/io/getstream/core/Stream.java | 24 +++++-- .../java/io/getstream/core/utils/Routes.java | 5 ++ .../client/BatchDeleteActivitiesTest.java | 68 +++++++++++++++++++ 4 files changed, 98 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/getstream/client/Client.java b/src/main/java/io/getstream/client/Client.java index 23f5951f..79301137 100644 --- a/src/main/java/io/getstream/client/Client.java +++ b/src/main/java/io/getstream/client/Client.java @@ -371,6 +371,11 @@ public CompletableFuture deleteActivities(BatchDeleteActivitiesRequest r return stream.deleteActivities(token, request); } + public CompletableFuture deleteReactions(BatchDeleteReactionsRequest request) throws StreamException { + final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.WRITE); + return stream.deleteReactions(token, request); + } + public CompletableFuture exportUserActivities(String userId) throws StreamException { final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.READ); return stream.exportUserActivities(token, userId); diff --git a/src/main/java/io/getstream/core/Stream.java b/src/main/java/io/getstream/core/Stream.java index a9779fa7..7df40e42 100644 --- a/src/main/java/io/getstream/core/Stream.java +++ b/src/main/java/io/getstream/core/Stream.java @@ -528,8 +528,8 @@ public CompletableFuture updateUser(Token token, String userID, Data u public CompletableFuture deleteActivities(Token token, BatchDeleteActivitiesRequest request) throws StreamException { try { -// final URL url = deleteActivitiesURL(baseURL); - final URL url = deleteActivitiesURL(new URL("https://oregon-api.stream-io-api.com"));//$$ need to deploy proxy + final URL url = deleteActivitiesURL(baseURL); +// final URL url = deleteActivitiesURL(new URL("https://oregon-api.stream-io-api.com"));//$$ need to deploy proxy final byte[] payload = toJSON(request); io.getstream.core.http.Request httpRequest = buildPost(url, key, token, payload); @@ -539,14 +539,30 @@ public CompletableFuture deleteActivities(Token token, BatchDeleteActivi } } + public CompletableFuture deleteReactions(Token token, BatchDeleteReactionsRequest request) throws StreamException { + try { + final URL url = deleteReactionsURL(baseURL); +// final URL url = deleteReactionsURL(new URL("https://oregon-api.stream-io-api.com"));//$$ need to deploy proxy + + final byte[] payload = toJSON(request); + io.getstream.core.http.Request httpRequest = buildPost(url, key, token, payload); + + //print the response + + return httpClient.execute(httpRequest).thenApply(response -> null); + } catch (Exception e) { + throw new StreamException(e); + } + } + public CompletableFuture exportUserActivities(Token token, String userId) throws StreamException { if (userId == null || userId.isEmpty()) { throw new IllegalArgumentException("User ID can't be null or empty"); } try { -// final URL url = buildExportIDsURL(baseURL, userId); - final URL url = buildExportIDsURL(new URL("https://oregon-api.stream-io-api.com"), userId);//$$ need to deploy proxy + final URL url = buildExportIDsURL(baseURL, userId); +// final URL url = buildExportIDsURL(new URL("https://oregon-api.stream-io-api.com"), userId);//$$ need to deploy proxy io.getstream.core.http.Request request = buildGet(url, key, token); return httpClient .execute(request) diff --git a/src/main/java/io/getstream/core/utils/Routes.java b/src/main/java/io/getstream/core/utils/Routes.java index 9be0f251..14f16b3e 100644 --- a/src/main/java/io/getstream/core/utils/Routes.java +++ b/src/main/java/io/getstream/core/utils/Routes.java @@ -30,6 +30,7 @@ public final class Routes { private static final String exportIDsPath = "data_privacy/export_ids/"; private static final String deleteActivitiesPath = "data_privacy/delete_activities/"; + private static final String deleteReactionsPath = "data_privacy/delete_reactions/"; private Routes() { /* nothing to see here */ @@ -129,6 +130,10 @@ public static URL deleteActivitiesURL(URL baseURL) throws MalformedURLException return new URL(baseURL, basePath + deleteActivitiesPath); } + public static URL deleteReactionsURL(URL baseURL) throws MalformedURLException { + return new URL(baseURL, basePath + deleteReactionsPath); + } + public static URL followStatsPath(URL baseURL) throws MalformedURLException { return new URL(baseURL, basePath + followStatsPath); } diff --git a/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java b/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java index efddf4c0..5d394256 100644 --- a/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java +++ b/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java @@ -3,9 +3,12 @@ import static org.junit.Assert.*; import com.google.common.collect.Lists; +import io.getstream.core.http.Response; import io.getstream.core.models.BatchDeleteActivitiesRequest; import io.getstream.core.models.BatchDeleteActivitiesRequest.ActivityToDelete; import io.getstream.core.models.Activity; +import io.getstream.core.models.BatchDeleteReactionsRequest; +import io.getstream.core.models.Reaction; import io.getstream.core.options.Filter; import io.getstream.core.options.Limit; import java8.util.concurrent.CompletableFuture; @@ -83,6 +86,71 @@ public void testDeleteActivities() throws Exception { assertEquals(0, deletedActivity2.size()); } + @Test + public void testDeleteReactions() throws Exception { + String uuid1 = UUID.randomUUID().toString().replace("-", ""); + FlatFeed feed = client.flatFeed("user", uuid1); + + // Insert some activities + Activity activity1 = Activity.builder() + .actor("user1") + .verb("post") + .object("object1") + .build(); + Activity activity1Res = feed.addActivity(activity1).join(); + + Activity activity2 = Activity.builder() + .actor("user1") + .verb("like") + .object("object2") + .build(); + Activity activity2Res = feed.addActivity(activity2).join(); + + //add reactions for activity1 + Reaction u1=client.reactions().add("user1", "like", activity1Res.getID()).join(); + Reaction u2=client.reactions().add("user2", "like", activity1Res.getID()).join(); + + Reaction u3=client.reactions().add("user1", "like", activity2Res.getID()).join(); + Reaction u4=client.reactions().add("user2", "like", activity2Res.getID()).join(); + + + //fetch test reactions + Reaction r1=client.reactions().get(u1.getId()).join(); + assertNotNull(r1); + + Reaction r2=client.reactions().get(u2.getId()).join(); + assertNotNull(r2); + + Reaction r3=client.reactions().get(u3.getId()).join(); + assertNotNull(r3); + + Reaction r4=client.reactions().get(u4.getId()).join(); + assertNotNull(r4); + + // Create reaction delete request + BatchDeleteReactionsRequest deleteReactionsRequest= + new BatchDeleteReactionsRequest(Arrays.asList + (u1.getId(), u2.getId(), u3.getId())); + + + client.deleteReactions(deleteReactionsRequest).join(); + + //fetch test reactions + + // DoesNotExistException + assertThrows(Exception.class, () -> { + client.reactions().get(u1.getId()).join(); + }); + assertThrows(Exception.class, () -> { + client.reactions().get(u2.getId()).join(); + }); + assertThrows(Exception.class, () -> { + client.reactions().get(u3.getId()).join(); + }); + + + } + @Test public void testDeleteActivitis() throws Exception { From 6dd5463fcf33965c29bd81ebaa28b271826d39fd Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Mon, 11 Nov 2024 17:11:40 +0100 Subject: [PATCH 7/8] chore: remove unused code --- src/main/java/io/getstream/core/Stream.java | 12 +++--------- .../getstream/client/BatchDeleteActivitiesTest.java | 8 +++----- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/main/java/io/getstream/core/Stream.java b/src/main/java/io/getstream/core/Stream.java index 7df40e42..a788533d 100644 --- a/src/main/java/io/getstream/core/Stream.java +++ b/src/main/java/io/getstream/core/Stream.java @@ -528,9 +528,7 @@ public CompletableFuture updateUser(Token token, String userID, Data u public CompletableFuture deleteActivities(Token token, BatchDeleteActivitiesRequest request) throws StreamException { try { - final URL url = deleteActivitiesURL(baseURL); -// final URL url = deleteActivitiesURL(new URL("https://oregon-api.stream-io-api.com"));//$$ need to deploy proxy - + final URL url = deleteActivitiesURL(baseURL); final byte[] payload = toJSON(request); io.getstream.core.http.Request httpRequest = buildPost(url, key, token, payload); return httpClient.execute(httpRequest).thenApply(response -> null); @@ -541,14 +539,11 @@ public CompletableFuture deleteActivities(Token token, BatchDeleteActivi public CompletableFuture deleteReactions(Token token, BatchDeleteReactionsRequest request) throws StreamException { try { - final URL url = deleteReactionsURL(baseURL); -// final URL url = deleteReactionsURL(new URL("https://oregon-api.stream-io-api.com"));//$$ need to deploy proxy + final URL url = deleteReactionsURL(baseURL); final byte[] payload = toJSON(request); io.getstream.core.http.Request httpRequest = buildPost(url, key, token, payload); - //print the response - return httpClient.execute(httpRequest).thenApply(response -> null); } catch (Exception e) { throw new StreamException(e); @@ -561,8 +556,7 @@ public CompletableFuture exportUserActivities(Token token, St } try { - final URL url = buildExportIDsURL(baseURL, userId); -// final URL url = buildExportIDsURL(new URL("https://oregon-api.stream-io-api.com"), userId);//$$ need to deploy proxy + final URL url = buildExportIDsURL(baseURL, userId); io.getstream.core.http.Request request = buildGet(url, key, token); return httpClient .execute(request) diff --git a/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java b/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java index 5d394256..85ecd7ab 100644 --- a/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java +++ b/src/test/java/io/getstream/client/BatchDeleteActivitiesTest.java @@ -152,7 +152,7 @@ public void testDeleteReactions() throws Exception { } @Test - public void testDeleteActivitis() throws Exception { + public void testDeleteActivitiesMultipleFeeds() throws Exception { // Insert some activities String uuid1 = UUID.randomUUID().toString().replace("-", ""); @@ -219,12 +219,10 @@ public void testDeleteActivitis() throws Exception { activities =feedAlice.getActivities( new Limit(10), new Filter()).join(); - assertEquals(2, activities.size());//0 + assertEquals(2, activities.size()); activities =feedAlice.getActivities( new Limit(10), new Filter().discardDeletedActivities()).join(); - assertEquals(0, activities.size());//1 - - + assertEquals(0, activities.size()); } } \ No newline at end of file From 72eb9b6add1c59047b528a40c0c9440ccc446b52 Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Mon, 11 Nov 2024 17:14:31 +0100 Subject: [PATCH 8/8] chore: add BatchDeleteReactionsRequest --- .../models/BatchDeleteReactionsRequest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/io/getstream/core/models/BatchDeleteReactionsRequest.java diff --git a/src/main/java/io/getstream/core/models/BatchDeleteReactionsRequest.java b/src/main/java/io/getstream/core/models/BatchDeleteReactionsRequest.java new file mode 100644 index 00000000..bf6efd4a --- /dev/null +++ b/src/main/java/io/getstream/core/models/BatchDeleteReactionsRequest.java @@ -0,0 +1,19 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class BatchDeleteReactionsRequest { + + private final List ids; + + public BatchDeleteReactionsRequest(@JsonProperty("ids") List ids) { + this.ids = ids; + } + + public List getIds() { + return ids; + } +} \ No newline at end of file