Skip to content

Commit 3315598

Browse files
author
Max Klyga
committed
Version 3.1.1
* Fix microsecond parsing causing ~8 minute skew when deserializing activities * Fix batch operation paths, arguments and tokens
1 parent 660a33a commit 3315598

File tree

10 files changed

+116
-47
lines changed

10 files changed

+116
-47
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ plugins {
99
}
1010

1111
group 'io.getstream.client'
12-
version = '3.1.0'
12+
version = '3.1.1'
1313

1414
dependencies {
1515
testCompile 'org.junit.jupiter:junit-jupiter-api:5.3.1'

src/main/java/io/getstream/client/BatchClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public CompletableFuture<Void> followMany(Iterable<FollowRelation> follows) thro
4747
}
4848

4949
public CompletableFuture<Void> unfollowMany(FollowRelation... follows) throws StreamException {
50-
final Token token = buildFollowToken(secret, TokenAction.DELETE);
50+
final Token token = buildFollowToken(secret, TokenAction.WRITE);
5151
return batch.unfollowMany(token, follows);
5252
}
5353

src/main/java/io/getstream/client/Client.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public CompletableFuture<Activity> updateActivityByID(String id, Map<String, Obj
3939
}
4040

4141
public CompletableFuture<Activity> updateActivityByID(String id, Map<String, Object> set, String[] unset) throws StreamException {
42-
final Token token = buildFeedToken(secret, TokenAction.WRITE);
42+
final Token token = buildActivityToken(secret, TokenAction.WRITE);
4343
return stream.updateActivityByID(token, id, set, unset);
4444
}
4545

src/main/java/io/getstream/core/Stream.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public CompletableFuture<Activity> updateActivityByID(Token token, String id, Ma
8585
public final Map<String, Object> set = propertiesToSet;
8686
public final String[] unset = propertiesToUnset;
8787
});
88-
final URL url = new URL(baseURL, "activity/");
88+
final URL url = buildActivityUpdateURL(baseURL);
8989
return httpClient.execute(buildPost(url, key, token, payload))
9090
.thenApply(response -> {
9191
try {
@@ -116,7 +116,7 @@ public CompletableFuture<Activity> updateActivityByForeignID(Token token, String
116116
public final Map<String, Object> set = propertiesToSet;
117117
public final String[] unset = propertiesToUnset;
118118
});
119-
final URL url = new URL(baseURL, "activity/");
119+
final URL url = buildActivityUpdateURL(baseURL);
120120
return httpClient.execute(buildPost(url, key, token, payload))
121121
.thenApply(response -> {
122122
try {

src/main/java/io/getstream/core/StreamBatch.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,18 @@
1818
import java.text.SimpleDateFormat;
1919
import java.util.Arrays;
2020
import java.util.List;
21+
import java.util.TimeZone;
2122
import java.util.concurrent.CompletableFuture;
2223
import java.util.concurrent.CompletionException;
2324

2425
import static com.google.common.base.Preconditions.checkArgument;
2526
import static com.google.common.base.Preconditions.checkNotNull;
2627
import static io.getstream.core.utils.Request.buildGet;
2728
import static io.getstream.core.utils.Request.buildPost;
28-
import static io.getstream.core.utils.Routes.buildActivitiesURL;
29+
import static io.getstream.core.utils.Routes.*;
2930
import static io.getstream.core.utils.Serialization.*;
3031

3132
public final class StreamBatch {
32-
private static final SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd");
33-
3433
private final String key;
3534
private final URL baseURL;
3635
private final HTTPClient httpClient;
@@ -52,9 +51,9 @@ public CompletableFuture<Void> addToMany(Token token, Activity activity, FeedID.
5251
try {
5352
final byte[] payload = toJSON(new Object() {
5453
public final Activity activity = data;
55-
public final String[] feed_ids = feedIDs;
54+
public final String[] feeds = feedIDs;
5655
});
57-
final URL url = new URL(baseURL, "feed/add_to_many/");
56+
final URL url = buildAddToManyURL(baseURL);
5857
return httpClient.execute(buildPost(url, key, token, payload))
5958
.thenApply(response -> {
6059
try {
@@ -75,7 +74,7 @@ public CompletableFuture<Void> followMany(Token token, int activityCopyLimit, Fo
7574

7675
try {
7776
final byte[] payload = toJSON(follows);
78-
final URL url = new URL(baseURL, "follow_many/");
77+
final URL url = buildFollowManyURL(baseURL);
7978
return httpClient.execute(buildPost(url, key, token, payload, new CustomQueryParameter("activity_copy_limit", Integer.toString(activityCopyLimit))))
8079
.thenApply(response -> {
8180
try {
@@ -95,7 +94,7 @@ public CompletableFuture<Void> unfollowMany(Token token, FollowRelation... follo
9594

9695
try {
9796
final byte[] payload = toJSON(follows);
98-
final URL url = new URL(baseURL, "unfollow_many/");
97+
final URL url = buildUnfollowManyURL(baseURL);
9998
return httpClient.execute(buildPost(url, key, token, payload))
10099
.thenApply(response -> {
101100
try {
@@ -132,6 +131,10 @@ public CompletableFuture<List<Activity>> getActivitiesByForeignID(Token token, F
132131
checkNotNull(activityIDTimePairs, "No activities to get");
133132
checkArgument(activityIDTimePairs.length > 0, "No activities to get");
134133

134+
SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
135+
timestampFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
136+
timestampFormat.setLenient(false);
137+
135138
String[] foreignIDs = Arrays.stream(activityIDTimePairs)
136139
.map(pair -> pair.getForeignID())
137140
.toArray(String[]::new);

src/main/java/io/getstream/core/utils/Routes.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ public final class Routes {
1414
private static final String analyticsSubdomain = "analytics";
1515
private static final String personalizationSubdomain = "personalization";
1616
private static final String activitiesPath = "activities/";
17+
private static final String activityUpdatePath = "activity/";
18+
private static final String addToManyPath = "feed/add_to_many/";
19+
private static final String followManyPath = "follow_many/";
20+
private static final String unfollowManyPath = "unfollow_many/";
1721
private static final String collectionsPath = "collections/";
1822
private static final String filesPath = "files/";
1923
private static final String imagesPath = "images/";
@@ -84,6 +88,22 @@ public static URL buildAnalyticsURL(URL baseURL, String path) throws MalformedUR
8488
return buildSubdomainPath(baseURL, analyticsSubdomain, analyticsPath, path);
8589
}
8690

91+
public static URL buildActivityUpdateURL(URL baseURL) throws MalformedURLException {
92+
return new URL(baseURL, basePath + activityUpdatePath);
93+
}
94+
95+
public static URL buildAddToManyURL(URL baseURL) throws MalformedURLException {
96+
return new URL(baseURL, basePath + addToManyPath);
97+
}
98+
99+
public static URL buildFollowManyURL(URL baseURL) throws MalformedURLException {
100+
return new URL(baseURL, basePath + followManyPath);
101+
}
102+
103+
public static URL buildUnfollowManyURL(URL baseURL) throws MalformedURLException {
104+
return new URL(baseURL, basePath + unfollowManyPath);
105+
}
106+
87107
private static URL buildSubdomainPath(URL baseURL, String subdomain, String apiPath, String path) throws MalformedURLException {
88108
try {
89109
URI baseURI = baseURL.toURI();
Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.getstream.client;
22

3+
import com.google.common.collect.ImmutableMap;
34
import io.getstream.core.http.OKHTTPClientAdapter;
45
import io.getstream.core.models.Activity;
56
import io.getstream.core.models.FeedID;
@@ -8,7 +9,8 @@
89
import okhttp3.OkHttpClient;
910
import org.junit.jupiter.api.Test;
1011

11-
import java.util.Date;
12+
import java.text.SimpleDateFormat;
13+
import java.util.*;
1214

1315
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
1416

@@ -19,84 +21,105 @@ class BatchClientTest {
1921
@Test
2022
void addToMany() {
2123
assertDoesNotThrow(() -> {
22-
Client client = Client.builder(apiKey, secret)
23-
.httpClient(new OKHTTPClientAdapter(new OkHttpClient()))
24-
.build();
24+
Client client = Client.builder(apiKey, secret).build();
2525

2626
Activity activity = Activity.builder()
2727
.actor("test")
2828
.verb("test")
2929
.object("test")
3030
.build();
31+
3132
client.batch().addToMany(activity, new FeedID[]{
3233
new FeedID("flat", "1"),
3334
new FeedID("flat", "2")
34-
});
35+
}).join();
3536
});
3637
}
3738

3839
@Test
3940
void followMany() {
4041
assertDoesNotThrow(() -> {
41-
BatchClient client = Client.builder(apiKey, secret)
42-
.httpClient(new OKHTTPClientAdapter(new OkHttpClient()))
43-
.build()
44-
.batch();
42+
BatchClient client = Client.builder(apiKey, secret).build().batch();
4543

46-
client.followMany(0, new FollowRelation("flat:1", "flat:2"), new FollowRelation("aggregated:1", "flat:1"));
44+
client.followMany(0, new FollowRelation[]{
45+
new FollowRelation("flat:1", "flat:2"),
46+
new FollowRelation("aggregated:1", "flat:1")
47+
}).join();
4748
});
4849
}
4950

5051
@Test
5152
void unfollowMany() {
5253
assertDoesNotThrow(() -> {
53-
BatchClient client = Client.builder(apiKey, secret)
54-
.httpClient(new OKHTTPClientAdapter(new OkHttpClient()))
55-
.build()
56-
.batch();
54+
BatchClient client = Client.builder(apiKey, secret).build().batch();
5755

58-
client.unfollowMany(new FollowRelation("flat:1", "flat:2"), new FollowRelation("aggregated:1", "flat:1"));
56+
client.unfollowMany(new FollowRelation[]{
57+
new FollowRelation("flat:1", "flat:2"),
58+
new FollowRelation("aggregated:1", "flat:1")
59+
}).join();
5960
});
6061
}
6162

6263
@Test
6364
void updateActivities() {
6465
assertDoesNotThrow(() -> {
65-
BatchClient client = Client.builder(apiKey, secret)
66-
.httpClient(new OKHTTPClientAdapter(new OkHttpClient()))
67-
.build()
68-
.batch();
66+
BatchClient client = Client.builder(apiKey, secret).build().batch();
6967

7068
client.updateActivities(Activity.builder()
71-
.id("54a60c1e-4ee3-494b-a1e3-50c06acb5ed4")
7269
.actor("test")
7370
.verb("test")
7471
.object("test")
75-
.build());
72+
.foreignID("foreignID")
73+
.time(new Date())
74+
.build()).join();
75+
});
76+
}
77+
78+
@Test
79+
void partiallyUpdateActivityByID() {
80+
Activity[] result = new Activity[1];
81+
assertDoesNotThrow(() -> {
82+
Client client = Client.builder(apiKey, secret).build();
83+
84+
Map<String, Object> set = ImmutableMap.of("value", "message");
85+
Iterable<String> unset = Collections.emptyList();
86+
result[0] = client.updateActivityByID("1657b300-a648-11d5-8080-800020fde6c3", set, unset).join();
87+
});
88+
}
89+
90+
@Test
91+
void partiallyUpdateActivityByForeignID() {
92+
Activity[] result = new Activity[1];
93+
assertDoesNotThrow(() -> {
94+
Client client = Client.builder(apiKey, secret).build();
95+
96+
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S");
97+
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
98+
Date time = isoFormat.parse("2001-09-11T00:01:02.000000");
99+
100+
Map<String, Object> set = ImmutableMap.of("value", "message");
101+
Iterable<String> unset = Collections.emptyList();
102+
result[0] = client.updateActivityByForeignID(new ForeignIDTimePair("foreignID", time), set, unset).join();
76103
});
77104
}
78105

79106
@Test
80107
void getActivitiesByID() {
108+
List<Activity>[] result = new List[1];
81109
assertDoesNotThrow(() -> {
82-
BatchClient client = Client.builder(apiKey, secret)
83-
.httpClient(new OKHTTPClientAdapter(new OkHttpClient()))
84-
.build()
85-
.batch();
110+
BatchClient client = Client.builder(apiKey, secret).build().batch();
86111

87-
client.getActivitiesByID("54a60c1e-4ee3-494b-a1e3-50c06acb5ed4");
112+
result[0] = client.getActivitiesByID("1657b300-a648-11d5-8080-800020fde6c3").join();
88113
});
89114
}
90115

91116
@Test
92117
void getActivitiesByForeignID() {
118+
List<Activity>[] result = new List[1];
93119
assertDoesNotThrow(() -> {
94-
BatchClient client = Client.builder(apiKey, secret)
95-
.httpClient(new OKHTTPClientAdapter(new OkHttpClient()))
96-
.build()
97-
.batch();
120+
BatchClient client = Client.builder(apiKey, secret).build().batch();
98121

99-
client.getActivitiesByForeignID(new ForeignIDTimePair("foreignID", new Date()));
122+
result[0] = client.getActivitiesByForeignID(new ForeignIDTimePair("foreignID", new Date())).join();
100123
});
101124
}
102125
}

src/test/java/io/getstream/client/FeedTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
import okhttp3.OkHttpClient;
1111
import org.junit.jupiter.api.Test;
1212

13+
import java.text.SimpleDateFormat;
1314
import java.util.Date;
1415
import java.util.List;
16+
import java.util.TimeZone;
1517

1618
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
1719

@@ -27,10 +29,16 @@ void addActivity() {
2729
.httpClient(new OKHTTPClientAdapter(new OkHttpClient()))
2830
.build();
2931

32+
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S");
33+
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
34+
Date time = isoFormat.parse("2001-09-11T00:01:02.000000");
35+
3036
Activity activity = Activity.builder()
3137
.actor("test")
3238
.verb("test")
3339
.object("test")
40+
.foreignID("foreignID")
41+
.time(time)
3442
.build();
3543
FlatFeed feed = client.flatFeed("flat", "1");
3644
result[0] = feed.addActivity(activity).join();

src/test/java/io/getstream/core/utils/ActivityGenerator.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
import com.pholser.junit.quickcheck.generator.java.lang.DoubleGenerator;
77
import com.pholser.junit.quickcheck.generator.java.lang.StringGenerator;
88
import com.pholser.junit.quickcheck.generator.java.util.ArrayListGenerator;
9-
import com.pholser.junit.quickcheck.generator.java.util.DateGenerator;
109
import com.pholser.junit.quickcheck.generator.java.util.HashMapGenerator;
1110
import com.pholser.junit.quickcheck.random.SourceOfRandomness;
1211
import io.getstream.core.models.Activity;
1312
import io.getstream.core.models.FeedID;
1413

14+
import java.util.Date;
15+
1516
public class ActivityGenerator extends Generator<Activity> {
1617
private static final class FeedIDGenerator extends Generator<FeedID> {
1718
public FeedIDGenerator() {
@@ -33,6 +34,20 @@ public FeedID generate(SourceOfRandomness r, GenerationStatus status) {
3334
}
3435
}
3536

37+
private static final class DateGenerator extends Generator<Date> {
38+
private Date min = new Date(Integer.MIN_VALUE);
39+
private Date max = new Date(8099, 0, 1);
40+
41+
public DateGenerator() {
42+
super(Date.class);
43+
}
44+
45+
@Override
46+
public Date generate(SourceOfRandomness random, GenerationStatus status) {
47+
return new Date(random.nextLong(min.getTime(), max.getTime()));
48+
}
49+
}
50+
3651
public ActivityGenerator() {
3752
super(Activity.class);
3853
}

src/test/java/io/getstream/core/utils/SerializationTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class SomeCustomType {
3333
class SerializationTest {
3434
@Test
3535
void activitySerialization() throws ParseException {
36-
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S");
36+
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
3737
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
3838

3939
String[] result = new String[1];
@@ -42,13 +42,13 @@ void activitySerialization() throws ParseException {
4242
.verb("test")
4343
.object("test")
4444
.to(new FeedID("hey:now"))
45-
.time(isoFormat.parse("2001-09-11T00:01:02.000000"))
45+
.time(isoFormat.parse("2001-09-11T00:01:02.000"))
4646
.build();
4747

4848
assertDoesNotThrow(() -> {
4949
result[0] = new String(toJSON(activity), Charset.forName("UTF-8"));
5050
});
51-
assertEquals(result[0], "{\"actor\":\"test\",\"verb\":\"test\",\"object\":\"test\",\"time\":\"2001-09-11T00:01:02.0\",\"to\":[\"hey:now\"]}");
51+
assertEquals(result[0], "{\"actor\":\"test\",\"verb\":\"test\",\"object\":\"test\",\"time\":\"2001-09-11T00:01:02.000\",\"to\":[\"hey:now\"]}");
5252
}
5353

5454
@Test

0 commit comments

Comments
 (0)