From c177149566c98fca9928d7d335c042f929356ce2 Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 12 Jan 2016 15:47:02 +0100 Subject: [PATCH 001/320] Added unit tests #13 --- pom.xml | 7 ++ stream-core/pom.xml | 5 ++ .../getstream/client/config/StreamRegion.java | 2 +- .../client/config/StreamRegionTest.java | 14 ++++ .../AggregatedActivityServiceImplTest.java | 61 +++++++++++++++ .../service/FlatActivityServiceImplTest.java | 59 +++++++++++++++ .../NotificationActivityServiceImplTest.java | 74 +++++++++++++++++++ .../service/UserActivityServiceImplTest.java | 61 +++++++++++++++ .../client/util/DateDeserializerTest.java | 47 ++++++++++++ .../getstream/client/util/InfoUtilTest.java | 16 ++++ .../src/test/resources/stream-java.info | 1 + 11 files changed, 346 insertions(+), 1 deletion(-) create mode 100644 stream-core/src/test/java/io/getstream/client/config/StreamRegionTest.java create mode 100644 stream-core/src/test/java/io/getstream/client/service/AggregatedActivityServiceImplTest.java create mode 100644 stream-core/src/test/java/io/getstream/client/service/FlatActivityServiceImplTest.java create mode 100644 stream-core/src/test/java/io/getstream/client/service/NotificationActivityServiceImplTest.java create mode 100644 stream-core/src/test/java/io/getstream/client/service/UserActivityServiceImplTest.java create mode 100644 stream-core/src/test/java/io/getstream/client/util/DateDeserializerTest.java create mode 100644 stream-core/src/test/java/io/getstream/client/util/InfoUtilTest.java create mode 100644 stream-core/src/test/resources/stream-java.info diff --git a/pom.xml b/pom.xml index 449338ea..ee3d4117 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,7 @@ 18.0 2.4.3 4.11 + 1.10.19 @@ -102,6 +103,12 @@ ${junit.version} test + + org.mockito + mockito-core + ${mockito.version} + test + diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 4ca18457..db5a9a14 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -56,5 +56,10 @@ junit test + + org.mockito + mockito-core + test + \ No newline at end of file diff --git a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java index 9ac965d8..d6a1bb8b 100644 --- a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java +++ b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java @@ -46,7 +46,7 @@ public enum StreamRegion { AP_SOUTH_EAST("https://ap-southeast-api.getstream.io/api"), LOCAL("http://localhost:8000/api"); - private final static String VERSION = "v1.0"; + protected final static String VERSION = "v1.0"; private final String endpoint; diff --git a/stream-core/src/test/java/io/getstream/client/config/StreamRegionTest.java b/stream-core/src/test/java/io/getstream/client/config/StreamRegionTest.java new file mode 100644 index 00000000..0a06fe53 --- /dev/null +++ b/stream-core/src/test/java/io/getstream/client/config/StreamRegionTest.java @@ -0,0 +1,14 @@ +package io.getstream.client.config; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class StreamRegionTest { + + @Test + public void shouldGetEndpoint() { + assertThat(StreamRegion.US_EAST.getEndpoint().toString(), is("https://us-east-api.getstream.io/api/" + StreamRegion.VERSION)); + } +} \ No newline at end of file diff --git a/stream-core/src/test/java/io/getstream/client/service/AggregatedActivityServiceImplTest.java b/stream-core/src/test/java/io/getstream/client/service/AggregatedActivityServiceImplTest.java new file mode 100644 index 00000000..8ecf13b5 --- /dev/null +++ b/stream-core/src/test/java/io/getstream/client/service/AggregatedActivityServiceImplTest.java @@ -0,0 +1,61 @@ +package io.getstream.client.service; + +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.AggregatedActivity; +import io.getstream.client.model.activities.BaseActivity; +import io.getstream.client.model.activities.SimpleActivity; +import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.feeds.BaseFeed; +import io.getstream.client.model.filters.FeedFilter; +import io.getstream.client.repo.StreamRepository; +import org.hamcrest.Matcher; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.io.IOException; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsNull.notNullValue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class AggregatedActivityServiceImplTest { + + @Mock + private BaseFeed feed; + + @Mock + private StreamRepository repository; + + @Mock + private StreamResponse response; + + private AggregatedActivityServiceImpl simpleActivityAggregatedActivityService; + + @Before + public void setUp() throws IOException, StreamClientException { + when(repository.getAggregatedActivities(any(BaseFeed.class), eq(SimpleActivity.class), any(FeedFilter.class))).thenReturn(response); + simpleActivityAggregatedActivityService = new AggregatedActivityServiceImpl<>(feed, SimpleActivity.class, repository); + } + + @Test + public void shouldGetActivities() throws Exception { + StreamResponse> activities = simpleActivityAggregatedActivityService.getActivities(); + verify(repository).getAggregatedActivities(any(BaseFeed.class), eq(SimpleActivity.class), any(FeedFilter.class)); + assertThat(activities, notNullValue()); + } + + @Test + public void shouldGetActivitiesWithFilter() throws Exception { + FeedFilter filter = new FeedFilter.Builder().build(); + StreamResponse> activities = simpleActivityAggregatedActivityService.getActivities(filter); + verify(repository).getAggregatedActivities(any(BaseFeed.class), eq(SimpleActivity.class), eq(filter)); + assertThat(activities, notNullValue()); + } +} \ No newline at end of file diff --git a/stream-core/src/test/java/io/getstream/client/service/FlatActivityServiceImplTest.java b/stream-core/src/test/java/io/getstream/client/service/FlatActivityServiceImplTest.java new file mode 100644 index 00000000..ca9c8700 --- /dev/null +++ b/stream-core/src/test/java/io/getstream/client/service/FlatActivityServiceImplTest.java @@ -0,0 +1,59 @@ +package io.getstream.client.service; + +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.AggregatedActivity; +import io.getstream.client.model.activities.SimpleActivity; +import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.feeds.BaseFeed; +import io.getstream.client.model.filters.FeedFilter; +import io.getstream.client.repo.StreamRepository; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.io.IOException; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsNull.notNullValue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class FlatActivityServiceImplTest { + + @Mock + private BaseFeed feed; + + @Mock + private StreamRepository repository; + + @Mock + private StreamResponse response; + + private FlatActivityService flatActivityService; + + @Before + public void setUp() throws IOException, StreamClientException { + when(repository.getActivities(any(BaseFeed.class), eq(SimpleActivity.class), any(FeedFilter.class))).thenReturn(response); + flatActivityService = new FlatActivityServiceImpl<>(feed, SimpleActivity.class, repository); + } + + @Test + public void shouldGetActivities() throws Exception { + StreamResponse activities = flatActivityService.getActivities(); + verify(repository).getActivities(any(BaseFeed.class), eq(SimpleActivity.class), any(FeedFilter.class)); + assertThat(activities, notNullValue()); + } + + @Test + public void shouldGetActivitiesWithFilter() throws Exception { + FeedFilter filter = new FeedFilter.Builder().build(); + StreamResponse activities = flatActivityService.getActivities(filter); + verify(repository).getActivities(any(BaseFeed.class), eq(SimpleActivity.class), eq(filter)); + assertThat(activities, notNullValue()); + } +} \ No newline at end of file diff --git a/stream-core/src/test/java/io/getstream/client/service/NotificationActivityServiceImplTest.java b/stream-core/src/test/java/io/getstream/client/service/NotificationActivityServiceImplTest.java new file mode 100644 index 00000000..04f9c396 --- /dev/null +++ b/stream-core/src/test/java/io/getstream/client/service/NotificationActivityServiceImplTest.java @@ -0,0 +1,74 @@ +package io.getstream.client.service; + +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.AggregatedActivity; +import io.getstream.client.model.activities.NotificationActivity; +import io.getstream.client.model.activities.SimpleActivity; +import io.getstream.client.model.beans.MarkedActivity; +import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.feeds.BaseFeed; +import io.getstream.client.model.filters.FeedFilter; +import io.getstream.client.repo.StreamRepository; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.io.IOException; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsNull.notNullValue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class NotificationActivityServiceImplTest { + + @Mock + private BaseFeed feed; + + @Mock + private StreamRepository repository; + + @Mock + private StreamResponse response; + + private NotificationActivityService notificationActivityService; + + @Before + public void setUp() throws IOException, StreamClientException { + when(repository.getNotificationActivities(any(BaseFeed.class), eq(SimpleActivity.class), any(FeedFilter.class))).thenReturn(response); + when(repository.getNotificationActivities(any(BaseFeed.class), eq(SimpleActivity.class), any(FeedFilter.class), anyBoolean(), anyBoolean())).thenReturn(response); + when(repository.getNotificationActivities(any(BaseFeed.class), eq(SimpleActivity.class), any(FeedFilter.class), any(MarkedActivity.class), any(MarkedActivity.class))).thenReturn(response); + notificationActivityService = new NotificationActivityServiceImpl<>(feed, SimpleActivity.class, repository); + } + + @Test + public void shouldGetActivities() throws Exception { + StreamResponse> activities = notificationActivityService.getActivities(); + verify(repository).getNotificationActivities(any(BaseFeed.class), eq(SimpleActivity.class), any(FeedFilter.class)); + assertThat(activities, notNullValue()); + } + + @Test + public void shouldGetActivitiesWithFilter() throws Exception { + FeedFilter filter = new FeedFilter.Builder().build(); + StreamResponse> activities = notificationActivityService.getActivities(filter, true, true); + verify(repository).getNotificationActivities(any(BaseFeed.class), eq(SimpleActivity.class), any(FeedFilter.class), eq(true), eq(true)); + assertThat(activities, notNullValue()); + } + + @Test + public void shouldGetActivitiesWithMark() throws Exception { + FeedFilter filter = new FeedFilter.Builder().build(); + MarkedActivity asSeen = new MarkedActivity.Builder().withActivityId("1").build(); + MarkedActivity asRead = new MarkedActivity.Builder().withActivityId("1").build(); + StreamResponse> activities = notificationActivityService.getActivities(filter, asSeen, asRead); + verify(repository).getNotificationActivities(any(BaseFeed.class), eq(SimpleActivity.class), any(FeedFilter.class), eq(asSeen), eq(asRead)); + assertThat(activities, notNullValue()); + } +} \ No newline at end of file diff --git a/stream-core/src/test/java/io/getstream/client/service/UserActivityServiceImplTest.java b/stream-core/src/test/java/io/getstream/client/service/UserActivityServiceImplTest.java new file mode 100644 index 00000000..5d67f3d8 --- /dev/null +++ b/stream-core/src/test/java/io/getstream/client/service/UserActivityServiceImplTest.java @@ -0,0 +1,61 @@ +package io.getstream.client.service; + +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.SimpleActivity; +import io.getstream.client.model.beans.MarkedActivity; +import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.feeds.BaseFeed; +import io.getstream.client.model.filters.FeedFilter; +import io.getstream.client.repo.StreamRepository; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.io.IOException; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsNull.notNullValue; +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class UserActivityServiceImplTest { + + @Mock + private BaseFeed feed; + + @Mock + private StreamRepository repository; + + @Mock + private StreamResponse response; + + private UserActivityService userActivityService; + + @Before + public void setUp() throws IOException, StreamClientException { + when(repository.getActivities(any(BaseFeed.class), eq(SimpleActivity.class), any(FeedFilter.class))).thenReturn(response); + userActivityService = new UserActivityServiceImpl<>(feed, SimpleActivity.class, repository); + } + + @Test + public void shouldGetActivities() throws Exception { + StreamResponse activities = userActivityService.getActivities(); + verify(repository).getActivities(any(BaseFeed.class), eq(SimpleActivity.class), any(FeedFilter.class)); + assertThat(activities, notNullValue()); + } + + @Test + public void shouldGetActivitiesWithFilter() throws Exception { + FeedFilter filter = new FeedFilter.Builder().build(); + StreamResponse activities = userActivityService.getActivities(filter); + verify(repository).getActivities(any(BaseFeed.class), eq(SimpleActivity.class), eq(filter)); + assertThat(activities, notNullValue()); + } +} \ No newline at end of file diff --git a/stream-core/src/test/java/io/getstream/client/util/DateDeserializerTest.java b/stream-core/src/test/java/io/getstream/client/util/DateDeserializerTest.java new file mode 100644 index 00000000..9e397e4f --- /dev/null +++ b/stream-core/src/test/java/io/getstream/client/util/DateDeserializerTest.java @@ -0,0 +1,47 @@ +package io.getstream.client.util; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.io.IOException; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class DateDeserializerTest { + + @Test + public void shouldParseTheDate() throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + MyDateBean myDateBean = objectMapper.readValue("{ \"time\": \"2016-01-12T08:20:59.000Z\" }", MyDateBean.class); + GregorianCalendar expectedDate = new GregorianCalendar(TimeZone.getTimeZone("GMT")); + expectedDate.set(2016,0,12,8,20,59); + expectedDate.set(GregorianCalendar.MILLISECOND, 0); + assertThat(myDateBean.getTime(), is(expectedDate.getTime())); + } + + static class MyDateBean { + @JsonDeserialize(using = DateDeserializer.class) + @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.S") + protected Date time; + + public Date getTime() { + return time; + } + + public void setTime(Date time) { + this.time = time; + } + } +} \ No newline at end of file diff --git a/stream-core/src/test/java/io/getstream/client/util/InfoUtilTest.java b/stream-core/src/test/java/io/getstream/client/util/InfoUtilTest.java new file mode 100644 index 00000000..0c5bd96d --- /dev/null +++ b/stream-core/src/test/java/io/getstream/client/util/InfoUtilTest.java @@ -0,0 +1,16 @@ +package io.getstream.client.util; + +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +public class InfoUtilTest { + + @Test + public void shouldGetProperties() { + assertThat(InfoUtil.getProperties().getProperty("version"), is("1.0")); + } + +} \ No newline at end of file diff --git a/stream-core/src/test/resources/stream-java.info b/stream-core/src/test/resources/stream-java.info new file mode 100644 index 00000000..2a453a00 --- /dev/null +++ b/stream-core/src/test/resources/stream-java.info @@ -0,0 +1 @@ +version=1.0 \ No newline at end of file From 80a68d696a243b5f4a10f702ce0e439a74b75988 Mon Sep 17 00:00:00 2001 From: sirio7g Date: Fri, 15 Jan 2016 16:57:21 +0100 Subject: [PATCH 002/320] Configure jackson to not break when a superset of the response is returned #8 --- .../getstream/client/apache/repo/StreamRepositoryImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index f42783f2..d3857d72 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -31,6 +31,7 @@ package io.getstream.client.apache.repo; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import io.getstream.client.config.ClientConfiguration; @@ -76,8 +77,9 @@ public class StreamRepositoryImpl implements StreamRepository { static final String API_KEY = "api_key"; /* will convert camelStyle to lower_case_style */ - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().setPropertyNamingStrategy( - PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() + .setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); private final URI baseEndpoint; private final String apiKey; From 0c431fe610faa3294a2968ac0b6c7c65a96d5779 Mon Sep 17 00:00:00 2001 From: alessandro Date: Sun, 24 Jan 2016 19:06:20 +0100 Subject: [PATCH 003/320] Jackson disabled FAIL_ON_EMPTY_BEANS --- .../getstream/client/apache/repo/StreamRepositoryImpl.java | 4 +++- .../getstream/client/okhttp/repo/StreamRepositoryImpl.java | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index 03e7ec93..b7c6a1ab 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -34,6 +34,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.SerializationFeature; import io.getstream.client.config.ClientConfiguration; import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.AggregatedActivity; @@ -83,7 +84,8 @@ public class StreamRepositoryImpl implements StreamRepository { /* will convert camelStyle to lower_case_style */ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() .setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES) - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); private final URI baseEndpoint; private final String apiKey; diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index cff1c0d8..267694b1 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -30,6 +30,8 @@ */ package io.getstream.client.okhttp.repo; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.SerializationFeature; import com.squareup.okhttp.MediaType; import com.squareup.okhttp.RequestBody; import io.getstream.client.model.beans.FollowMany; @@ -81,7 +83,10 @@ public String getToken(BaseFeed feed) { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().setPropertyNamingStrategy( /* will convert camelStyle to lower_case_style */ - PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); + PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + private final URI baseEndpoint; private final String apiKey; From e938471360b57ae5c7071bde3019589855e88638 Mon Sep 17 00:00:00 2001 From: alessandro Date: Mon, 25 Jan 2016 14:15:38 +0100 Subject: [PATCH 004/320] Add add_to_many implementation #9 --- .../getstream/client/model/beans/AddMany.java | 38 +++++++++++++++++++ .../client/repo/StreamRepository.java | 18 ++++++++- .../service/AbstractActivityService.java | 14 +++++++ .../apache/repo/StreamActivityRepository.java | 28 ++++++++++++++ .../apache/repo/StreamRepositoryImpl.java | 6 ++- .../client/apache/IntegrationTest.java | 21 +++++++++- .../okhttp/repo/StreamActivityRepository.java | 22 +++++++++++ .../okhttp/repo/StreamRepositoryImpl.java | 5 +++ .../client/okhttp/IntegrationTest.java | 22 +++++++++++ 9 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/AddMany.java diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/AddMany.java b/stream-core/src/main/java/io/getstream/client/model/beans/AddMany.java new file mode 100644 index 00000000..a5cc1163 --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/model/beans/AddMany.java @@ -0,0 +1,38 @@ +package io.getstream.client.model.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.getstream.client.model.activities.BaseActivity; + +import java.util.List; + +/** + * Helper bean to create a payload used for the add_to_many API call. + * @param Type of the activity + */ +public class AddMany { + + @JsonProperty("feeds") + private List targetIds; + private T activity; + + public AddMany(List targetIds, T activity) { + this.targetIds = targetIds; + this.activity = activity; + } + + public List getTargetIds() { + return targetIds; + } + + public void setTargetIds(List targetIds) { + this.targetIds = targetIds; + } + + public T getActivity() { + return activity; + } + + public void setActivity(T activity) { + this.activity = activity; + } +} diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java index 7a9d6bac..bef1133b 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java @@ -147,6 +147,17 @@ public interface StreamRepository { */ T addActivity(BaseFeed feed, T activity) throws StreamClientException, IOException; + /** + * Add a new activity of type {@link T} to multiple feeds. + * + * @param targetIds Destination feeds.
A target id is defined as $feedSlug:$feedId. + * @param activity Activity to add. + * @return Response activity of type {@link T} coming from the server. + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + T addActivityToMany(List targetIds, T activity) throws StreamClientException, IOException; + /** * List aggregated activities. * @@ -205,7 +216,12 @@ public interface StreamRepository { */ StreamResponse> getNotificationActivities(BaseFeed feed, Class type, FeedFilter filter, MarkedActivity markAsRead, MarkedActivity markAsSeen) throws IOException, StreamClientException; - public String getToken(BaseFeed feed); + /** + * Get the token for the given feed. + * @param feed Feed + * @return A token string + */ + String getToken(BaseFeed feed); /** * Send the shutdown signal to the client. diff --git a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java index 6ae92974..e36a9cd6 100644 --- a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java +++ b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java @@ -36,6 +36,7 @@ import io.getstream.client.repo.StreamRepository; import java.io.IOException; +import java.util.List; /** * Provides operations to be performed against activities. @@ -66,4 +67,17 @@ public AbstractActivityService(BaseFeed feed, Class type, StreamRepository strea public T addActivity(T activity) throws IOException, StreamClientException { return streamRepository.addActivity(this.feed, activity); } + + /** + * Add a new activity of type {@link T} to multiple feeds. + * + * @param targetIds Destination feeds.
A target id is defined as $feedSlug:$feedId. + * @param activity Activity to add. + * @return Response activity of type {@link T} coming from the server. + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + public T addActivityToMany(List targetIds, T activity) throws IOException, StreamClientException { + return streamRepository.addActivityToMany(targetIds, activity); + } } diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java index b046c4df..5b101839 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java @@ -31,10 +31,12 @@ package io.getstream.client.apache.repo; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableList; import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.NotificationActivity; +import io.getstream.client.model.beans.AddMany; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.apache.repo.handlers.StreamExceptionHandler; import io.getstream.client.apache.repo.utils.SignatureUtils; @@ -43,6 +45,9 @@ import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.apache.repo.utils.StreamRepoUtils; import io.getstream.client.apache.repo.utils.UriBuilder; +import io.getstream.client.util.HttpSignatureHandler; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; @@ -51,13 +56,16 @@ import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.message.BasicNameValuePair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URI; +import java.util.List; import static io.getstream.client.apache.repo.utils.FeedFilterUtils.apply; +import static org.apache.http.entity.ContentType.APPLICATION_FORM_URLENCODED; import static org.apache.http.entity.ContentType.APPLICATION_JSON; public class StreamActivityRepository { @@ -97,6 +105,26 @@ public T addActivity(BaseFeed feed, T activity) throws } } + public T addToMany(List targetIds, T activity) throws StreamClientException, IOException { + HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) + .path("feed") + .path("add_to_many/") + .build()); + LOG.debug("Invoking url: '{}'", request.getURI()); + + request.setEntity(new StringEntity( + objectMapper.writeValueAsString(new AddMany<>(targetIds, activity)), + APPLICATION_JSON)); + + request.addHeader(HttpSignatureHandler.X_API_KEY_HEADER, apiKey); + + try (CloseableHttpResponse response = httpClient.execute(request, HttpClientContext.create())) { + handleResponseCode(response); + return objectMapper.readValue(response.getEntity().getContent(), + objectMapper.getTypeFactory().constructType(activity.getClass())); + } + } + public StreamResponse getActivities(BaseFeed feed, Class type, FeedFilter filter) throws IOException, StreamClientException { HttpGet request = new HttpGet(apply(UriBuilder.fromEndpoint(baseEndpoint) .path("feed").path(feed.getFeedSlug()).path(feed.getUserId() + "/") diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index b7c6a1ab..36c330e1 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -50,7 +50,6 @@ import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.apache.repo.utils.UriBuilder; import io.getstream.client.repo.StreamRepository; -import org.apache.http.HttpEntity; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpDelete; @@ -191,6 +190,11 @@ public T addActivity(BaseFeed feed, T activity) throws return streamActivityRepository.addActivity(feed, activity); } + @Override + public T addActivityToMany(List targetIds, T activity) throws StreamClientException, IOException { + return streamActivityRepository.addToMany(targetIds, activity); + } + @Override public StreamResponse> getAggregatedActivities(BaseFeed feed, Class type, FeedFilter filter) throws IOException, StreamClientException { return streamActivityRepository.getAggregatedActivities(feed, type, filter); diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index 1351d044..f4b633f8 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -1,5 +1,6 @@ package io.getstream.client.apache; +import com.google.common.collect.ImmutableList; import io.getstream.client.StreamClient; import io.getstream.client.config.ClientConfiguration; import io.getstream.client.exception.AuthenticationFailedException; @@ -19,6 +20,7 @@ import io.getstream.client.service.NotificationActivityServiceImpl; import org.hamcrest.MatcherAssert; //import org.junit.BeforeClass; +import org.junit.BeforeClass; import org.junit.Test; import java.io.IOException; @@ -34,7 +36,7 @@ public class IntegrationTest { public static final String API_KEY = "nfq26m3qgfyp"; public static final String API_SECRET = "245nvvjm49s3uwrs5e4h3gadsw34mnwste6v3rdnd69ztb35bqspvq8kfzt9v7h2"; - //@BeforeClass + @BeforeClass public static void setLog() { System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); @@ -210,6 +212,23 @@ public void shouldAddActivity() throws IOException, StreamClientException { streamClient.shutdown(); } + @Test + public void shouldAddActivityToMany() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + API_SECRET); + + String userId = this.getTestUserId("shouldAddActivityToMany"); + Feed feed = streamClient.newFeed("user", userId); + FlatActivityServiceImpl flatActivityService = feed.newFlatActivityService(SimpleActivity.class); + SimpleActivity activity = new SimpleActivity(); + activity.setActor("actor"); + activity.setObject("object"); + activity.setTarget("target"); + activity.setVerb("verb"); + flatActivityService.addActivityToMany(ImmutableList.of("user:1", "user:2").asList(), activity); + streamClient.shutdown(); + } + @Test public void shouldAddActivityToRecipients() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java index 69ac73fc..18f33dfa 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java @@ -30,6 +30,7 @@ */ package io.getstream.client.okhttp.repo; +import io.getstream.client.model.beans.AddMany; import io.getstream.client.okhttp.repo.handlers.StreamExceptionHandler; import io.getstream.client.okhttp.repo.utils.SignatureUtils; import io.getstream.client.okhttp.repo.utils.StreamRepoUtils; @@ -49,11 +50,13 @@ import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.okhttp.repo.utils.FeedFilterUtils; +import io.getstream.client.util.HttpSignatureHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URI; +import java.util.List; public class StreamActivityRepository { @@ -95,6 +98,25 @@ public T addActivity(BaseFeed feed, T activity) throws objectMapper.getTypeFactory().constructType(activity.getClass())); } + public T addToMany(List targetIds, T activity) throws StreamClientException, IOException { + Request.Builder requestBuilder = new Request.Builder().url(UriBuilder.fromEndpoint(baseEndpoint) + .path("feed") + .path("add_to_many/") + .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build().toURL()); + + requestBuilder.addHeader(HttpSignatureHandler.X_API_KEY_HEADER, apiKey); + requestBuilder.post(RequestBody.create(MediaType.parse(APPLICATION_JSON), + objectMapper.writeValueAsString(new AddMany<>(targetIds, activity)))); + + final Request request = requestBuilder.build(); + LOG.debug("Invoking url: '{}", request.urlString()); + + Response response = httpClient.newCall(request).execute(); + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructType(activity.getClass())); + } + public StreamResponse getActivities(BaseFeed feed, Class type, FeedFilter filter) throws IOException, StreamClientException { Request.Builder requestBuilder = new Request.Builder().url(FeedFilterUtils.apply(UriBuilder.fromEndpoint(baseEndpoint) .path("feed").path(feed.getFeedSlug()).path(feed.getUserId() + "/") diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index 267694b1..03fc211e 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -196,6 +196,11 @@ public T addActivity(BaseFeed feed, T activity) throws return streamActivityRepository.addActivity(feed, activity); } + @Override + public T addActivityToMany(List targetIds, T activity) throws StreamClientException, IOException { + return streamActivityRepository.addToMany(targetIds, activity); + } + @Override public StreamResponse> getAggregatedActivities(BaseFeed feed, Class type, FeedFilter filter) throws IOException, StreamClientException { return streamActivityRepository.getAggregatedActivities(feed, type, filter); diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index 800f21dd..d4ce22e2 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -1,5 +1,6 @@ package io.getstream.client.okhttp; +import com.google.common.collect.ImmutableList; import io.getstream.client.StreamClient; import io.getstream.client.config.ClientConfiguration; import io.getstream.client.exception.AuthenticationFailedException; @@ -230,6 +231,27 @@ public void shouldAddActivity() throws IOException, StreamClientException { streamClient.shutdown(); } + @Test + public void shouldAddActivityToMany() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + API_SECRET); + + String userId = this.getTestUserId("shouldAddActivity"); + Feed feed = streamClient.newFeed("user", userId); + FlatActivityServiceImpl flatActivityService = feed.newFlatActivityService(SimpleActivity.class); + SimpleActivity activity = new SimpleActivity(); + activity.setActor("actor"); + activity.setObject("object"); + activity.setTarget("target"); + activity.setVerb("verb"); + + flatActivityService.addActivityToMany( + ImmutableList.of("user:1", "user:2").asList(), + activity + ); + streamClient.shutdown(); + } + @Test public void shouldAddActivityToRecipients() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, From e65a8c6849347bdeb3542d0eab8666529666d64b Mon Sep 17 00:00:00 2001 From: alessandro Date: Mon, 1 Feb 2016 16:46:58 +0100 Subject: [PATCH 005/320] Added unit tests #13 --- README.md | 17 ++-- pom.xml | 51 ++++++++++ .../getstream/client/config/StreamRegion.java | 2 +- .../getstream/client/model/beans/AddMany.java | 2 +- .../client/model/beans/FollowMany.java | 3 + stream-repo-apache/pom.xml | 11 +++ .../client/apache/IntegrationTest.java | 1 - .../client/apache/StreamClientImplTest.java | 38 ++++++++ .../apache/repo/StreamRepositoryImplTest.java | 93 +++++++++++++++++++ .../client/okhttp/StreamClientImplTest.java | 38 ++++++++ 10 files changed, 247 insertions(+), 9 deletions(-) create mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/StreamClientImplTest.java create mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java create mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/StreamClientImplTest.java diff --git a/README.md b/README.md index ddbee397..bf9bb344 100644 --- a/README.md +++ b/README.md @@ -67,11 +67,17 @@ feed.follow(flat", "42"); // Stop following another feed feed.unfollow(flat", "42"); -// Batch adding activities -// This is not supported yet +// Batch adding activities to many feeds +flatActivityService.addActivityToMany(ImmutableList.of("user:1", "user:2").asList(), myActivity); // Batch following many feeds -// This is not supported yet +FollowMany followMany = new FollowMany.Builder() + .add("user:1", "user:2") + .add("user:1", "user:3") + .add("user:1", "user:4") + .add("user:2", "user:3") + .build(); +feed.followMany(followMany); // Add an activity and push it to other feeds too using the `to` field // This is not supported yet @@ -82,9 +88,6 @@ feed.unfollow(flat", "42"); // Generating tokens for client side usage String token = feed.getToken(); -// Javascript client side feed initialization -// user1 = client.feed('user', '1', '{{ token }}'); - // Retrieve first 10 followers of a feed FeedFilter filter = new FeedFilter.Builder().withLimit(10).build(); List followingPaged = feed.getFollowing(filter); @@ -98,4 +101,6 @@ List followingPaged = feed.getFollowing(filter); ``` +For more examples have a look [here](https://github.com/GetStream/stream-java/tree/milestone1/stream-repo-apache/src/test/java/io/getstream/client/apache/example). + Docs are available on [GetStream.io](http://getstream.io/docs/). diff --git a/pom.xml b/pom.xml index 6d5f2049..8eed5654 100644 --- a/pom.xml +++ b/pom.xml @@ -115,6 +115,57 @@ ${mockito.version} test + + com.github.tomakehurst + wiremock + 1.57 + test + + + standalone + + + org.mortbay.jetty + jetty + + + com.google.guava + guava + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-databind + + + org.apache.httpcomponents + httpclient + + + org.skyscreamer + jsonassert + + + xmlunit + xmlunit + + + com.jayway.jsonpath + json-path + + + net.sf.jopt-simple + jopt-simple + + + diff --git a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java index d6a1bb8b..a5d431e2 100644 --- a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java +++ b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java @@ -44,7 +44,7 @@ public enum StreamRegion { EU_WEST("https://eu-west-api.getstream.io/api"), AP_NORTH_EAST("https://ap-northeast-api.getstream.io/api"), AP_SOUTH_EAST("https://ap-southeast-api.getstream.io/api"), - LOCAL("http://localhost:8000/api"); + LOCAL_TEST("http://localhost:8089/api"); /* used for testing purpose only */ protected final static String VERSION = "v1.0"; diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/AddMany.java b/stream-core/src/main/java/io/getstream/client/model/beans/AddMany.java index a5cc1163..bf338396 100644 --- a/stream-core/src/main/java/io/getstream/client/model/beans/AddMany.java +++ b/stream-core/src/main/java/io/getstream/client/model/beans/AddMany.java @@ -6,7 +6,7 @@ import java.util.List; /** - * Helper bean to create a payload used for the add_to_many API call. + * Helper bean used to create a payload for the add_to_many API call. * @param Type of the activity */ public class AddMany { diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/FollowMany.java b/stream-core/src/main/java/io/getstream/client/model/beans/FollowMany.java index ce8219ac..4a3f746a 100644 --- a/stream-core/src/main/java/io/getstream/client/model/beans/FollowMany.java +++ b/stream-core/src/main/java/io/getstream/client/model/beans/FollowMany.java @@ -8,6 +8,9 @@ import java.util.List; +/** + * Helper bean used to create a payload for the follow_many API call. + */ public class FollowMany { @JsonSerialize(contentAs = FollowMany.Entry.class) diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 21756349..a8ce40f2 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -70,6 +70,17 @@ junit test + + org.mockito + mockito-core + test + + + com.github.tomakehurst + wiremock + standalone + test + diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index f4b633f8..3ea3142e 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -19,7 +19,6 @@ import io.getstream.client.service.FlatActivityServiceImpl; import io.getstream.client.service.NotificationActivityServiceImpl; import org.hamcrest.MatcherAssert; -//import org.junit.BeforeClass; import org.junit.BeforeClass; import org.junit.Test; diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/StreamClientImplTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/StreamClientImplTest.java new file mode 100644 index 00000000..eca042b0 --- /dev/null +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/StreamClientImplTest.java @@ -0,0 +1,38 @@ +package io.getstream.client.apache; + +import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.exception.InvalidFeedNameException; +import org.junit.Test; + +public class StreamClientImplTest { + + private static final String API_KEY = "apikey"; + private static final String API_SECRET = "secretkey"; + + private final StreamClientImpl streamClient; + + public StreamClientImplTest() { + ClientConfiguration clientConfiguration = new ClientConfiguration(); + streamClient = new StreamClientImpl(clientConfiguration, API_KEY, API_SECRET); + } + + @Test + public void shouldCreateNewFeed() throws Exception { + streamClient.newFeed("foo", "1"); + } + + @Test(expected = InvalidFeedNameException.class) + public void shouldFailCreatingNewFeed() throws Exception { + streamClient.newFeed("foo+bar", "1"); + } + + @Test(expected = InvalidFeedNameException.class) + public void shouldFailCreatingNewFeedAgain() throws Exception { + streamClient.newFeed("foo", "1+bar"); + } + + @Test + public void shouldShutdown() throws Exception { + streamClient.shutdown(); + } +} \ No newline at end of file diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java new file mode 100644 index 00000000..f2bdcbb9 --- /dev/null +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java @@ -0,0 +1,93 @@ +package io.getstream.client.apache.repo; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.tomakehurst.wiremock.client.RequestPatternBuilder; +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import io.getstream.client.StreamClient; +import io.getstream.client.apache.StreamClientImpl; +import io.getstream.client.config.AuthenticationHandlerConfiguration; +import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.config.StreamRegion; +import io.getstream.client.exception.InvalidFeedNameException; +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.SimpleActivity; +import io.getstream.client.model.beans.FollowMany; +import io.getstream.client.model.feeds.Feed; +import org.apache.http.impl.client.CloseableHttpClient; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.Result; + +import java.io.IOException; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.mock; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; + +public class StreamRepositoryImplTest { + + public static final String API_KEY = "nfq26m3qgfyp"; + public static final String API_SECRET = "245nvvjm49s3uwrs5e4h3gadsw34mnwste6v3rdnd69ztb35bqspvq8kfzt9v7h2"; + + @Rule + public WireMockRule wireMockRule = new WireMockRule(8089); // No-args constructor defaults to port 8080 + + private final StreamRepositoryImpl streamRepository; + + private final StreamClientImpl streamClient; + + public StreamRepositoryImplTest() { + ClientConfiguration clientConfiguration = new ClientConfiguration(); + clientConfiguration.setRegion(StreamRegion.LOCAL_TEST); + streamClient = new StreamClientImpl(clientConfiguration, API_KEY, API_SECRET); + streamRepository = new StreamRepositoryImpl(clientConfiguration, mock(CloseableHttpClient.class)); + } + + @Test + public void shouldNotFailWithExtraField() throws IOException { + String toParse = "{\"actor\":null,\"verb\":null,\"object\":null,\"target\":null,\"time\":null," + + "\"to\":[],\"foreign_id\":null,\"my_extra_field\":null}"; + + ObjectMapper objectMapper = streamRepository.getObjectMapper(); + SimpleActivity simpleActivity = objectMapper.readValue(toParse, SimpleActivity.class); + } + + @Test + public void shouldParseLowerCaseWithUnderscore() throws IOException { + String toParse = "{\"actor\":null,\"verb\":null,\"object\":null,\"target\":null,\"time\":null," + + "\"to\":[],\"foreign_id\":\"id\"}"; + + ObjectMapper objectMapper = streamRepository.getObjectMapper(); + SimpleActivity simpleActivity = objectMapper.readValue(toParse, SimpleActivity.class); + assertThat(simpleActivity.getForeignId(), is("id")); + } + + @Test + public void shouldFollowMany() throws StreamClientException, IOException { + stubFor(post(urlEqualTo("/api/v1.0/follow_many/?activity_copy_limit=300")) + .willReturn(aResponse() + .withStatus(201) + .withHeader("Content-Type", "application/json") + .withBody("{\"duration\": \"7ms\"}"))); + + Feed feed = streamClient.newFeed("user", "0"); + FollowMany followMany = new FollowMany.Builder() + .add("user:0", "user:1") + .add("user:0", "user:2") + .add("user:0", "user:3") + .build(); + feed.followMany(followMany); + + verify(postRequestedFor(urlEqualTo("/api/v1.0/follow_many/?activity_copy_limit=300")) + .withHeader("X-Api-Key", equalTo("nfq26m3qgfyp")) + .withHeader("Date", matching(".*")) + .withHeader("Authorization", containing("Signature keyId=\"nfq26m3qgfyp\",algorithm=\"hmac-sha256\",headers=\"date\"")) + .withRequestBody(containing("\"target\":\"user:1\"")) + .withRequestBody(containing("\"target\":\"user:2\"")) + .withRequestBody(containing("\"target\":\"user:3\"")) + ); + } + +} \ No newline at end of file diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/StreamClientImplTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/StreamClientImplTest.java new file mode 100644 index 00000000..88bf53b0 --- /dev/null +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/StreamClientImplTest.java @@ -0,0 +1,38 @@ +package io.getstream.client.okhttp; + +import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.exception.InvalidFeedNameException; +import org.junit.Test; + +public class StreamClientImplTest { + + private static final String API_KEY = "apikey"; + private static final String API_SECRET = "secretkey"; + + private final StreamClientImpl streamClient; + + public StreamClientImplTest() { + ClientConfiguration clientConfiguration = new ClientConfiguration(); + streamClient = new StreamClientImpl(clientConfiguration, API_KEY, API_SECRET); + } + + @Test + public void shouldCreateNewFeed() throws Exception { + streamClient.newFeed("foo", "1"); + } + + @Test(expected = InvalidFeedNameException.class) + public void shouldFailCreatingNewFeed() throws Exception { + streamClient.newFeed("foo+bar", "1"); + } + + @Test(expected = InvalidFeedNameException.class) + public void shouldFailCreatingNewFeedAgain() throws Exception { + streamClient.newFeed("foo", "1+bar"); + } + + @Test + public void shouldShutdown() throws Exception { + streamClient.shutdown(); + } +} \ No newline at end of file From c5aa07e8b52bb3882d72151f40bc666a1e3f3044 Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 2 Feb 2016 10:31:31 +0100 Subject: [PATCH 006/320] Disabled default execution of integration tests --- pom.xml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/pom.xml b/pom.xml index 8eed5654..cc0fa29e 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,9 @@ 1.0 4.11 1.10.19 + + true + false @@ -219,6 +222,38 @@ maven-release-plugin 2.5 + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + ${skipTests} + + **/IntegrationTest.java + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.19.1 + + ${skipTests} + ${skipITs} + + **/IntegrationTest.java + + + + + integration-test + + integration-test + verify + + + + From ff22e338e91739115af884f5b9f66b6ee6fb1055 Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 2 Feb 2016 11:00:14 +0100 Subject: [PATCH 007/320] [maven-release-plugin] prepare release stream-java-1.0 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index cc0fa29e..cd2477c9 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 0.1-RC6-SNAPSHOT + 1.0 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-1.0 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index a3cf7d0b..70e3356a 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 0.1-RC6-SNAPSHOT + 1.0 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index a8ce40f2..49410855 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 0.1-RC6-SNAPSHOT + 1.0 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 0a059efd..0df17e53 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 0.1-RC6-SNAPSHOT + 1.0 4.0.0 From f097ad5c7098f993ff0d7cc64bc3b9440d63494e Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 2 Feb 2016 11:00:18 +0100 Subject: [PATCH 008/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index cd2477c9..90280edc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.0 + 1.1-RC1-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-1.0 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 70e3356a..0ff6f668 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.0 + 1.1-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 49410855..4fd76b82 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.0 + 1.1-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 0df17e53..db213e68 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.0 + 1.1-RC1-SNAPSHOT 4.0.0 From 49d079fc7720ae1a2df6222426beb6f6e7bcc8a4 Mon Sep 17 00:00:00 2001 From: Tommaso Barbugli Date: Tue, 2 Feb 2016 11:05:07 +0100 Subject: [PATCH 009/320] add link to Sonatype snapshots --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf9bb344..bf441ff7 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Download the latest JAR or grab via Maven: ``` -Snapshots of the development version are available in Sonatype's snapshots repository. +Snapshots of the development version are available in [Sonatype](https://oss.sonatype.org/content/repositories/snapshots/io/getstream/client/) snapshots repository. ### Usage From 0639d6bd6e11fe09ca14e4f9524527e00a2162d7 Mon Sep 17 00:00:00 2001 From: alessandro Date: Thu, 11 Feb 2016 12:31:01 +0100 Subject: [PATCH 010/320] Updated README --- README.md | 118 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 84 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index bf441ff7..96d2818b 100644 --- a/README.md +++ b/README.md @@ -4,46 +4,86 @@ stream-java stream-java is a Java client for [Stream](https://getstream.io/). +The Stream's Java client come in two different flavours, you should decide which one to drag into your project. +Those two implementations differ according to the underlying library used to handle HTTP connections: + +- *stream-repo-apache* uses Apache HttpClient and we recommend it for backend applications. Apache HttpClient is a mature, reliable and rock-solid HTTP library. +- *stream-repo-okhttp* uses Square's OkHttp which is lightweight, powerful and mobile-oriented HTTP library. We recommend it for mobile application. ### Installation -Download the latest JAR or grab via Maven: +If you decide to go for the *Apache HttpClient* implementation, add the following dependency to your pom.xml: + +```xml + + io.getstream.client + stream-repo-apache + 1.0 + +``` + +or in your build.gradle: + +```gradle +compile 'io.getstream.client:stream-repo-apache:1.0' +``` + +Instead, if you opted out for the *OkHttp* implementation please add it to your pom.xml ```xml io.getstream.client stream-repo-okhttp - 0.1-RC2 + 1.0 ``` +or in your build.gradle: + +```gradle +compile 'io.getstream.client:stream-repo-okhttp:1.0' +``` + +In case you want to download the artifact and put it manually into your project, +you can download it from [here](https://github.com/GetStream/stream-java/releases). + Snapshots of the development version are available in [Sonatype](https://oss.sonatype.org/content/repositories/snapshots/io/getstream/client/) snapshots repository. ### Usage ```java -// Instantiate a new client to connect to us east API endpoint -// Find your API keys here https://getstream.io/dashboard/ +/** + * Instantiate a new client to connect to us east API endpoint + * Find your API keys here https://getstream.io/dashboard/ + **/ ClientConfiguration streamConfig = new ClientConfiguration().setRegion(StreamRegion.US_EAST); StreamClient streamClient = new StreamClientImpl(streamConfig, 'API_KEY', 'API_SECRET'); +``` -// Instantiate a feed object +#### Create a new Feed + +```java +/* Instantiate a feed object */ Feed feed = streamClient.newFeed("user", "1"); +``` -// Create an activity service +#### Working with Activities + +```java +/* Create an activity service */ FlatActivityServiceImpl flatActivityService = feed.newFlatActivityService(SimpleActivity.class); -// Get activities from 5 to 10 (using offset pagination) +/* Get activities from 5 to 10 (using offset pagination) */ FeedFilter filter = new FeedFilter.Builder().withLimit(5).withOffset(5).build(); List activities = flatActivityService.getActivities(filter).getResults(); -// Filter on an id less than the given UUID +/* Filter on an id less than the given UUID */ aid = "e561de8f-00f1-11e4-b400-0cc47a024be0"; FeedFilter filter = new FeedFilter.Builder().withIdLowerThan(aid).withLimit(5).build(); List activities = flatActivityService.getActivities(filter).getResults(); -// Create a new activity +/* Create a new activity */ SimpleActivity activity = new SimpleActivity(); activity.setActor("user:1"); activity.setObject("tweet:1"); @@ -52,25 +92,46 @@ activity.setForeignId("tweet:1"); SimpleActivity response = flatActivityService.addActivity(activity); ``` -The API client allows you to send activities with custom field as well, you can find a complete example [here](https://github.com/GetStream/stream-java/blob/master/stream-repo-apache/src/test/java/io/getstream/client/example/mixtype/MixedType.java) +In case you want to add a single activity to multiple feeds, you can use the batch feature _addToMany_: ```java -// Remove an activity by its id +/* Batch adding activities to many feeds */ +flatActivityService.addActivityToMany(ImmutableList.of("user:1", "user:2").asList(), myActivity); +``` + +The API client allows you to send activities with custom field as well, you can find a +complete example [here](https://github.com/GetStream/stream-java/blob/master/stream-repo-apache/src/test/java/io/getstream/client/example/mixtype/MixedType.java) + +```java +/* Remove an activity by its id */ feed.deleteActivity("e561de8f-00f1-11e4-b400-0cc47a024be0"); -// Remove activities by their foreign_id +/* Remove activities by their foreign_id */ feed.deleteActivityByForeignId("tweet:1"); +``` + +#### Follow and Unfollow -// Follow another feed +```java +/* Follow another feed */ feed.follow(flat", "42"); -// Stop following another feed +/* Stop following another feed */ feed.unfollow(flat", "42"); -// Batch adding activities to many feeds -flatActivityService.addActivityToMany(ImmutableList.of("user:1", "user:2").asList(), myActivity); +/* Retrieve first 10 followers of a feed */ +FeedFilter filter = new FeedFilter.Builder().withLimit(10).build(); +List followingPaged = feed.getFollowing(filter); + +/* Retrieve the first 10 followed feeds */ +FeedFilter filter = new FeedFilter.Builder().withLimit(10).build(); +List followingPaged = feed.getFollowing(filter); +``` + +In case you want to send to Stream a long list of following relationships you can use the batch feature _followMany_: -// Batch following many feeds +```java +/* Batch following many feeds */ FollowMany followMany = new FollowMany.Builder() .add("user:1", "user:2") .add("user:1", "user:3") @@ -79,26 +140,15 @@ FollowMany followMany = new FollowMany.Builder() .build(); feed.followMany(followMany); -// Add an activity and push it to other feeds too using the `to` field -// This is not supported yet - -// Remove a feed and its content -// This is not supported yet - -// Generating tokens for client side usage -String token = feed.getToken(); - -// Retrieve first 10 followers of a feed -FeedFilter filter = new FeedFilter.Builder().withLimit(10).build(); -List followingPaged = feed.getFollowing(filter); +``` -// Retrieve the first 10 followed feeds -FeedFilter filter = new FeedFilter.Builder().withLimit(10).build(); -List followingPaged = feed.getFollowing(filter); +#### Client token -// Check if specific feeds are followed -// This is not supported yet +In order to generate a token for client side usage (e.g. JS client), you can use the following code: +```java +/* Generating tokens for client side usage */ +String token = feed.getToken(); ``` For more examples have a look [here](https://github.com/GetStream/stream-java/tree/milestone1/stream-repo-apache/src/test/java/io/getstream/client/apache/example). From 79e498c3523a398527d52c886bbfc0fd62cdcc14 Mon Sep 17 00:00:00 2001 From: alessandro Date: Thu, 11 Feb 2016 12:32:31 +0100 Subject: [PATCH 011/320] Updated README --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 96d2818b..6e011447 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,12 @@ activity.setObject("tweet:1"); activity.setVerb("tweet"); activity.setForeignId("tweet:1"); SimpleActivity response = flatActivityService.addActivity(activity); + +/* Remove an activity by its id */ +feed.deleteActivity("e561de8f-00f1-11e4-b400-0cc47a024be0"); + +/* Remove activities by their foreign_id */ +feed.deleteActivityByForeignId("tweet:1"); ``` In case you want to add a single activity to multiple feeds, you can use the batch feature _addToMany_: @@ -102,14 +108,6 @@ flatActivityService.addActivityToMany(ImmutableList.of("user:1", "user:2 The API client allows you to send activities with custom field as well, you can find a complete example [here](https://github.com/GetStream/stream-java/blob/master/stream-repo-apache/src/test/java/io/getstream/client/example/mixtype/MixedType.java) -```java -/* Remove an activity by its id */ -feed.deleteActivity("e561de8f-00f1-11e4-b400-0cc47a024be0"); - -/* Remove activities by their foreign_id */ -feed.deleteActivityByForeignId("tweet:1"); -``` - #### Follow and Unfollow ```java From 8b4be385417a4854e178b54d11b11a0625daebe1 Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 5 Apr 2016 12:14:18 +0200 Subject: [PATCH 012/320] Added javadocs aggregator --- pom.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pom.xml b/pom.xml index 90280edc..d15eec5a 100644 --- a/pom.xml +++ b/pom.xml @@ -199,6 +199,20 @@ + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + aggregate + + aggregate + + site + + + org.sonatype.plugins nexus-staging-maven-plugin From 50eb89ae3910897cc04b33e1d19c532242680215 Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 6 Apr 2016 11:21:21 +0200 Subject: [PATCH 013/320] Added a shortcut to initialise client with a specific version --- .../client/config/ClientConfiguration.java | 16 ++++++++++++++++ .../client/apache/StreamClientImplTest.java | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java b/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java index 08272a07..403a6a4a 100644 --- a/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java +++ b/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java @@ -79,6 +79,22 @@ public class ClientConfiguration { private AuthenticationHandlerConfiguration authenticationHandlerConfiguration; + /** + * Default constructor. + */ + public ClientConfiguration() { + super(); + } + + /** + * Create a configuration using a given region. + * @param region Region + */ + public ClientConfiguration(final StreamRegion region) { + super(); + this.region = region; + } + /** * Create a ClientConfiguration bean from a given json string. * diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/StreamClientImplTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/StreamClientImplTest.java index eca042b0..1728de80 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/StreamClientImplTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/StreamClientImplTest.java @@ -1,9 +1,14 @@ package io.getstream.client.apache; +import io.getstream.client.StreamClient; import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.config.StreamRegion; import io.getstream.client.exception.InvalidFeedNameException; import org.junit.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsNull.notNullValue; + public class StreamClientImplTest { private static final String API_KEY = "apikey"; @@ -16,6 +21,13 @@ public StreamClientImplTest() { streamClient = new StreamClientImpl(clientConfiguration, API_KEY, API_SECRET); } + @Test + public void shouldCreateClientWithDifferentRegion() throws Exception { + StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(StreamRegion.LOCAL_TEST), + API_KEY, API_SECRET); + assertThat(streamClient, notNullValue()); + } + @Test public void shouldCreateNewFeed() throws Exception { streamClient.newFeed("foo", "1"); From 1d652be8e2760a105b08bd40b54db4046beeb2ac Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 6 Apr 2016 11:35:18 +0200 Subject: [PATCH 014/320] Added us-west region --- README.md | 7 +++++-- .../main/java/io/getstream/client/config/StreamRegion.java | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6e011447..7e8ae8b5 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,7 @@ Snapshots of the development version are available in [Sonatype](https://oss.son * Find your API keys here https://getstream.io/dashboard/ **/ -ClientConfiguration streamConfig = new ClientConfiguration().setRegion(StreamRegion.US_EAST); -StreamClient streamClient = new StreamClientImpl(streamConfig, 'API_KEY', 'API_SECRET'); +StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), "", ""); ``` #### Create a new Feed @@ -149,6 +148,10 @@ In order to generate a token for client side usage (e.g. JS client), you can use String token = feed.getToken(); ``` +#### Further references + For more examples have a look [here](https://github.com/GetStream/stream-java/tree/milestone1/stream-repo-apache/src/test/java/io/getstream/client/apache/example). Docs are available on [GetStream.io](http://getstream.io/docs/). + +Javadocs are available [here](https://getstream.github.io/stream-java/). \ No newline at end of file diff --git a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java index a5d431e2..bdb8d40f 100644 --- a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java +++ b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java @@ -41,6 +41,7 @@ public enum StreamRegion { US_EAST("https://us-east-api.getstream.io/api"), + US_WEST("https://us-west-api.getstream.io/api"), EU_WEST("https://eu-west-api.getstream.io/api"), AP_NORTH_EAST("https://ap-northeast-api.getstream.io/api"), AP_SOUTH_EAST("https://ap-southeast-api.getstream.io/api"), From c6482421ae8af418d961c317ecd851040dfcc19b Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 6 Apr 2016 13:00:30 +0200 Subject: [PATCH 015/320] [maven-release-plugin] prepare release 1.0.1 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index d15eec5a..261c5755 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.1-RC1-SNAPSHOT + 1.0.1 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + 1.0.1 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 0ff6f668..e2aa1393 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1-RC1-SNAPSHOT + 1.0.1 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 4fd76b82..924e690d 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1-RC1-SNAPSHOT + 1.0.1 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index db213e68..a5a6cc6d 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1-RC1-SNAPSHOT + 1.0.1 4.0.0 From ed0e52a61919931cfe2a073ee3a32a02e7c19deb Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 6 Apr 2016 13:00:34 +0200 Subject: [PATCH 016/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 261c5755..d15eec5a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.0.1 + 1.1-RC1-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - 1.0.1 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index e2aa1393..0ff6f668 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.0.1 + 1.1-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 924e690d..4fd76b82 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.0.1 + 1.1-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index a5a6cc6d..db213e68 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.0.1 + 1.1-RC1-SNAPSHOT 4.0.0 From f408e6f5b0fb0eb8f479971aab08c4cfecbb5cf0 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 6 Apr 2016 13:11:20 +0200 Subject: [PATCH 017/320] Update README.md Changed version number --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7e8ae8b5..b872d5b2 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 1.0 + 1.0.1 ``` @@ -34,7 +34,7 @@ Instead, if you opted out for the *OkHttp* implementation please add it to your io.getstream.client stream-repo-okhttp - 1.0 + 1.0.1 ``` @@ -154,4 +154,4 @@ For more examples have a look [here](https://github.com/GetStream/stream-java/tr Docs are available on [GetStream.io](http://getstream.io/docs/). -Javadocs are available [here](https://getstream.github.io/stream-java/). \ No newline at end of file +Javadocs are available [here](https://getstream.github.io/stream-java/). From 7f081771527381b08763905cdf180c8594082ec6 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 6 Apr 2016 13:11:55 +0200 Subject: [PATCH 018/320] Update README.md Changed version number --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b872d5b2..ad7f22b3 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:1.0' +compile 'io.getstream.client:stream-repo-apache:1.0.1' ``` Instead, if you opted out for the *OkHttp* implementation please add it to your pom.xml @@ -41,7 +41,7 @@ Instead, if you opted out for the *OkHttp* implementation please add it to your or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:1.0' +compile 'io.getstream.client:stream-repo-okhttp:1.0.1' ``` In case you want to download the artifact and put it manually into your project, From c511f54664924d013dc5438c09d1652476f92754 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 6 Apr 2016 13:12:30 +0200 Subject: [PATCH 019/320] Update README.md corrected --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad7f22b3..de6510cd 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ or in your build.gradle: compile 'io.getstream.client:stream-repo-apache:1.0.1' ``` -Instead, if you opted out for the *OkHttp* implementation please add it to your pom.xml +Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml ```xml From a1cae73ceb9215480f6c09409f8aa4368977f1e8 Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 27 May 2016 11:38:54 +0200 Subject: [PATCH 020/320] Created request entity using a Byte arrays instead of a String --- pom.xml | 6 ++ stream-core/pom.xml | 4 ++ .../client/repo/StreamRepository.java | 12 ++++ .../service/AbstractActivityService.java | 15 +++++ .../client/util/JwtAuthenticationUtil.java | 39 ++++++++++++ .../util/JwtAuthenticationUtilTest.java | 63 +++++++++++++++++++ .../apache/repo/StreamActivityRepository.java | 19 +++--- 7 files changed, 147 insertions(+), 11 deletions(-) create mode 100644 stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java create mode 100644 stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java diff --git a/pom.xml b/pom.xml index d15eec5a..62054eba 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,7 @@ 1.0 4.11 1.10.19 + 2.1.0 true false @@ -104,6 +105,11 @@ tomitribe-http-signatures ${tomitribe-http-signatures.version} + + com.auth0 + java-jwt + ${java-jwt.version} + diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 0ff6f668..9eaaef31 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -53,6 +53,10 @@ org.tomitribe tomitribe-http-signatures + + com.auth0 + java-jwt + diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java index bef1133b..b8837a8f 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java @@ -147,6 +147,18 @@ public interface StreamRepository { */ T addActivity(BaseFeed feed, T activity) throws StreamClientException, IOException; + /** + * Update activities (foreignId and time are mandatory fields). + * Please refer to GetStream.io/docs for more info. + * @param feed Feed which the activities belong to + * @param activities List of activities to update + * @param Subtype of {@link BaseActivity} representing the activity type to handle. + * @return Operation response + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + StreamResponse updateActivities(BaseFeed feed, List activities) throws IOException, StreamClientException; + /** * Add a new activity of type {@link T} to multiple feeds. * diff --git a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java index e36a9cd6..2f3c871a 100644 --- a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java +++ b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java @@ -32,6 +32,7 @@ import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.BaseActivity; +import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.repo.StreamRepository; @@ -68,6 +69,20 @@ public T addActivity(T activity) throws IOException, StreamClientException { return streamRepository.addActivity(this.feed, activity); } + /** + * Add a new activity of type {@link T}. + * + * @param activities List of activities to update + * @return Response activity of type {@link T} coming from the server.
+ * The returning activity in the 'to' field contains the targetFeedId along + * with its signature (e.g: 'user:1 6mQhuzQ79e0rZ17bSq1CCxXoRac') + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + public StreamResponse updateActivities(List activities) throws IOException, StreamClientException { + return streamRepository.updateActivities(this.feed, activities); + } + /** * Add a new activity of type {@link T} to multiple feeds. * diff --git a/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java b/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java new file mode 100644 index 00000000..be95f8f0 --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java @@ -0,0 +1,39 @@ +package io.getstream.client.util; + +import com.auth0.jwt.Algorithm; +import com.auth0.jwt.JWTSigner; + +import java.util.HashMap; + +/** + * Utility class to generate a JWT token. + */ +public class JwtAuthenticationUtil { + + /** + * A convenient way to indicate the 'all' quantifier. + */ + public final static String ALL = "*"; + + /** + * Generate JWT token. + * @param secretKey API Secret + * @param action Action to be performed + * @param resource Target resource + * @param feedId FeedId (if null it will not be added to the payload) + * @param userId UserId (if null it will not be added to the payload) + * @return Token string + */ + public static String generateToken(final String secretKey, final String action, final String resource, final String feedId, final String userId) { + HashMap claims = new HashMap(); + claims.put("action", action); + claims.put("resource", resource); + if (null != feedId) { + claims.put("feed_id", feedId); + } + if (null != userId) { + claims.put("user_id", userId); + } + return new JWTSigner(secretKey).sign(claims, new JWTSigner.Options().setAlgorithm(Algorithm.HS256)); + } +} diff --git a/stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java b/stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java new file mode 100644 index 00000000..629d398d --- /dev/null +++ b/stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java @@ -0,0 +1,63 @@ +package io.getstream.client.util; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +public class JwtAuthenticationUtilTest { + + private static final String SECRET_KEY = "245nvvjm49s3uwrs5e4h3gadsw34mnwste6v3rdnd69ztb35bqspvq8kfzt9v7h2"; + + @Test + public void testGenerateToken() throws Exception { + assertThat(JwtAuthenticationUtil.generateToken( + SECRET_KEY, + "activities", + "myResource", + null, + null), + is("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3Rpb24iOiJhY3Rpdml0aWVzIiwicmVzb3VyY2UiOi" + + "JteVJlc291cmNlIn0.zLHVXhkZWK_VTpX_iHxyg_pjQBVSgBKkeSGpP8W6zF0") + ); + } + + @Test + public void testGenerateTokenWithFeedId() throws Exception { + assertThat(JwtAuthenticationUtil.generateToken( + SECRET_KEY, + "activities", + JwtAuthenticationUtil.ALL, + "feed1", + null), + is("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3Rpb24iOiJhY3Rpdml0aWVzIiwicmVzb3VyY2UiOiIq" + + "IiwiZmVlZF9pZCI6ImZlZWQxIn0.uBBDb91Lo-D9k9LQY-nK1nXMYjcwgQ4MWao69s4unRI") + ); + } + + @Test + public void testGenerateTokenWithUserId() throws Exception { + assertThat(JwtAuthenticationUtil.generateToken( + SECRET_KEY, + "activities", + JwtAuthenticationUtil.ALL, + null, + "userId1"), + is("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3Rpb24iOiJhY3Rpdml0aWVzIiwicmVzb3VyY2UiOiIqIi" + + "widXNlcl9pZCI6InVzZXJJZDEifQ.Ssr60hHaffWZ7TKj69bb7f5kxZ1b0K56GUAj_2tpkgg") + ); + } + + @Test + public void testGenerateTokenWithFeedAndUserId() throws Exception { + assertThat(JwtAuthenticationUtil.generateToken( + SECRET_KEY, + "activities", + "myResource", + "feedId", + "userId"), + is("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3Rpb24iOiJhY3Rpdml0aWVzIiwicmVzb3VyY2UiOiJteVJl" + + "c291cmNlIiwidXNlcl9pZCI6InVzZXJJZCIsImZlZWRfaWQiOiJmZWVkSWQifQ.A7Qv7dmj3EwoZ93YBWKidRi9BLVikxpwfspGO0IccPU") + ); + } +} \ No newline at end of file diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java index 5b101839..eb540507 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java @@ -31,41 +31,38 @@ package io.getstream.client.apache.repo; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.ImmutableList; +import io.getstream.client.apache.repo.handlers.StreamExceptionHandler; +import io.getstream.client.apache.repo.utils.SignatureUtils; +import io.getstream.client.apache.repo.utils.StreamRepoUtils; +import io.getstream.client.apache.repo.utils.UriBuilder; import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.NotificationActivity; import io.getstream.client.model.beans.AddMany; -import io.getstream.client.model.feeds.BaseFeed; -import io.getstream.client.apache.repo.handlers.StreamExceptionHandler; -import io.getstream.client.apache.repo.utils.SignatureUtils; import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; -import io.getstream.client.apache.repo.utils.StreamRepoUtils; -import io.getstream.client.apache.repo.utils.UriBuilder; import io.getstream.client.util.HttpSignatureHandler; -import org.apache.http.NameValuePair; -import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.message.BasicNameValuePair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URI; import java.util.List; import static io.getstream.client.apache.repo.utils.FeedFilterUtils.apply; -import static org.apache.http.entity.ContentType.APPLICATION_FORM_URLENCODED; import static org.apache.http.entity.ContentType.APPLICATION_JSON; public class StreamActivityRepository { @@ -97,7 +94,7 @@ public T addActivity(BaseFeed feed, T activity) throws SignatureUtils.addSignatureToRecipients(secretKey, activity); - request.setEntity(new StringEntity(objectMapper.writeValueAsString(activity), APPLICATION_JSON)); + request.setEntity(new InputStreamEntity(new ByteArrayInputStream(objectMapper.writeValueAsBytes(activity)), APPLICATION_JSON)); try (CloseableHttpResponse response = httpClient.execute(addAuthentication(feed, request), HttpClientContext.create())) { handleResponseCode(response); return objectMapper.readValue(response.getEntity().getContent(), From 1163c1a5be4f73594002fafb846d0c8a3a123e04 Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 27 May 2016 18:40:03 +0200 Subject: [PATCH 021/320] Added updateActivities and addActivities --- .../client/repo/StreamRepository.java | 12 +++ .../service/AbstractActivityService.java | 14 +++ .../apache/repo/StreamActivityRepository.java | 47 +++++++++ .../apache/repo/StreamRepositoryImpl.java | 10 ++ .../apache/repo/utils/StreamRepoUtils.java | 19 +++- .../client/apache/IntegrationTest.java | 71 ++++++++++++-- .../repo/utils/StreamRepoUtilsTest.java | 53 ++++++++++ stream-repo-okhttp/pom.xml | 5 + .../okhttp/repo/StreamActivityRepository.java | 58 ++++++++++- .../okhttp/repo/StreamRepositoryImpl.java | 10 ++ .../okhttp/repo/utils/StreamRepoUtils.java | 15 +++ .../client/okhttp/IntegrationTest.java | 97 ++++++++++++++----- .../repo/utils/StreamRepoUtilsTest.java | 52 ++++++++++ 13 files changed, 421 insertions(+), 42 deletions(-) create mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/repo/utils/StreamRepoUtilsTest.java create mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtilsTest.java diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java index b8837a8f..ad9179b5 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java @@ -147,6 +147,18 @@ public interface StreamRepository { */ T addActivity(BaseFeed feed, T activity) throws StreamClientException, IOException; + /** + * Add a new list of activities to the given feed. + * + * @param feed Feed which the activities belong to + * @param activities List of activities to add + * @param Subtype of {@link BaseActivity} representing the activity type to handle. + * @return Activity as returned by the Stream server + * @throws StreamClientException in case of functional or server-side exception + * @throws IOException in case of network/socket exceptions + */ + StreamResponse addActivities(BaseFeed feed, List activities) throws StreamClientException, IOException; + /** * Update activities (foreignId and time are mandatory fields). * Please refer to GetStream.io/docs for more info. diff --git a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java index 2f3c871a..778ef3cf 100644 --- a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java +++ b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java @@ -69,6 +69,20 @@ public T addActivity(T activity) throws IOException, StreamClientException { return streamRepository.addActivity(this.feed, activity); } + /** + * Add a new activity of type {@link T}. + * + * @param activities List of Activities to add. + * @return Response activity of type {@link T} coming from the server.
+ * The returning activity in the 'to' field contains the targetFeedId along + * with its signature (e.g: 'user:1 6mQhuzQ79e0rZ17bSq1CCxXoRac') + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + public StreamResponse addActivities(List activities) throws IOException, StreamClientException { + return streamRepository.addActivities(this.feed, activities); + } + /** * Add a new activity of type {@link T}. * diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java index eb540507..332b568a 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java @@ -31,6 +31,7 @@ package io.getstream.client.apache.repo; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.reflect.TypeToken; import io.getstream.client.apache.repo.handlers.StreamExceptionHandler; import io.getstream.client.apache.repo.utils.SignatureUtils; import io.getstream.client.apache.repo.utils.StreamRepoUtils; @@ -39,6 +40,7 @@ import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.NotificationActivity; +import io.getstream.client.model.activities.SimpleActivity; import io.getstream.client.model.beans.AddMany; import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamResponse; @@ -60,9 +62,12 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URI; +import java.util.Collections; import java.util.List; import static io.getstream.client.apache.repo.utils.FeedFilterUtils.apply; +import static io.getstream.client.util.JwtAuthenticationUtil.ALL; +import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; import static org.apache.http.entity.ContentType.APPLICATION_JSON; public class StreamActivityRepository { @@ -102,6 +107,28 @@ public T addActivity(BaseFeed feed, T activity) throws } } + public StreamResponse addActivities(BaseFeed feed, List activities) throws StreamClientException, IOException { + HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) + .path("feed").path(feed.getFeedSlug()).path(feed.getUserId() + "/") + .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build()); + LOG.debug("Invoking url: '{}'", request.getURI()); + + Class clazz = SimpleActivity.class; + for (T activity : activities) { + SignatureUtils.addSignatureToRecipients(secretKey, activity); + clazz = activity.getClass(); + System.out.println(clazz); + } + + request.setEntity(new InputStreamEntity(new ByteArrayInputStream( + objectMapper.writeValueAsBytes(Collections.singletonMap("activities", activities))), APPLICATION_JSON)); + try (CloseableHttpResponse response = httpClient.execute(addAuthentication(feed, request), HttpClientContext.create())) { + handleResponseCode(response); + return objectMapper.readValue(response.getEntity().getContent(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, clazz)); + } + } + public T addToMany(List targetIds, T activity) throws StreamClientException, IOException { HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) .path("feed") @@ -214,6 +241,26 @@ public void deleteActivityByForeignId(BaseFeed feed, String activityId) throws I } } + public StreamResponse updateActivities(BaseFeed feed, List activities) throws StreamClientException, IOException { + HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) + .path("activities/") + .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build()); + LOG.debug("Invoking url: '{}'", request.getURI()); + + + request.setEntity(new InputStreamEntity( + new ByteArrayInputStream(objectMapper.writeValueAsBytes(Collections.singletonMap("activities", activities))), + APPLICATION_JSON) + ); + + request = StreamRepoUtils.addJwtAuthentication(generateToken(secretKey, "activities", ALL, ALL, null), request); + + try (CloseableHttpResponse response = httpClient.execute(request, HttpClientContext.create())) { + handleResponseCode(response); + return objectMapper.readValue(response.getEntity().getContent(), StreamResponse.class); + } + } + private HttpRequestBase addAuthentication(BaseFeed feed, HttpRequestBase request) { return StreamRepoUtils.addAuthentication(feed, secretKey, request); } diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index 36c330e1..48f5686b 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -190,6 +190,16 @@ public T addActivity(BaseFeed feed, T activity) throws return streamActivityRepository.addActivity(feed, activity); } + @Override + public StreamResponse addActivities(BaseFeed feed, List activities) throws StreamClientException, IOException { + return streamActivityRepository.addActivities(feed, activities); + } + + @Override + public StreamResponse updateActivities(BaseFeed feed, List activities) throws StreamClientException, IOException { + return streamActivityRepository.updateActivities(feed, activities); + } + @Override public T addActivityToMany(List targetIds, T activity) throws StreamClientException, IOException { return streamActivityRepository.addToMany(targetIds, activity); diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java index 94fc25e9..d89e3fdf 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java @@ -31,6 +31,7 @@ package io.getstream.client.apache.repo.utils; import io.getstream.client.model.feeds.BaseFeed; +import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import java.io.UnsupportedEncodingException; @@ -43,6 +44,9 @@ */ public class StreamRepoUtils { + private static final String HEADER_AUTHORIZATION = "Authorization"; + private static final String HEADER_AUTH_TYPE = "stream-auth-type"; + private StreamRepoUtils() { throw new AssertionError(); } @@ -56,7 +60,7 @@ private StreamRepoUtils() { * @return Request with the Authorization header. */ public static HttpRequestBase addAuthentication(BaseFeed feed, String secretKey, HttpRequestBase httpRequest) { - httpRequest.addHeader("Authorization", createFeedSignature(feed, secretKey)); + httpRequest.addHeader(HEADER_AUTHORIZATION, createFeedSignature(feed, secretKey)); return httpRequest; } @@ -86,4 +90,17 @@ public static String createFeedSignature(BaseFeed feed, String secretKey){ String token = createFeedToken(feed, secretKey); return String.format("%s %s", feed.getFeedId(), token); } + + + /** + * Add authentication headers to the request using the JWT authentication type. + * @param token JWT token + * @param request Outgoing request + * @return The same request with authentication headers. + */ + public static HttpPost addJwtAuthentication(String token, HttpPost request) { + request.addHeader(HEADER_AUTHORIZATION, token); + request.addHeader(HEADER_AUTH_TYPE, "jwt"); + return request; + } } diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index 3ea3142e..7bf94418 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -23,7 +23,10 @@ import org.junit.Test; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; @@ -32,8 +35,8 @@ public class IntegrationTest { - public static final String API_KEY = "nfq26m3qgfyp"; - public static final String API_SECRET = "245nvvjm49s3uwrs5e4h3gadsw34mnwste6v3rdnd69ztb35bqspvq8kfzt9v7h2"; + public static final String API_KEY = "zdwbqmpxmgh5"; + public static final String API_SECRET = "myjspevsc7rh7abz7n27q3emxrtgqnuuhgdx2767qrr9p4wresyw38hsbmz82tbx"; @BeforeClass public static void setLog() { @@ -207,10 +210,59 @@ public void shouldAddActivity() throws IOException, StreamClientException { activity.setObject("object"); activity.setTarget("target"); activity.setVerb("verb"); + activity.setForeignId("foreign1"); flatActivityService.addActivity(activity); streamClient.shutdown(); } + @Test + public void shouldAddActivities() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + API_SECRET); + + String userId = this.getTestUserId("shouldAddActivity"); + Feed feed = streamClient.newFeed("user", userId); + FlatActivityServiceImpl flatActivityService = feed.newFlatActivityService(SimpleActivity.class); + SimpleActivity activity = new SimpleActivity(); + activity.setActor("actor"); + activity.setObject("object"); + activity.setTarget("target"); + activity.setVerb("verb"); + activity.setForeignId("foreign1"); + + SimpleActivity activity2 = new SimpleActivity(); + activity2.setActor("actor"); + activity2.setObject("object"); + activity2.setTarget("target"); + activity2.setVerb("verb"); + activity2.setForeignId("foreign2"); + + List listToAdd = new ArrayList<>(); + listToAdd.add(activity); + listToAdd.add(activity2); + flatActivityService.addActivities(listToAdd); + streamClient.shutdown(); + } + + @Test + public void shouldUpdateActivity() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + API_SECRET); + + String userId = this.getTestUserId("shouldAddActivity"); + Feed feed = streamClient.newFeed("user", userId); + FlatActivityServiceImpl flatActivityService = feed.newFlatActivityService(SimpleActivity.class); + SimpleActivity activity = new SimpleActivity(); + activity.setActor("actor"); + activity.setObject("object"); + activity.setTarget("target"); + activity.setTime(new Date()); + activity.setForeignId("foreign1"); + activity.setVerb("verb"); + flatActivityService.updateActivities(Collections.singletonList(activity)); + streamClient.shutdown(); + } + @Test public void shouldAddActivityToMany() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, @@ -539,24 +591,23 @@ public void shouldGetActivitiesFromNotificationFeedAndMarkThemById() throws IOEx activity.setTarget("target"); activity.setVerb("like"); notificationActivityService.addActivity(activity); - activity.setVerb("dislike"); - notificationActivityService.addActivity(activity); + StreamResponse> responseAfter = notificationActivityService.getActivities(); - assertThat((int)responseAfter.getUnread(), is(2)); - assertThat((int) responseAfter.getUnseen(), is(2)); + assertThat((int)responseAfter.getUnread(), is(1)); + assertThat((int)responseAfter.getUnseen(), is(1)); String aid = responseAfter.getResults().get(0).getId(); MarkedActivity marker = new MarkedActivity.Builder().withActivityId(aid).build(); StreamResponse> responseAfterMark = notificationActivityService.getActivities(new FeedFilter.Builder().build(), marker, new MarkedActivity.Builder().build()); - assertThat((int)responseAfterMark.getUnread(), is(1)); - assertThat((int)responseAfterMark.getUnseen(), is(2)); + assertThat((int)responseAfterMark.getUnread(), is(0)); + assertThat((int)responseAfterMark.getUnseen(), is(1)); StreamResponse> responseAfterMark2 = notificationActivityService.getActivities(new FeedFilter.Builder().build(), new MarkedActivity.Builder().build(), marker); - assertThat((int)responseAfterMark2.getUnread(), is(1)); - assertThat((int)responseAfterMark2.getUnseen(), is(1)); + assertThat((int)responseAfterMark2.getUnread(), is(0)); + assertThat((int)responseAfterMark2.getUnseen(), is(0)); streamClient.shutdown(); } diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/utils/StreamRepoUtilsTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/utils/StreamRepoUtilsTest.java new file mode 100644 index 00000000..afe94d2a --- /dev/null +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/utils/StreamRepoUtilsTest.java @@ -0,0 +1,53 @@ +package io.getstream.client.apache.repo.utils; + +import io.getstream.client.model.feeds.BaseFeed; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; + +public class StreamRepoUtilsTest { + + private static final String API_SECRET = "4vknf33hn4n94exgrg367jbmg4jxetem93bqcg3nkdf2xau3q8pmy3pftytq4w8v"; + + private BaseFeed feed; + + @Before + public void init() { + this.feed = mock(BaseFeed.class); + when(this.feed.getFeedId()).thenReturn("id"); + } + + @Test + public void shouldAddAuthentication() throws Exception { + HttpRequestBase request = mock(HttpRequestBase.class); + String signature = StreamRepoUtils.createFeedSignature(feed, API_SECRET); + + StreamRepoUtils.addAuthentication(feed, API_SECRET, request); + verify(request).addHeader(eq("Authorization"), eq(signature)); + } + + @Test + public void shouldCreateFeedToken() throws Exception { + assertThat(StreamRepoUtils.createFeedToken(feed, API_SECRET), is("0DayILmfWZ4i8h6WHFUV0diDXOg")); + } + + @Test + public void shouldCreateFeedSignature() throws Exception { + assertThat(StreamRepoUtils.createFeedSignature(feed, API_SECRET), is("id 0DayILmfWZ4i8h6WHFUV0diDXOg")); + } + + @Test + public void shouldAddJwtAuthentication() throws Exception { + HttpPost request = mock(HttpPost.class); + + StreamRepoUtils.addJwtAuthentication("token", request); + verify(request).addHeader(eq("Authorization"), eq("token")); + verify(request).addHeader(eq("stream-auth-type"), eq("jwt")); + } +} \ No newline at end of file diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index db213e68..f7fb3633 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -70,6 +70,11 @@ junit test
+ + org.mockito + mockito-core + test + diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java index 18f33dfa..01281a11 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java @@ -30,11 +30,6 @@ */ package io.getstream.client.okhttp.repo; -import io.getstream.client.model.beans.AddMany; -import io.getstream.client.okhttp.repo.handlers.StreamExceptionHandler; -import io.getstream.client.okhttp.repo.utils.SignatureUtils; -import io.getstream.client.okhttp.repo.utils.StreamRepoUtils; -import io.getstream.client.okhttp.repo.utils.UriBuilder; import com.fasterxml.jackson.databind.ObjectMapper; import com.squareup.okhttp.MediaType; import com.squareup.okhttp.OkHttpClient; @@ -45,19 +40,29 @@ import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.NotificationActivity; +import io.getstream.client.model.activities.SimpleActivity; +import io.getstream.client.model.beans.AddMany; import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; +import io.getstream.client.okhttp.repo.handlers.StreamExceptionHandler; import io.getstream.client.okhttp.repo.utils.FeedFilterUtils; +import io.getstream.client.okhttp.repo.utils.SignatureUtils; +import io.getstream.client.okhttp.repo.utils.StreamRepoUtils; +import io.getstream.client.okhttp.repo.utils.UriBuilder; import io.getstream.client.util.HttpSignatureHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URI; +import java.util.Collections; import java.util.List; +import static io.getstream.client.util.JwtAuthenticationUtil.ALL; +import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; + public class StreamActivityRepository { private static final Logger LOG = LoggerFactory.getLogger(StreamActivityRepository.class); @@ -98,6 +103,30 @@ public T addActivity(BaseFeed feed, T activity) throws objectMapper.getTypeFactory().constructType(activity.getClass())); } + public StreamResponse addActivities(BaseFeed feed, List activities) throws StreamClientException, IOException { + Request.Builder requestBuilder = new Request.Builder().url(UriBuilder.fromEndpoint(baseEndpoint) + .path("feed").path(feed.getFeedSlug()).path(feed.getUserId() + "/") + .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build().toURL()); + + Class clazz = SimpleActivity.class; + for (T activity : activities) { + SignatureUtils.addSignatureToRecipients(secretKey, activity); + clazz = activity.getClass(); + System.out.println(clazz); + } + + requestBuilder.post(RequestBody.create(MediaType.parse(APPLICATION_JSON), + objectMapper.writeValueAsString(Collections.singletonMap("activities", activities)))); + + Request request = addAuthentication(feed, requestBuilder).build(); + LOG.debug("Invoking url: '{}", request.urlString()); + + Response response = httpClient.newCall(request).execute(); + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, clazz)); + } + public T addToMany(List targetIds, T activity) throws StreamClientException, IOException { Request.Builder requestBuilder = new Request.Builder().url(UriBuilder.fromEndpoint(baseEndpoint) .path("feed") @@ -223,6 +252,25 @@ public void deleteActivityByForeignId(BaseFeed feed, String activityId) throws I handleResponseCode(response); } + public StreamResponse updateActivities(BaseFeed feed, List activities) throws IOException, StreamClientException { + Request.Builder requestBuilder = new Request.Builder().delete().url(UriBuilder.fromEndpoint(baseEndpoint) + .path("activities/") + .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build().toURL()); + + requestBuilder.post(RequestBody.create(MediaType.parse(APPLICATION_JSON), + objectMapper.writeValueAsBytes(Collections.singletonMap("activities", activities)))); + + Request request = StreamRepoUtils.addJwtAuthentication( + generateToken(secretKey, "activities", ALL, ALL, null), + requestBuilder).build(); + + LOG.debug("Invoking url: '{}", request.urlString()); + + Response response = httpClient.newCall(request).execute(); + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), StreamResponse.class); + } + private void handleResponseCode(Response response) throws StreamClientException, IOException { exceptionHandler.handleResponseCode(response); } diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index 03fc211e..fcb2a4c6 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -196,6 +196,16 @@ public T addActivity(BaseFeed feed, T activity) throws return streamActivityRepository.addActivity(feed, activity); } + @Override + public StreamResponse addActivities(BaseFeed feed, List activities) throws IOException, StreamClientException { + return streamActivityRepository.addActivities(feed, activities); + } + + @Override + public StreamResponse updateActivities(BaseFeed feed, List activities) throws IOException, StreamClientException { + return streamActivityRepository.updateActivities(feed, activities); + } + @Override public T addActivityToMany(List targetIds, T activity) throws StreamClientException, IOException { return streamActivityRepository.addToMany(targetIds, activity); diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java index 7c04d915..6a95ef84 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java @@ -43,6 +43,9 @@ */ public class StreamRepoUtils { + private static final String HEADER_AUTHORIZATION = "Authorization"; + private static final String HEADER_AUTH_TYPE = "stream-auth-type"; + private StreamRepoUtils() { throw new AssertionError(); } @@ -86,4 +89,16 @@ public static String createFeedSignature(BaseFeed feed, String secretKey){ String token = createFeedToken(feed, secretKey); return String.format("%s %s", feed.getFeedId(), token); } + + /** + * Add authentication headers to the request using the JWT authentication type. + * @param token JWT token + * @param requestBuilder Outgoing request builder + * @return The same request with authentication headers. + */ + public static Request.Builder addJwtAuthentication(String token, Request.Builder requestBuilder) { + requestBuilder.addHeader(HEADER_AUTHORIZATION, token); + requestBuilder.addHeader(HEADER_AUTH_TYPE, "jwt"); + return requestBuilder; + } } diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index d4ce22e2..636df653 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -22,7 +22,9 @@ import org.junit.Test; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; @@ -34,15 +36,8 @@ public class IntegrationTest { - public static final String API_KEY = "nfq26m3qgfyp"; - public static final String API_SECRET = "245nvvjm49s3uwrs5e4h3gadsw34mnwste6v3rdnd69ztb35bqspvq8kfzt9v7h2"; - - // @BeforeClass - public static void setLog() { - System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); - System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); - System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "DEBUG"); - } + public static final String API_KEY = "aygdeg2vhjxg"; + public static final String API_SECRET = "4vknf33hn4n94exgrg367jbmg4jxetem93bqcg3nkdf2xau3q8pmy3pftytq4w8v"; public String getTestUserId(String userId) { long millis = System.currentTimeMillis(); @@ -231,6 +226,54 @@ public void shouldAddActivity() throws IOException, StreamClientException { streamClient.shutdown(); } + @Test + public void shouldAddActivities() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + API_SECRET); + + String userId = this.getTestUserId("shouldAddActivity"); + Feed feed = streamClient.newFeed("user", userId); + FlatActivityServiceImpl flatActivityService = feed.newFlatActivityService(SimpleActivity.class); + SimpleActivity activity = new SimpleActivity(); + activity.setActor("actor"); + activity.setObject("object"); + activity.setTarget("target"); + activity.setVerb("verb"); + activity.setForeignId("foreign1"); + + SimpleActivity activity2 = new SimpleActivity(); + activity2.setActor("actor"); + activity2.setObject("object"); + activity2.setTarget("target"); + activity2.setVerb("verb"); + activity2.setForeignId("foreign2"); + + List listToAdd = new ArrayList<>(); + listToAdd.add(activity); + listToAdd.add(activity2); + flatActivityService.addActivities(listToAdd); + streamClient.shutdown(); + } + + @Test + public void shouldUpdateActivity() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + API_SECRET); + + String userId = this.getTestUserId("shouldAddActivity"); + Feed feed = streamClient.newFeed("user", userId); + FlatActivityServiceImpl flatActivityService = feed.newFlatActivityService(SimpleActivity.class); + SimpleActivity activity = new SimpleActivity(); + activity.setActor("actor"); + activity.setObject("object"); + activity.setTarget("target"); + activity.setTime(new Date()); + activity.setForeignId("foreign1"); + activity.setVerb("verb"); + flatActivityService.updateActivities(Collections.singletonList(activity)); + streamClient.shutdown(); + } + @Test public void shouldAddActivityToMany() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, @@ -291,7 +334,7 @@ public void shouldAddAndRetrieveActivity() throws IOException, StreamClientExcep } @Test - public void shouldAddAndRetrieveActivityToRecipients() throws IOException, StreamClientException { + public void shouldAddAndRetrieveActivityToRecipients() throws IOException, StreamClientException, InterruptedException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddAndRetrieveActivityToRecipients"); @@ -306,12 +349,17 @@ public void shouldAddAndRetrieveActivityToRecipients() throws IOException, Strea activity.setTarget("target"); activity.setTo(Arrays.asList(String.format("user:%s", recipientId1), String.format("user:%s", recipientId2))); activity.setVerb("verb"); + List firstRequest = flatActivityService.getActivities().getResults(); assertThat(firstRequest.size(), is(0)); flatActivityService.addActivity(activity); + List secondRequest = flatActivityService.getActivities().getResults(); assertThat(secondRequest.size(), is(1)); + /* needed to bypass the lock on backend side */ + Thread.sleep(3500); + // retrieve the list of activities from the other 2 feeds too Feed feedRecipient1 = streamClient.newFeed("user", recipientId1); FlatActivityServiceImpl flatActivityService1 = feedRecipient1.newFlatActivityService(SimpleActivity.class); @@ -556,31 +604,31 @@ public void shouldGetActivitiesFromNotificationFeedAndMarkThemById() throws IOEx StreamResponse> response = notificationActivityService.getActivities(); assertThat((int)response.getUnread(), is(0)); - assertThat((int) response.getUnseen(), is(0)); + assertThat((int)response.getUnseen(), is(0)); SimpleActivity activity = new SimpleActivity(); activity.setActor("actor"); activity.setObject("object"); activity.setTarget("target"); activity.setVerb("like"); + notificationActivityService.addActivity(activity); - activity.setVerb("dislike"); - notificationActivityService.addActivity(activity); + StreamResponse> responseAfter = notificationActivityService.getActivities(); - assertThat((int)responseAfter.getUnread(), is(2)); - assertThat((int) responseAfter.getUnseen(), is(2)); + assertThat((int)responseAfter.getUnread(), is(1)); + assertThat((int)responseAfter.getUnseen(), is(1)); String aid = responseAfter.getResults().get(0).getId(); MarkedActivity marker = new MarkedActivity.Builder().withActivityId(aid).build(); StreamResponse> responseAfterMark = notificationActivityService.getActivities(new FeedFilter.Builder().build(), marker, new MarkedActivity.Builder().build()); - assertThat((int)responseAfterMark.getUnread(), is(1)); - assertThat((int)responseAfterMark.getUnseen(), is(2)); + assertThat((int)responseAfterMark.getUnread(), is(0)); + assertThat((int)responseAfterMark.getUnseen(), is(1)); StreamResponse> responseAfterMark2 = notificationActivityService.getActivities(new FeedFilter.Builder().build(), new MarkedActivity.Builder().build(), marker); - assertThat((int)responseAfterMark2.getUnread(), is(1)); - assertThat((int)responseAfterMark2.getUnseen(), is(1)); + assertThat((int)responseAfterMark2.getUnread(), is(0)); + assertThat((int)responseAfterMark2.getUnseen(), is(0)); streamClient.shutdown(); } @@ -600,7 +648,7 @@ public void shouldGetActivitiesFromEmptyAggregatedFeed() throws IOException, Str } @Test - public void shouldGetActivitiesFromAggregatedFeed() throws IOException, StreamClientException { + public void shouldGetActivitiesFromAggregatedFeed() throws IOException, StreamClientException, InterruptedException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, API_SECRET); @@ -622,17 +670,14 @@ public void shouldGetActivitiesFromAggregatedFeed() throws IOException, StreamCl assertThat(oneActivity.size(), is(1)); assertThat((int)oneActivity.get(0).getActivityCount(), is(1)); + /* needed to bypass the lock on the backend */ + Thread.sleep(3500); + aggregatedActivityService.addActivity(activity); List> oneActivityB = aggregatedActivityService.getActivities().getResults(); assertThat(oneActivityB.size(), is(1)); assertThat((int)oneActivityB.get(0).getActivityCount(), is(2)); - activity.setVerb("pin"); - aggregatedActivityService.addActivity(activity); - List> twoActivities = aggregatedActivityService.getActivities().getResults(); - assertThat(twoActivities.size(), is(2)); - assertThat((int)twoActivities.get(0).getActivityCount(), is(1)); - assertThat((int)twoActivities.get(1).getActivityCount(), is(2)); streamClient.shutdown(); } diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtilsTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtilsTest.java new file mode 100644 index 00000000..20414efd --- /dev/null +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtilsTest.java @@ -0,0 +1,52 @@ +package io.getstream.client.okhttp.repo.utils; + +import com.squareup.okhttp.Request; +import io.getstream.client.model.feeds.BaseFeed; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; + +public class StreamRepoUtilsTest { + + private static final String API_SECRET = "4vknf33hn4n94exgrg367jbmg4jxetem93bqcg3nkdf2xau3q8pmy3pftytq4w8v"; + + private BaseFeed feed; + + @Before + public void init() { + this.feed = mock(BaseFeed.class); + when(this.feed.getFeedId()).thenReturn("id"); + } + + @Test + public void shouldAddAuthentication() throws Exception { + Request.Builder request = mock(Request.Builder.class); + String signature = StreamRepoUtils.createFeedSignature(feed, API_SECRET); + + StreamRepoUtils.addAuthentication(feed, API_SECRET, request); + verify(request).addHeader(eq("Authorization"), eq(signature)); + } + + @Test + public void shouldCreateFeedToken() throws Exception { + assertThat(StreamRepoUtils.createFeedToken(feed, API_SECRET), is("0DayILmfWZ4i8h6WHFUV0diDXOg")); + } + + @Test + public void shouldCreateFeedSignature() throws Exception { + assertThat(StreamRepoUtils.createFeedSignature(feed, API_SECRET), is("id 0DayILmfWZ4i8h6WHFUV0diDXOg")); + } + + @Test + public void shouldAddJwtAuthentication() throws Exception { + Request.Builder request = mock(Request.Builder.class); + + StreamRepoUtils.addJwtAuthentication("token", request); + verify(request).addHeader(eq("Authorization"), eq("token")); + verify(request).addHeader(eq("stream-auth-type"), eq("jwt")); + } +} \ No newline at end of file From 7bad67479c431505bb11724e8fddac5315c46253 Mon Sep 17 00:00:00 2001 From: alessandro Date: Mon, 30 May 2016 16:57:39 +0200 Subject: [PATCH 022/320] Added updateActivities Added addActivities Added activity_copy_limit (follow, followMany) Added keep_history (unfollow) Added read only token for RealTime update Fixed integration test Preserve order while creating JWT token --- .../model/beans/StreamActivitiesResponse.java | 22 +++++ .../client/model/feeds/BaseFeed.java | 29 ++++-- .../io/getstream/client/model/feeds/Feed.java | 28 ++++++ .../client/repo/StreamRepository.java | 37 +++++--- .../service/AbstractActivityService.java | 10 +-- .../client/util/JwtAuthenticationUtil.java | 5 +- .../util/JwtAuthenticationUtilTest.java | 89 ++++++++++++------- .../apache/repo/StreamActivityRepository.java | 15 ++-- .../apache/repo/StreamRepositoryImpl.java | 29 +++--- .../client/apache/IntegrationTest.java | 68 ++++++++++---- .../okhttp/repo/StreamActivityRepository.java | 14 ++- .../okhttp/repo/StreamRepositoryImpl.java | 50 ++++++----- .../client/okhttp/IntegrationTest.java | 72 ++++++++++++++- 13 files changed, 342 insertions(+), 126 deletions(-) create mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java b/stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java new file mode 100644 index 00000000..8ab3cd38 --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java @@ -0,0 +1,22 @@ +package io.getstream.client.model.beans; + +import io.getstream.client.model.activities.BaseActivity; + +import java.util.List; + +/** + * + * @param + */ +public class StreamActivitiesResponse { + + private List activities; + + public List getActivities() { + return activities; + } + + public void setActivities(List activities) { + this.activities = activities; + } +} diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java index c444c778..c93cf553 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java @@ -34,12 +34,12 @@ import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; -import io.getstream.client.service.FlatActivityServiceImpl; -import io.getstream.client.service.UserActivityServiceImpl; import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.repo.StreamRepository; import io.getstream.client.service.AggregatedActivityServiceImpl; +import io.getstream.client.service.FlatActivityServiceImpl; import io.getstream.client.service.NotificationActivityServiceImpl; +import io.getstream.client.service.UserActivityServiceImpl; import java.io.IOException; import java.util.List; @@ -49,7 +49,9 @@ */ public class BaseFeed implements Feed { - public static final int DEFAULT_ACTIVITY_COPY_LIMIT = 300; + private static final int DEFAULT_ACTIVITY_COPY_LIMIT = 300; + private static final boolean DEFAULT_KEEP_HISTORY = false; + protected final StreamRepository streamRepository; protected final String feedSlug; protected final String userId; @@ -70,10 +72,21 @@ public BaseFeed(StreamRepository streamRepository, String feedSlug, String userI this.id = feedSlug.concat(":").concat(userId); } + @Override + public String getReadOnlyToken() { + return streamRepository.getReadOnlyToken(this); + } + @Override public void follow(String feedSlug, String userId) throws IOException, StreamClientException { String feedId = String.format("%s:%s", feedSlug, userId); - streamRepository.follow(this, feedId); + streamRepository.follow(this, feedId, DEFAULT_ACTIVITY_COPY_LIMIT); + } + + @Override + public void follow(String feedSlug, String userId, int activityCopyLimit) throws IOException, StreamClientException { + String feedId = String.format("%s:%s", feedSlug, userId); + streamRepository.follow(this, feedId, activityCopyLimit); } @Override @@ -89,7 +102,13 @@ public void followMany(FollowMany follows) throws IOException, StreamClientExcep @Override public void unfollow(String feedSlug, String userId) throws IOException, StreamClientException { String feedId = String.format("%s:%s", feedSlug, userId); - streamRepository.unfollow(this, feedId); + streamRepository.unfollow(this, feedId, DEFAULT_KEEP_HISTORY); + } + + @Override + public void unfollow(String feedSlug, String userId, boolean keepHistory) throws IOException, StreamClientException { + String feedId = String.format("%s:%s", feedSlug, userId); + streamRepository.unfollow(this, feedId, keepHistory); } @Override diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java b/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java index 7ba73116..46aca1c3 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java @@ -62,6 +62,12 @@ public interface Feed { */ String getToken(); + /** + * Generate a JWT token to perform readonly operations + * @return Token + */ + String getReadOnlyToken(); + /** * Follows the given target feed. * @@ -72,6 +78,17 @@ public interface Feed { */ void follow(String feedSlug, String userId) throws IOException, StreamClientException; + /** + * Follows the given target feed. + * + * @param feedSlug the slug of the target feed. + * @param userId user id + * @param activityCopyLimit How many activities should be copied from the target feed + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + void follow(String feedSlug, String userId, int activityCopyLimit) throws IOException, StreamClientException; + /** * Follow many feed in one shot. * @@ -104,6 +121,17 @@ public interface Feed { */ void unfollow(String feedSlug, String userId) throws IOException, StreamClientException; + /** + * Unfollow the given target feed. + * + * @param feedSlug the slug of the target feed. + * @param userId user id + * @param keepHistory Whether the activities from the unfollowed feed should be removed + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + void unfollow(String feedSlug, String userId, boolean keepHistory) throws IOException, StreamClientException; + /** * Lists the followers of the feed. * diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java index ad9179b5..5f1787fd 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java @@ -31,14 +31,15 @@ package io.getstream.client.repo; import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; +import io.getstream.client.model.activities.NotificationActivity; import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; -import io.getstream.client.model.feeds.BaseFeed; -import io.getstream.client.model.activities.AggregatedActivity; -import io.getstream.client.model.activities.NotificationActivity; import io.getstream.client.model.beans.MarkedActivity; +import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; import java.io.IOException; @@ -69,15 +70,23 @@ public interface StreamRepository { */ void deleteActivityByForeignId(BaseFeed feed, String foreignId) throws IOException, StreamClientException; + /** + * Generate a JWT token to perform readonly operations. + * @param feed Input feed + * @return JWT token + */ + String getReadOnlyToken(BaseFeed feed); + /** * Follow a feed. * * @param feed Feed that wants to follow a target feed. * @param targetFeedId Feed to follow. + * @param activityCopyLimit How many activities should be copied from the target feed * @throws StreamClientException in case of functional or server-side exception * @throws IOException in case of network/socket exceptions */ - void follow(BaseFeed feed, String targetFeedId) throws StreamClientException, IOException; + void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) throws StreamClientException, IOException; /** * Follow many feed in one shot. @@ -95,10 +104,11 @@ public interface StreamRepository { * * @param feed Source feed * @param targetFeedId Feed to unfollow. + * @param keepHistory Whether the activities from the unfollowed feed should be removed * @throws StreamClientException in case of functional or server-side exception * @throws IOException in case of network/socket exceptions */ - void unfollow(BaseFeed feed, String targetFeedId) throws StreamClientException, IOException; + void unfollow(BaseFeed feed, String targetFeedId, boolean keepHistory) throws StreamClientException, IOException; /** * List the feeds which the given feed is following. @@ -149,27 +159,26 @@ public interface StreamRepository { /** * Add a new list of activities to the given feed. - * + * @param Subtype of {@link BaseActivity} representing the activity type to handle. * @param feed Feed which the activities belong to - * @param activities List of activities to add - * @param Subtype of {@link BaseActivity} representing the activity type to handle. - * @return Activity as returned by the Stream server + * @param type Type of the activity. Must be a subtype of {@link BaseActivity} + * @param activities List of activities to add @return Activity as returned by the Stream server * @throws StreamClientException in case of functional or server-side exception * @throws IOException in case of network/socket exceptions */ - StreamResponse addActivities(BaseFeed feed, List activities) throws StreamClientException, IOException; + StreamActivitiesResponse addActivities(BaseFeed feed, Class type, List activities) throws StreamClientException, IOException; /** * Update activities (foreignId and time are mandatory fields). * Please refer to GetStream.io/docs for more info. - * @param feed Feed which the activities belong to - * @param activities List of activities to update * @param Subtype of {@link BaseActivity} representing the activity type to handle. - * @return Operation response + * @param feed Feed which the activities belong to + * @param type Type of the activity. Must be a subtype of {@link BaseActivity} + * @param activities List of activities to update @return Operation response * @throws IOException in case of network/socket exceptions * @throws StreamClientException in case of functional or server-side exception */ - StreamResponse updateActivities(BaseFeed feed, List activities) throws IOException, StreamClientException; + StreamActivitiesResponse updateActivities(BaseFeed feed, Class type, List activities) throws IOException, StreamClientException; /** * Add a new activity of type {@link T} to multiple feeds. diff --git a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java index 778ef3cf..37127b53 100644 --- a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java +++ b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java @@ -32,7 +32,7 @@ import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.BaseActivity; -import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.repo.StreamRepository; @@ -79,8 +79,8 @@ public T addActivity(T activity) throws IOException, StreamClientException { * @throws IOException in case of network/socket exceptions * @throws StreamClientException in case of functional or server-side exception */ - public StreamResponse addActivities(List activities) throws IOException, StreamClientException { - return streamRepository.addActivities(this.feed, activities); + public StreamActivitiesResponse addActivities(List activities) throws IOException, StreamClientException { + return streamRepository.addActivities(this.feed, type, activities); } /** @@ -93,8 +93,8 @@ public StreamResponse addActivities(List activities) throws IOException, S * @throws IOException in case of network/socket exceptions * @throws StreamClientException in case of functional or server-side exception */ - public StreamResponse updateActivities(List activities) throws IOException, StreamClientException { - return streamRepository.updateActivities(this.feed, activities); + public StreamActivitiesResponse updateActivities(List activities) throws IOException, StreamClientException { + return streamRepository.updateActivities(this.feed, type, activities); } /** diff --git a/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java b/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java index be95f8f0..6524d429 100644 --- a/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java +++ b/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java @@ -3,7 +3,8 @@ import com.auth0.jwt.Algorithm; import com.auth0.jwt.JWTSigner; -import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; /** * Utility class to generate a JWT token. @@ -25,7 +26,7 @@ public class JwtAuthenticationUtil { * @return Token string */ public static String generateToken(final String secretKey, final String action, final String resource, final String feedId, final String userId) { - HashMap claims = new HashMap(); + Map claims = new LinkedHashMap(); claims.put("action", action); claims.put("resource", resource); if (null != feedId) { diff --git a/stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java b/stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java index 629d398d..cec6921a 100644 --- a/stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java +++ b/stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java @@ -1,9 +1,19 @@ package io.getstream.client.util; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.JWTVerifyException; import org.junit.Test; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SignatureException; +import java.util.Map; + +import static io.getstream.client.util.JwtAuthenticationUtil.ALL; +import static junit.framework.TestCase.assertTrue; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; +import static org.hamcrest.MatcherAssert.assertThat; public class JwtAuthenticationUtilTest { @@ -11,53 +21,66 @@ public class JwtAuthenticationUtilTest { @Test public void testGenerateToken() throws Exception { - assertThat(JwtAuthenticationUtil.generateToken( - SECRET_KEY, - "activities", - "myResource", - null, - null), - is("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3Rpb24iOiJhY3Rpdml0aWVzIiwicmVzb3VyY2UiOi" + - "JteVJlc291cmNlIn0.zLHVXhkZWK_VTpX_iHxyg_pjQBVSgBKkeSGpP8W6zF0") + Map map = verifyToken( + JwtAuthenticationUtil.generateToken( + SECRET_KEY, + "activities", + "myResource", + null, + null) ); + assertTrue(map.size() > 0); + assertThat(map.get("action").toString(), is("activities")); } @Test public void testGenerateTokenWithFeedId() throws Exception { - assertThat(JwtAuthenticationUtil.generateToken( - SECRET_KEY, - "activities", - JwtAuthenticationUtil.ALL, - "feed1", - null), - is("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3Rpb24iOiJhY3Rpdml0aWVzIiwicmVzb3VyY2UiOiIq" + - "IiwiZmVlZF9pZCI6ImZlZWQxIn0.uBBDb91Lo-D9k9LQY-nK1nXMYjcwgQ4MWao69s4unRI") + Map map = verifyToken( + JwtAuthenticationUtil.generateToken( + SECRET_KEY, + "activities", + ALL, + "feedId", + null) ); + assertTrue(map.size() > 0); + assertThat(map.get("resource").toString(), is(ALL)); + assertThat(map.get("feed_id").toString(), is("feedId")); } @Test public void testGenerateTokenWithUserId() throws Exception { - assertThat(JwtAuthenticationUtil.generateToken( - SECRET_KEY, - "activities", - JwtAuthenticationUtil.ALL, - null, - "userId1"), - is("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3Rpb24iOiJhY3Rpdml0aWVzIiwicmVzb3VyY2UiOiIqIi" + - "widXNlcl9pZCI6InVzZXJJZDEifQ.Ssr60hHaffWZ7TKj69bb7f5kxZ1b0K56GUAj_2tpkgg") + Map map = verifyToken( + JwtAuthenticationUtil.generateToken( + SECRET_KEY, + "activities", + ALL, + null, + "userId1") ); + assertTrue(map.size() > 0); + assertThat(map.get("resource").toString(), is(ALL)); + assertThat(map.get("user_id").toString(), is("userId1")); } @Test public void testGenerateTokenWithFeedAndUserId() throws Exception { - assertThat(JwtAuthenticationUtil.generateToken( - SECRET_KEY, - "activities", - "myResource", - "feedId", - "userId"), - is("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3Rpb24iOiJhY3Rpdml0aWVzIiwicmVzb3VyY2UiOiJteVJl" + - "c291cmNlIiwidXNlcl9pZCI6InVzZXJJZCIsImZlZWRfaWQiOiJmZWVkSWQifQ.A7Qv7dmj3EwoZ93YBWKidRi9BLVikxpwfspGO0IccPU") + Map map = verifyToken( + JwtAuthenticationUtil.generateToken( + SECRET_KEY, + "activities", + ALL, + "feedId", + "userId1") ); + assertTrue(map.size() > 0); + assertThat(map.get("resource").toString(), is(ALL)); + assertThat(map.get("feed_id").toString(), is("feedId")); + assertThat(map.get("user_id").toString(), is("userId1")); + } + + private Map verifyToken(final String token) throws SignatureException, NoSuchAlgorithmException, JWTVerifyException, InvalidKeyException, IOException { + byte[] secret = SECRET_KEY.getBytes(); + return new JWTVerifier(secret, "audience").verify(token); } } \ No newline at end of file diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java index 332b568a..b5c33082 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java @@ -31,7 +31,6 @@ package io.getstream.client.apache.repo; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.reflect.TypeToken; import io.getstream.client.apache.repo.handlers.StreamExceptionHandler; import io.getstream.client.apache.repo.utils.SignatureUtils; import io.getstream.client.apache.repo.utils.StreamRepoUtils; @@ -40,9 +39,9 @@ import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.NotificationActivity; -import io.getstream.client.model.activities.SimpleActivity; import io.getstream.client.model.beans.AddMany; import io.getstream.client.model.beans.MarkedActivity; +import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; @@ -107,17 +106,14 @@ public T addActivity(BaseFeed feed, T activity) throws } } - public StreamResponse addActivities(BaseFeed feed, List activities) throws StreamClientException, IOException { + public StreamActivitiesResponse addActivities(BaseFeed feed, Class type, List activities) throws StreamClientException, IOException { HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) .path("feed").path(feed.getFeedSlug()).path(feed.getUserId() + "/") .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build()); LOG.debug("Invoking url: '{}'", request.getURI()); - Class clazz = SimpleActivity.class; for (T activity : activities) { SignatureUtils.addSignatureToRecipients(secretKey, activity); - clazz = activity.getClass(); - System.out.println(clazz); } request.setEntity(new InputStreamEntity(new ByteArrayInputStream( @@ -125,7 +121,7 @@ public StreamResponse addActivities(BaseFeed feed, L try (CloseableHttpResponse response = httpClient.execute(addAuthentication(feed, request), HttpClientContext.create())) { handleResponseCode(response); return objectMapper.readValue(response.getEntity().getContent(), - objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, clazz)); + objectMapper.getTypeFactory().constructParametricType(StreamActivitiesResponse.class, type)); } } @@ -241,7 +237,7 @@ public void deleteActivityByForeignId(BaseFeed feed, String activityId) throws I } } - public StreamResponse updateActivities(BaseFeed feed, List activities) throws StreamClientException, IOException { + public StreamActivitiesResponse updateActivities(BaseFeed feed, Class type, List activities) throws StreamClientException, IOException { HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) .path("activities/") .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build()); @@ -257,7 +253,8 @@ public StreamResponse updateActivities(BaseFeed feed, L try (CloseableHttpResponse response = httpClient.execute(request, HttpClientContext.create())) { handleResponseCode(response); - return objectMapper.readValue(response.getEntity().getContent(), StreamResponse.class); + return objectMapper.readValue(response.getEntity().getContent(), + objectMapper.getTypeFactory().constructParametricType(StreamActivitiesResponse.class, type)); } } diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index 48f5686b..9d815377 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -35,6 +35,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.SerializationFeature; +import io.getstream.client.apache.repo.handlers.StreamExceptionHandler; +import io.getstream.client.apache.repo.utils.StreamRepoUtils; +import io.getstream.client.apache.repo.utils.UriBuilder; import io.getstream.client.config.ClientConfiguration; import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.AggregatedActivity; @@ -42,14 +45,13 @@ import io.getstream.client.model.activities.NotificationActivity; import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; -import io.getstream.client.model.feeds.BaseFeed; -import io.getstream.client.apache.repo.handlers.StreamExceptionHandler; -import io.getstream.client.apache.repo.utils.StreamRepoUtils; import io.getstream.client.model.beans.MarkedActivity; +import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; -import io.getstream.client.apache.repo.utils.UriBuilder; import io.getstream.client.repo.StreamRepository; +import io.getstream.client.util.JwtAuthenticationUtil; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpDelete; @@ -112,9 +114,15 @@ public StreamRepositoryImpl(ClientConfiguration streamClient, CloseableHttpClien } @Override - public void follow(BaseFeed feed, String targetFeedId) throws StreamClientException, IOException { + public String getReadOnlyToken(BaseFeed feed) { + return JwtAuthenticationUtil.generateToken(secretKey, "read", "*", feed.getFeedSlug().concat(feed.getUserId()), null); + } + + @Override + public void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) throws StreamClientException, IOException { HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) .path("feed").path(feed.getFeedSlug()).path(feed.getUserId()).path("following/") + .queryParam("activity_copy_limit", activityCopyLimit) .queryParam(API_KEY, apiKey).build()); request.setEntity(new UrlEncodedFormEntity( Collections.singletonList(new BasicNameValuePair("target", targetFeedId)))); @@ -133,9 +141,10 @@ public void followMany(BaseFeed feed, FollowMany followManyInput, int activityCo } @Override - public void unfollow(BaseFeed feed, String targetFeedId) throws StreamClientException, IOException { + public void unfollow(BaseFeed feed, String targetFeedId, boolean keepHistory) throws StreamClientException, IOException { HttpDelete request = new HttpDelete(UriBuilder.fromEndpoint(baseEndpoint) .path("feed").path(feed.getFeedSlug()).path(feed.getUserId()).path("following").path(targetFeedId + "/") + .queryParam("keep_history", Boolean.toString(keepHistory)) .queryParam(API_KEY, apiKey).build()); fireAndForget(addAuthentication(feed, request)); } @@ -191,13 +200,13 @@ public T addActivity(BaseFeed feed, T activity) throws } @Override - public StreamResponse addActivities(BaseFeed feed, List activities) throws StreamClientException, IOException { - return streamActivityRepository.addActivities(feed, activities); + public StreamActivitiesResponse addActivities(BaseFeed feed, Class type, List activities) throws StreamClientException, IOException { + return streamActivityRepository.addActivities(feed, type, activities); } @Override - public StreamResponse updateActivities(BaseFeed feed, List activities) throws StreamClientException, IOException { - return streamActivityRepository.updateActivities(feed, activities); + public StreamActivitiesResponse updateActivities(BaseFeed feed, Class type, List activities) throws StreamClientException, IOException { + return streamActivityRepository.updateActivities(feed, type, activities); } @Override diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index 7bf94418..cf774b6a 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -12,6 +12,7 @@ import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; import io.getstream.client.model.beans.MarkedActivity; +import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.Feed; import io.getstream.client.model.filters.FeedFilter; @@ -30,7 +31,8 @@ import java.util.List; import java.util.concurrent.TimeUnit; -import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; public class IntegrationTest { @@ -50,6 +52,15 @@ public String getTestUserId(String userId) { return String.format("%s_%d", userId, millis); } + @Test + public void shouldGetReadOnlyToken() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + API_SECRET); + Feed feed = streamClient.newFeed("user", "1"); + assertThat(feed.getReadOnlyToken(), is("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3Rpb24iOiJyZWFkIiwicmVzb" + + "3VyY2UiOiIqIiwiZmVlZF9pZCI6InVzZXIxIn0.slCmD5rirATciiL01aE9jXsxjE3NnUwkSgvviUpBhxE")); + } + @Test public void shouldGetFollowers() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, @@ -68,7 +79,6 @@ public void shouldGetFollowers() throws IOException, StreamClientException { assertThat(followersAfter.size(), is(1)); streamClient.shutdown(); - streamClient.shutdown(); } @Test @@ -96,6 +106,25 @@ public void shouldFollow() throws IOException, StreamClientException { streamClient.shutdown(); } + @Test + public void shouldFollowWithActivityCopyLimit() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + API_SECRET); + + String followerId = this.getTestUserId("shouldFollow"); + Feed feed = streamClient.newFeed("user", followerId); + + List following = feed.getFollowing(); + assertThat(following.size(), is(0)); + + feed.follow("user", "1", 50); + + List followingAfter = feed.getFollowing(); + assertThat(followingAfter.size(), is(1)); + + streamClient.shutdown(); + } + @Test public void shouldFollowMany() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, @@ -171,9 +200,10 @@ public void shouldUnfollow() throws IOException, StreamClientException, Interrup List followingAfter = feed.getFollowing(); assertThat(followingAfter.size(), is(3)); feed.unfollow("user", "2"); + feed.unfollow("user", "3", true); List followingAgain = feed.getFollowing(); - assertThat(followingAgain.size(), is(2)); + assertThat(followingAgain.size(), is(1)); streamClient.shutdown(); } @@ -211,7 +241,9 @@ public void shouldAddActivity() throws IOException, StreamClientException { activity.setTarget("target"); activity.setVerb("verb"); activity.setForeignId("foreign1"); - flatActivityService.addActivity(activity); + + SimpleActivity simpleActivity = flatActivityService.addActivity(activity); + streamClient.shutdown(); } @@ -240,12 +272,15 @@ public void shouldAddActivities() throws IOException, StreamClientException { List listToAdd = new ArrayList<>(); listToAdd.add(activity); listToAdd.add(activity2); - flatActivityService.addActivities(listToAdd); + + StreamActivitiesResponse streamResponse = flatActivityService.addActivities(listToAdd); + streamResponse.getActivities(); + streamClient.shutdown(); } @Test - public void shouldUpdateActivity() throws IOException, StreamClientException { + public void shouldUpdateActivities() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, API_SECRET); @@ -259,7 +294,10 @@ public void shouldUpdateActivity() throws IOException, StreamClientException { activity.setTime(new Date()); activity.setForeignId("foreign1"); activity.setVerb("verb"); - flatActivityService.updateActivities(Collections.singletonList(activity)); + + StreamActivitiesResponse response = flatActivityService.updateActivities(Collections.singletonList(activity)); + response.getActivities(); + streamClient.shutdown(); } @@ -628,7 +666,7 @@ public void shouldGetActivitiesFromEmptyAggregatedFeed() throws IOException, Str } @Test - public void shouldGetActivitiesFromAggregatedFeed() throws IOException, StreamClientException { + public void shouldGetActivitiesFromAggregatedFeed() throws IOException, StreamClientException, InterruptedException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, API_SECRET); @@ -647,20 +685,20 @@ public void shouldGetActivitiesFromAggregatedFeed() throws IOException, StreamCl aggregatedActivityService.addActivity(activity); List> oneActivity = aggregatedActivityService.getActivities().getResults(); - assertThat(oneActivity.size(), is(1)); - assertThat((int)oneActivity.get(0).getActivityCount(), is(1)); - aggregatedActivityService.addActivity(activity); - List> oneActivityB = aggregatedActivityService.getActivities().getResults(); - assertThat(oneActivityB.size(), is(1)); - assertThat((int)oneActivityB.get(0).getActivityCount(), is(2)); + /* needed to bypass the lock on backend side */ + Thread.sleep(3500); activity.setVerb("pin"); aggregatedActivityService.addActivity(activity); + + assertThat(oneActivity.size(), is(1)); + assertThat((int)oneActivity.get(0).getActivityCount(), is(1)); + List> twoActivities = aggregatedActivityService.getActivities().getResults(); assertThat(twoActivities.size(), is(2)); assertThat((int)twoActivities.get(0).getActivityCount(), is(1)); - assertThat((int)twoActivities.get(1).getActivityCount(), is(2)); + assertThat((int)twoActivities.get(1).getActivityCount(), is(1)); streamClient.shutdown(); } diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java index 01281a11..557c43bd 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java @@ -40,9 +40,9 @@ import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.NotificationActivity; -import io.getstream.client.model.activities.SimpleActivity; import io.getstream.client.model.beans.AddMany; import io.getstream.client.model.beans.MarkedActivity; +import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; @@ -103,16 +103,13 @@ public T addActivity(BaseFeed feed, T activity) throws objectMapper.getTypeFactory().constructType(activity.getClass())); } - public StreamResponse addActivities(BaseFeed feed, List activities) throws StreamClientException, IOException { + public StreamActivitiesResponse addActivities(BaseFeed feed, Class type, List activities) throws StreamClientException, IOException { Request.Builder requestBuilder = new Request.Builder().url(UriBuilder.fromEndpoint(baseEndpoint) .path("feed").path(feed.getFeedSlug()).path(feed.getUserId() + "/") .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build().toURL()); - Class clazz = SimpleActivity.class; for (T activity : activities) { SignatureUtils.addSignatureToRecipients(secretKey, activity); - clazz = activity.getClass(); - System.out.println(clazz); } requestBuilder.post(RequestBody.create(MediaType.parse(APPLICATION_JSON), @@ -124,7 +121,7 @@ public StreamResponse addActivities(BaseFeed feed, L Response response = httpClient.newCall(request).execute(); handleResponseCode(response); return objectMapper.readValue(response.body().byteStream(), - objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, clazz)); + objectMapper.getTypeFactory().constructParametricType(StreamActivitiesResponse.class, type)); } public T addToMany(List targetIds, T activity) throws StreamClientException, IOException { @@ -252,7 +249,7 @@ public void deleteActivityByForeignId(BaseFeed feed, String activityId) throws I handleResponseCode(response); } - public StreamResponse updateActivities(BaseFeed feed, List activities) throws IOException, StreamClientException { + public StreamActivitiesResponse updateActivities(BaseFeed feed, Class type, List activities) throws IOException, StreamClientException { Request.Builder requestBuilder = new Request.Builder().delete().url(UriBuilder.fromEndpoint(baseEndpoint) .path("activities/") .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build().toURL()); @@ -268,7 +265,8 @@ public StreamResponse updateActivities(BaseFeed feed, L Response response = httpClient.newCall(request).execute(); handleResponseCode(response); - return objectMapper.readValue(response.body().byteStream(), StreamResponse.class); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamActivitiesResponse.class, type)); } private void handleResponseCode(Response response) throws StreamClientException, IOException { diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index fcb2a4c6..03415ee3 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -30,20 +30,16 @@ */ package io.getstream.client.okhttp.repo; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.squareup.okhttp.MediaType; -import com.squareup.okhttp.RequestBody; -import io.getstream.client.model.beans.FollowMany; -import io.getstream.client.okhttp.repo.handlers.StreamExceptionHandler; -import io.getstream.client.okhttp.repo.utils.StreamRepoUtils; -import io.getstream.client.okhttp.repo.utils.UriBuilder; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.SerializationFeature; import com.squareup.okhttp.FormEncodingBuilder; +import com.squareup.okhttp.MediaType; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; +import com.squareup.okhttp.RequestBody; import com.squareup.okhttp.Response; import io.getstream.client.config.ClientConfiguration; import io.getstream.client.exception.StreamClientException; @@ -51,13 +47,19 @@ import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.NotificationActivity; import io.getstream.client.model.beans.FeedFollow; +import io.getstream.client.model.beans.FollowMany; import io.getstream.client.model.beans.MarkedActivity; +import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; -import io.getstream.client.repo.StreamRepository; +import io.getstream.client.okhttp.repo.handlers.StreamExceptionHandler; import io.getstream.client.okhttp.repo.utils.FeedFilterUtils; +import io.getstream.client.okhttp.repo.utils.StreamRepoUtils; +import io.getstream.client.okhttp.repo.utils.UriBuilder; +import io.getstream.client.repo.StreamRepository; import io.getstream.client.util.HttpSignatureHandler; +import io.getstream.client.util.JwtAuthenticationUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -72,11 +74,6 @@ public class StreamRepositoryImpl implements StreamRepository { private static final String APPLICATION_JSON = "application/json; charset=utf-8"; - @Override - public String getToken(BaseFeed feed) { - return StreamRepoUtils.createFeedToken(feed, secretKey); - } - private static final Logger LOG = LoggerFactory.getLogger(StreamRepositoryImpl.class); static final String API_KEY = "api_key"; @@ -87,7 +84,6 @@ public String getToken(BaseFeed feed) { .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - private final URI baseEndpoint; private final String apiKey; private final String secretKey; @@ -114,9 +110,20 @@ public StreamRepositoryImpl(ClientConfiguration streamClient, OkHttpClient close } @Override - public void follow(BaseFeed feed, String targetFeedId) throws StreamClientException, IOException { + public String getReadOnlyToken(BaseFeed feed) { + return JwtAuthenticationUtil.generateToken(secretKey, "read", "*", feed.getFeedSlug().concat(feed.getUserId()), null); + } + + @Override + public String getToken(BaseFeed feed) { + return StreamRepoUtils.createFeedToken(feed, secretKey); + } + + @Override + public void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) throws StreamClientException, IOException { Request.Builder requestBuilder = new Request.Builder().url(UriBuilder.fromEndpoint(baseEndpoint) .path("feed").path(feed.getFeedSlug()).path(feed.getUserId()).path("following/") + .queryParam("activity_copy_limit", activityCopyLimit) .queryParam(API_KEY, apiKey).build().toURL()); requestBuilder.post(new FormEncodingBuilder().add("target", targetFeedId).build()); @@ -137,9 +144,10 @@ public void followMany(BaseFeed feed, FollowMany followManyInput, int activityCo } @Override - public void unfollow(BaseFeed feed, String targetFeedId) throws StreamClientException, IOException { + public void unfollow(BaseFeed feed, String targetFeedId, boolean keepHistory) throws StreamClientException, IOException { Request.Builder requestBuilder = new Request.Builder().url(UriBuilder.fromEndpoint(baseEndpoint) .path("feed").path(feed.getFeedSlug()).path(feed.getUserId()).path("following").path(targetFeedId + "/") + .queryParam("keep_history", Boolean.toString(keepHistory)) .queryParam(API_KEY, apiKey).build().toURL()).delete(); fireAndForget(addAuthentication(feed, requestBuilder).build()); } @@ -197,13 +205,13 @@ public T addActivity(BaseFeed feed, T activity) throws } @Override - public StreamResponse addActivities(BaseFeed feed, List activities) throws IOException, StreamClientException { - return streamActivityRepository.addActivities(feed, activities); + public StreamActivitiesResponse addActivities(BaseFeed feed, Class type, List activities) throws IOException, StreamClientException { + return streamActivityRepository.addActivities(feed, type, activities); } @Override - public StreamResponse updateActivities(BaseFeed feed, List activities) throws IOException, StreamClientException { - return streamActivityRepository.updateActivities(feed, activities); + public StreamActivitiesResponse updateActivities(BaseFeed feed, Class type, List activities) throws IOException, StreamClientException { + return streamActivityRepository.updateActivities(feed, type, activities); } @Override diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index 636df653..03764a13 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -12,6 +12,7 @@ import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; import io.getstream.client.model.beans.MarkedActivity; +import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.Feed; import io.getstream.client.model.filters.FeedFilter; @@ -44,6 +45,15 @@ public String getTestUserId(String userId) { return String.format("%s_%d", userId, millis); } + @Test + public void shouldGetReadOnlyToken() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + API_SECRET); + Feed feed = streamClient.newFeed("user", "1"); + assertThat(feed.getReadOnlyToken(), is("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3Rpb24iOiJyZWFkIiwicmV" + + "zb3VyY2UiOiIqIiwiZmVlZF9pZCI6InVzZXIxIn0.MywMBtZJzjzSlTU7jfBglJ1NcUeaAWY1uhe6sjB97Wg")); + } + @Test public void shouldGetFollowers() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, @@ -90,6 +100,25 @@ public void shouldFollow() throws IOException, StreamClientException { streamClient.shutdown(); } + @Test + public void shouldFollowWithActivityCopyLimit() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + API_SECRET); + + String followerId = this.getTestUserId("shouldFollow"); + Feed feed = streamClient.newFeed("user", followerId); + + List following = feed.getFollowing(); + assertThat(following.size(), is(0)); + + feed.follow("user", "1", 50); + + List followingAfter = feed.getFollowing(); + assertThat(followingAfter.size(), is(1)); + + streamClient.shutdown(); + } + @Test public void shouldFollowMany() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, @@ -118,6 +147,34 @@ public void shouldFollowMany() throws IOException, StreamClientException { streamClient.shutdown(); } + @Test + public void shouldFollowManyWithActivityCopyLimit() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + API_SECRET); + + String followerId = this.getTestUserId("follower"); + Feed feed = streamClient.newFeed("user", followerId); + + List following = feed.getFollowing(); + assertThat(following.size(), is(0)); + + FollowMany followMany = new FollowMany.Builder() + .add("user:" + followerId, "user:1") + .add("user:" + followerId, "user:2") + .add("user:" + followerId, "user:3") + .build(); + feed.followMany(followMany, 50); + + List followingAfter = feed.getFollowing(); + assertThat(followingAfter.size(), is(3)); + + FeedFilter filter = new FeedFilter.Builder().withLimit(1).withOffset(1).build(); + List followingPaged = feed.getFollowing(filter); + assertThat(followingPaged.size(), is(1)); + + streamClient.shutdown(); + } + @Test public void shouldHaveOriginField() throws IOException, StreamClientException, InterruptedException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, @@ -164,10 +221,11 @@ public void shouldUnfollow() throws IOException, StreamClientException, Interrup List followingAfter = feed.getFollowing(); assertThat(followingAfter.size(), is(3)); - feed.unfollow("user", "2"); + feed.unfollow("user", "3"); + feed.unfollow("user", "2", true); //keep history List followingAgain = feed.getFollowing(); - assertThat(followingAgain.size(), is(2)); + assertThat(followingAgain.size(), is(1)); streamClient.shutdown(); } @@ -251,7 +309,10 @@ public void shouldAddActivities() throws IOException, StreamClientException { List listToAdd = new ArrayList<>(); listToAdd.add(activity); listToAdd.add(activity2); - flatActivityService.addActivities(listToAdd); + + StreamActivitiesResponse response = flatActivityService.addActivities(listToAdd); + response.getActivities(); + streamClient.shutdown(); } @@ -270,7 +331,10 @@ public void shouldUpdateActivity() throws IOException, StreamClientException { activity.setTime(new Date()); activity.setForeignId("foreign1"); activity.setVerb("verb"); - flatActivityService.updateActivities(Collections.singletonList(activity)); + + StreamActivitiesResponse response = flatActivityService.updateActivities(Collections.singletonList(activity)); + response.getActivities(); + streamClient.shutdown(); } From b6d6a0ffd29b6dcccced4edaf0397d879d6e2879 Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 31 May 2016 14:23:04 +0200 Subject: [PATCH 023/320] [maven-release-plugin] prepare release stream-java-1.1.0 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 62054eba..496630e6 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.1-RC1-SNAPSHOT + 1.1.0 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-1.1.0 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 9eaaef31..b910077c 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1-RC1-SNAPSHOT + 1.1.0 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 4fd76b82..7a444bcf 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1-RC1-SNAPSHOT + 1.1.0 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index f7fb3633..e0005609 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1-RC1-SNAPSHOT + 1.1.0 4.0.0 From b3d674bc91fd6351c9c2f11d62b44db0f15693fb Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 31 May 2016 14:23:09 +0200 Subject: [PATCH 024/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 496630e6..f8bc754a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.1.0 + 1.2.0-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-1.1.0 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index b910077c..c3986e55 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1.0 + 1.2.0-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 7a444bcf..6567dfcb 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1.0 + 1.2.0-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index e0005609..da5ef4f8 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1.0 + 1.2.0-SNAPSHOT 4.0.0 From 7eb8e60ef67b916f7858ad5cd9bad13a95377c3d Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 31 May 2016 14:48:26 +0200 Subject: [PATCH 025/320] Fixed javadocs --- pom.xml | 2 +- stream-core/pom.xml | 2 +- .../io/getstream/client/StreamClient.java | 1 + .../model/beans/StreamActivitiesResponse.java | 34 +++++++++++++++++-- .../client/model/feeds/FeedFactory.java | 3 +- .../client/repo/StreamRepository.java | 7 ++-- .../service/AbstractActivityService.java | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 9 files changed, 44 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index f8bc754a..62054eba 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.2.0-SNAPSHOT + 1.1-RC1-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. diff --git a/stream-core/pom.xml b/stream-core/pom.xml index c3986e55..9eaaef31 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.0-SNAPSHOT + 1.1-RC1-SNAPSHOT 4.0.0 diff --git a/stream-core/src/main/java/io/getstream/client/StreamClient.java b/stream-core/src/main/java/io/getstream/client/StreamClient.java index 5d4d8531..e5a988af 100644 --- a/stream-core/src/main/java/io/getstream/client/StreamClient.java +++ b/stream-core/src/main/java/io/getstream/client/StreamClient.java @@ -46,6 +46,7 @@ public interface StreamClient { * @param feedSlug Feed slug * @param id Feed id * @return A new feed + * @throws InvalidFeedNameException if the feed name is not valid */ Feed newFeed(String feedSlug, String id) throws InvalidFeedNameException; diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java b/stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java index 8ab3cd38..5d6b050e 100644 --- a/stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java +++ b/stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java @@ -1,3 +1,33 @@ +/** + + Copyright (c) 2015, Alessandro Pieri + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + The views and conclusions contained in the software and documentation are those + of the authors and should not be interpreted as representing official policies, + either expressed or implied, of the FreeBSD Project. + + */ package io.getstream.client.model.beans; import io.getstream.client.model.activities.BaseActivity; @@ -5,8 +35,8 @@ import java.util.List; /** - * - * @param + * Response from activities' bulk insert/update. + * @param Type of the activity */ public class StreamActivitiesResponse { diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java b/stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java index 6df5b77b..d5066493 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java @@ -32,8 +32,6 @@ import io.getstream.client.exception.InvalidFeedNameException; -import java.util.regex.Pattern; - /** * Factory class to create new feed. */ @@ -55,6 +53,7 @@ public interface FeedFactory { * @param feedSlug feed slug. * @param id feed id. * @return A new feed + * @throws InvalidFeedNameException if the name of the feed is not valid */ Feed createFeed(String feedSlug, String id) throws InvalidFeedNameException; } diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java index 5f1787fd..4d173592 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java @@ -159,10 +159,11 @@ public interface StreamRepository { /** * Add a new list of activities to the given feed. - * @param Subtype of {@link BaseActivity} representing the activity type to handle. + * @param Subtype of {@link BaseActivity} representing the activity type to handle. * @param feed Feed which the activities belong to * @param type Type of the activity. Must be a subtype of {@link BaseActivity} * @param activities List of activities to add @return Activity as returned by the Stream server + * @return List of just sent activities * @throws StreamClientException in case of functional or server-side exception * @throws IOException in case of network/socket exceptions */ @@ -175,6 +176,7 @@ public interface StreamRepository { * @param feed Feed which the activities belong to * @param type Type of the activity. Must be a subtype of {@link BaseActivity} * @param activities List of activities to update @return Operation response + * @return List of just sent activities * @throws IOException in case of network/socket exceptions * @throws StreamClientException in case of functional or server-side exception */ @@ -183,7 +185,8 @@ public interface StreamRepository { /** * Add a new activity of type {@link T} to multiple feeds. * - * @param targetIds Destination feeds.
A target id is defined as $feedSlug:$feedId. + * @param Subtype of {@link BaseActivity} representing the activity type to handle. + * @param targetIds Destination feeds. A target id is defined as $feedSlug:$feedId. * @param activity Activity to add. * @return Response activity of type {@link T} coming from the server. * @throws IOException in case of network/socket exceptions diff --git a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java index 37127b53..e36c2393 100644 --- a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java +++ b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java @@ -100,7 +100,7 @@ public StreamActivitiesResponse updateActivities(List activities) throws I /** * Add a new activity of type {@link T} to multiple feeds. * - * @param targetIds Destination feeds.
A target id is defined as $feedSlug:$feedId. + * @param targetIds Destination feeds. A target id is defined as $feedSlug:$feedId. * @param activity Activity to add. * @return Response activity of type {@link T} coming from the server. * @throws IOException in case of network/socket exceptions diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 6567dfcb..4fd76b82 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.0-SNAPSHOT + 1.1-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index da5ef4f8..f7fb3633 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.0-SNAPSHOT + 1.1-RC1-SNAPSHOT 4.0.0 From 87668a1aa3cfcd830789fd8f9043314a212efa9c Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 31 May 2016 15:10:13 +0200 Subject: [PATCH 026/320] [maven-release-plugin] prepare release stream-java-1.1.0 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 62054eba..496630e6 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.1-RC1-SNAPSHOT + 1.1.0 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-1.1.0 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 9eaaef31..b910077c 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1-RC1-SNAPSHOT + 1.1.0 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 4fd76b82..7a444bcf 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1-RC1-SNAPSHOT + 1.1.0 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index f7fb3633..e0005609 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1-RC1-SNAPSHOT + 1.1.0 4.0.0 From dd852538d7ba3548632fc819aad1e51f24c847be Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 31 May 2016 15:10:17 +0200 Subject: [PATCH 027/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 496630e6..55063785 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.1.0 + 1.2.0-RC1-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-1.1.0 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index b910077c..d506e94a 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1.0 + 1.2.0-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 7a444bcf..de9bfbc3 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1.0 + 1.2.0-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index e0005609..06adbc84 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.1.0 + 1.2.0-RC1-SNAPSHOT 4.0.0 From be6573a4663c9634aee59177ad44c17458fca308 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 31 May 2016 15:27:02 +0200 Subject: [PATCH 028/320] Updated version number --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index de6510cd..607ea1d3 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 1.0.1 + 1.1.0 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:1.0.1' +compile 'io.getstream.client:stream-repo-apache:1.1.0' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -34,14 +34,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 1.0.1 + 1.1.0 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:1.0.1' +compile 'io.getstream.client:stream-repo-okhttp:1.1.0' ``` In case you want to download the artifact and put it manually into your project, From 96feee4b716074e03afaa649a99476f6a0dc3736 Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 1 Jun 2016 09:03:23 +0200 Subject: [PATCH 029/320] Fixed indentation --- .../apache/example/helloworld/HelloWorld.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/example/helloworld/HelloWorld.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/example/helloworld/HelloWorld.java index f5fba686..150fb88f 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/example/helloworld/HelloWorld.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/example/helloworld/HelloWorld.java @@ -1,10 +1,10 @@ package io.getstream.client.apache.example.helloworld; -import io.getstream.client.apache.StreamClientImpl; import io.getstream.client.StreamClient; -import io.getstream.client.model.activities.BaseActivity; +import io.getstream.client.apache.StreamClientImpl; import io.getstream.client.config.ClientConfiguration; import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.feeds.Feed; import io.getstream.client.service.FlatActivityServiceImpl; @@ -21,7 +21,7 @@ public static void main(String[] args) throws IOException, StreamClientException * Create client using api key and secret key. */ StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), "nfq26m3qgfyp", - "245nvvjm49s3uwrs5e4h3gadsw34mnwste6v3rdnd69ztb35bqspvq8kfzt9v7h2"); + "245nvvjm49s3uwrs5e4h3gadsw34mnwste6v3rdnd69ztb35bqspvq8kfzt9v7h2"); /** * Get the referent to a feed (either new or existing one). @@ -51,15 +51,15 @@ public static void main(String[] args) throws IOException, StreamClientException streamClient.shutdown(); } - /** - * A custom activity must extends BaseActivity. - * Feel free to add as many fields as you want. - */ - static class HelloWorldActivity extends BaseActivity { - protected String message; + /** + * A custom activity must extends BaseActivity. + * Feel free to add as many fields as you want. + */ + static class HelloWorldActivity extends BaseActivity { + protected String message; - public void setMessage(String message) { - this.message = message; - } - } + public void setMessage(String message) { + this.message = message; + } + } } From 50985bbf01488d51a4a3945a26a7d774ae99f47a Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 1 Jun 2016 09:06:21 +0200 Subject: [PATCH 030/320] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 607ea1d3..91893364 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ String token = feed.getToken(); #### Further references -For more examples have a look [here](https://github.com/GetStream/stream-java/tree/milestone1/stream-repo-apache/src/test/java/io/getstream/client/apache/example). +For more examples have a look [here](https://github.com/GetStream/stream-java/tree/master/stream-repo-apache/src/test/java/io/getstream/client/apache/example). Docs are available on [GetStream.io](http://getstream.io/docs/). From 78f7a60133829298bed85ad46985e3d09afa8bdf Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 3 Jun 2016 16:58:23 +0200 Subject: [PATCH 031/320] Added support for ranked feed --- .../client/model/activities/BaseActivity.java | 8 +++++++ .../client/model/filters/FeedFilter.java | 10 +++++++++ .../apache/repo/utils/FeedFilterUtils.java | 3 +++ .../client/apache/IntegrationTest.java | 22 ++++++++++++++++--- .../client/okhttp/IntegrationTest.java | 22 ++++++++++++++++--- 5 files changed, 59 insertions(+), 6 deletions(-) diff --git a/stream-core/src/main/java/io/getstream/client/model/activities/BaseActivity.java b/stream-core/src/main/java/io/getstream/client/model/activities/BaseActivity.java index b6c30f75..e9017bcc 100644 --- a/stream-core/src/main/java/io/getstream/client/model/activities/BaseActivity.java +++ b/stream-core/src/main/java/io/getstream/client/model/activities/BaseActivity.java @@ -53,6 +53,9 @@ public abstract class BaseActivity { protected String object; protected String target; + @JsonProperty("score") + protected Double score; + @JsonDeserialize(using = DateDeserializer.class) @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.S") protected Date time; @@ -146,6 +149,10 @@ public void setForeignId(String foreignId) { this.foreignId = foreignId; } + public Double getScore() { + return score; + } + @JsonIgnore public String getDuration() { return duration; @@ -167,6 +174,7 @@ public String toString() { .add("time", this.time) .add("to", this.to.toString()) .add("origin", this.origin) + .add("score", this.score) .add("duration", this.duration).toString(); } } \ No newline at end of file diff --git a/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java b/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java index 0c1a160c..f8ebf6c0 100644 --- a/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java +++ b/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java @@ -44,6 +44,7 @@ public class FeedFilter { public final static String PARAM_ID_LOWER_THAN = "id_lt"; public final static String PARAM_ID_LOWER_THAN_EQUALS = "id_lte"; public final static String PARAM_FEED_IDS = "filter"; + public final static String PARAM_RANKING = "ranking"; private static final int DEFAULT_LIMIT = 25; @@ -53,6 +54,7 @@ public class FeedFilter { private String idGreaterThanEquals = null; private String idLowerThanEquals = null; private String idLowerThan = null; + private String ranking = null; private List feedIds = null; protected FeedFilter() { @@ -86,6 +88,10 @@ public List getFeedIds() { return feedIds; } + public String getRanking() { + return ranking; + } + /** * Builder to build up a {@link FeedFilter}. */ @@ -135,5 +141,9 @@ public Builder withIdLowerThan(String idLowerThan) { return this; } + public Builder withRanking(String ranking) { + feedFilter.ranking = ranking; + return this; + } } } diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java index 881e4bf2..74af4a00 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java @@ -38,6 +38,9 @@ public static UriBuilder apply(final UriBuilder uriBuilder, final FeedFilter fil if (null != filter.getFeedIds()) { uriBuilder.queryParam(FeedFilter.PARAM_FEED_IDS, Joiner.on(",").join(filter.getFeedIds())); } + if (null != filter.getRanking()) { + uriBuilder.queryParam(FeedFilter.PARAM_RANKING, filter.getRanking()); + } return uriBuilder; } } diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index cf774b6a..be1f1f72 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -1,5 +1,7 @@ package io.getstream.client.apache; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.JWTVerifyException; import com.google.common.collect.ImmutableList; import io.getstream.client.StreamClient; import io.getstream.client.config.ClientConfiguration; @@ -24,13 +26,19 @@ import org.junit.Test; import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SignatureException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; +import static io.getstream.client.util.JwtAuthenticationUtil.ALL; +import static junit.framework.TestCase.assertTrue; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; @@ -53,12 +61,15 @@ public String getTestUserId(String userId) { } @Test - public void shouldGetReadOnlyToken() throws IOException, StreamClientException { + public void shouldGetReadOnlyToken() throws IOException, StreamClientException, NoSuchAlgorithmException, SignatureException, JWTVerifyException, InvalidKeyException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, API_SECRET); Feed feed = streamClient.newFeed("user", "1"); - assertThat(feed.getReadOnlyToken(), is("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3Rpb24iOiJyZWFkIiwicmVzb" + - "3VyY2UiOiIqIiwiZmVlZF9pZCI6InVzZXIxIn0.slCmD5rirATciiL01aE9jXsxjE3NnUwkSgvviUpBhxE")); + + Map map = verifyToken(feed.getReadOnlyToken()); + assertTrue(map.size() > 0); + assertThat(map.get("action").toString(), is("read")); + assertThat(map.get("resource").toString(), is(ALL)); } @Test @@ -710,4 +721,9 @@ public void shouldHaveToken() throws IOException, StreamClientException { String token = feed.getToken(); assertThat(token, notNullValue()); } + + private Map verifyToken(final String token) throws SignatureException, NoSuchAlgorithmException, JWTVerifyException, InvalidKeyException, IOException { + byte[] secret = API_SECRET.getBytes(); + return new JWTVerifier(secret, "audience").verify(token); + } } diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index 03764a13..f2110c3a 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -1,5 +1,7 @@ package io.getstream.client.okhttp; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.JWTVerifyException; import com.google.common.collect.ImmutableList; import io.getstream.client.StreamClient; import io.getstream.client.config.ClientConfiguration; @@ -23,13 +25,19 @@ import org.junit.Test; import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SignatureException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; +import static io.getstream.client.util.JwtAuthenticationUtil.ALL; +import static junit.framework.TestCase.assertTrue; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; @@ -46,12 +54,15 @@ public String getTestUserId(String userId) { } @Test - public void shouldGetReadOnlyToken() throws IOException, StreamClientException { + public void shouldGetReadOnlyToken() throws IOException, StreamClientException, NoSuchAlgorithmException, SignatureException, JWTVerifyException, InvalidKeyException { StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, API_SECRET); Feed feed = streamClient.newFeed("user", "1"); - assertThat(feed.getReadOnlyToken(), is("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3Rpb24iOiJyZWFkIiwicmV" + - "zb3VyY2UiOiIqIiwiZmVlZF9pZCI6InVzZXIxIn0.MywMBtZJzjzSlTU7jfBglJ1NcUeaAWY1uhe6sjB97Wg")); + + Map map = verifyToken(feed.getReadOnlyToken()); + assertTrue(map.size() > 0); + assertThat(map.get("action").toString(), is("read")); + assertThat(map.get("resource").toString(), is(ALL)); } @Test @@ -753,4 +764,9 @@ public void shouldHaveToken() throws IOException, StreamClientException { String token = feed.getToken(); assertThat(token, notNullValue()); } + + private Map verifyToken(final String token) throws SignatureException, NoSuchAlgorithmException, JWTVerifyException, InvalidKeyException, IOException { + byte[] secret = API_SECRET.getBytes(); + return new JWTVerifier(secret, "audience").verify(token); + } } \ No newline at end of file From 9e8f3be1060d879897b8236069c3e79aee217b2f Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 3 Jun 2016 17:03:15 +0200 Subject: [PATCH 032/320] [maven-release-plugin] prepare release stream-java-1.2.0 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 55063785..c96e9629 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.2.0-RC1-SNAPSHOT + 1.2.0 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-1.2.0 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index d506e94a..496ecc72 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.0-RC1-SNAPSHOT + 1.2.0 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index de9bfbc3..0128b392 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.0-RC1-SNAPSHOT + 1.2.0 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 06adbc84..3fb217bb 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.0-RC1-SNAPSHOT + 1.2.0 4.0.0 From 95dde64d94c586a39ca8a3a10b6a0939159d0161 Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 3 Jun 2016 17:03:19 +0200 Subject: [PATCH 033/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index c96e9629..d64c82de 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.2.0 + 1.3.0-RC1-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-1.2.0 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 496ecc72..37d86782 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.0 + 1.3.0-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 0128b392..f91963fa 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.0 + 1.3.0-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 3fb217bb..8ddd1e1a 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.0 + 1.3.0-RC1-SNAPSHOT 4.0.0 From 1cd06d310c24db95bbbff18e2921e8d1fa475671 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Fri, 3 Jun 2016 17:20:59 +0200 Subject: [PATCH 034/320] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 91893364..6a407d03 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 1.1.0 + 1.2.0 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:1.1.0' +compile 'io.getstream.client:stream-repo-apache:1.2.0' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -34,14 +34,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 1.1.0 + 1.2.0 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:1.1.0' +compile 'io.getstream.client:stream-repo-okhttp:1.2.0' ``` In case you want to download the artifact and put it manually into your project, From 4df6a8b6f31bff27a07155ad2038a21381ffef6a Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 21 Dec 2016 17:31:11 +0100 Subject: [PATCH 035/320] Fixed JWT token generation for updateActivities --- .../getstream/client/apache/repo/StreamActivityRepository.java | 2 +- .../getstream/client/okhttp/repo/StreamActivityRepository.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java index b5c33082..978e9161 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java @@ -249,7 +249,7 @@ public StreamActivitiesResponse updateActivities(Bas APPLICATION_JSON) ); - request = StreamRepoUtils.addJwtAuthentication(generateToken(secretKey, "activities", ALL, ALL, null), request); + request = StreamRepoUtils.addJwtAuthentication(generateToken(secretKey, ALL, "activities", ALL, null), request); try (CloseableHttpResponse response = httpClient.execute(request, HttpClientContext.create())) { handleResponseCode(response); diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java index 557c43bd..fd565de0 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java @@ -258,7 +258,7 @@ public StreamActivitiesResponse updateActivities(Bas objectMapper.writeValueAsBytes(Collections.singletonMap("activities", activities)))); Request request = StreamRepoUtils.addJwtAuthentication( - generateToken(secretKey, "activities", ALL, ALL, null), + generateToken(secretKey, ALL, "activities", ALL, null), requestBuilder).build(); LOG.debug("Invoking url: '{}", request.urlString()); From 61eab2f9f75d6d753429faa8bd83e8256b9bfe2f Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 21 Dec 2016 17:31:57 +0100 Subject: [PATCH 036/320] Added QA_TEST region for (blocking) integration tests --- .../getstream/client/config/StreamRegion.java | 3 +- .../client/apache/IntegrationTest.java | 60 +++++++++-------- .../client/okhttp/IntegrationTest.java | 66 ++++++++++--------- 3 files changed, 67 insertions(+), 62 deletions(-) diff --git a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java index bdb8d40f..11163851 100644 --- a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java +++ b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java @@ -45,7 +45,8 @@ public enum StreamRegion { EU_WEST("https://eu-west-api.getstream.io/api"), AP_NORTH_EAST("https://ap-northeast-api.getstream.io/api"), AP_SOUTH_EAST("https://ap-southeast-api.getstream.io/api"), - LOCAL_TEST("http://localhost:8089/api"); /* used for testing purpose only */ + LOCAL_TEST("http://localhost:8089/api"), /* used for testing purpose only */ + QA_TEST("http://qa-api.getstream.io/api"); /* used for integration test */ protected final static String VERSION = "v1.0"; diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index be1f1f72..f01560f2 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableList; import io.getstream.client.StreamClient; import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.config.StreamRegion; import io.getstream.client.exception.AuthenticationFailedException; import io.getstream.client.exception.InvalidOrMissingInputException; import io.getstream.client.exception.StreamClientException; @@ -47,6 +48,7 @@ public class IntegrationTest { public static final String API_KEY = "zdwbqmpxmgh5"; public static final String API_SECRET = "myjspevsc7rh7abz7n27q3emxrtgqnuuhgdx2767qrr9p4wresyw38hsbmz82tbx"; + public static final ClientConfiguration CLIENT_CONFIGURATION = new ClientConfiguration(StreamRegion.QA_TEST); @BeforeClass public static void setLog() { @@ -62,7 +64,7 @@ public String getTestUserId(String userId) { @Test public void shouldGetReadOnlyToken() throws IOException, StreamClientException, NoSuchAlgorithmException, SignatureException, JWTVerifyException, InvalidKeyException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); Feed feed = streamClient.newFeed("user", "1"); @@ -74,7 +76,7 @@ public void shouldGetReadOnlyToken() throws IOException, StreamClientException, @Test public void shouldGetFollowers() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String followerId = this.getTestUserId("shouldGetFollowers"); String followedId = this.getTestUserId("shouldGetFollowersFollowed"); @@ -94,7 +96,7 @@ public void shouldGetFollowers() throws IOException, StreamClientException { @Test public void shouldFollow() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String followerId = this.getTestUserId("shouldFollow"); @@ -119,7 +121,7 @@ public void shouldFollow() throws IOException, StreamClientException { @Test public void shouldFollowWithActivityCopyLimit() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String followerId = this.getTestUserId("shouldFollow"); @@ -138,7 +140,7 @@ public void shouldFollowWithActivityCopyLimit() throws IOException, StreamClient @Test public void shouldFollowMany() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String followerId = this.getTestUserId("shouldFollowMany"); @@ -166,7 +168,7 @@ public void shouldFollowMany() throws IOException, StreamClientException { @Test public void shouldHaveOriginField() throws IOException, StreamClientException, InterruptedException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String producerId = this.getTestUserId("shouldHaveOriginField1"); @@ -195,7 +197,7 @@ public void shouldHaveOriginField() throws IOException, StreamClientException, I @Test public void shouldUnfollow() throws IOException, StreamClientException, InterruptedException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String followerId = this.getTestUserId("follower"); @@ -220,7 +222,7 @@ public void shouldUnfollow() throws IOException, StreamClientException, Interrup @Test public void shouldGetActivities() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldGetActivities"); @@ -240,7 +242,7 @@ public void shouldGetActivities() throws IOException, StreamClientException { @Test public void shouldAddActivity() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddActivity"); @@ -260,7 +262,7 @@ public void shouldAddActivity() throws IOException, StreamClientException { @Test public void shouldAddActivities() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddActivity"); @@ -292,7 +294,7 @@ public void shouldAddActivities() throws IOException, StreamClientException { @Test public void shouldUpdateActivities() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddActivity"); @@ -314,7 +316,7 @@ public void shouldUpdateActivities() throws IOException, StreamClientException { @Test public void shouldAddActivityToMany() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddActivityToMany"); @@ -331,7 +333,7 @@ public void shouldAddActivityToMany() throws IOException, StreamClientException @Test public void shouldAddActivityToRecipients() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); Feed feed = streamClient.newFeed("user", "2"); @@ -348,7 +350,7 @@ public void shouldAddActivityToRecipients() throws IOException, StreamClientExce @Test public void shouldAddAndRetrieveActivity() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddAndRetrieveActivityToRecipients"); @@ -369,7 +371,7 @@ public void shouldAddAndRetrieveActivity() throws IOException, StreamClientExcep @Test public void shouldAddAndRetrieveActivityToRecipients() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddAndRetrieveActivityToRecipients"); String recipientId1 = this.getTestUserId("shouldAddAndRetrieveActivityToRecipients1"); @@ -405,7 +407,7 @@ public void shouldAddAndRetrieveActivityToRecipients() throws IOException, Strea @Test public void shouldReturnActivityIdAfterInsert() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldReturnActivityId"); @@ -425,7 +427,7 @@ public void shouldReturnActivityIdAfterInsert() throws IOException, StreamClient @Test public void shouldActivityShouldHaveId() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldActivityShouldHaveId"); @@ -447,7 +449,7 @@ public void shouldActivityShouldHaveId() throws IOException, StreamClientExcepti @Test public void shouldRemoveActivity() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldRemoveActivity"); @@ -476,7 +478,7 @@ public void shouldRemoveActivity() throws IOException, StreamClientException { @Test public void shouldRemoveActivityByForeignId() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldRemoveActivity"); @@ -505,7 +507,7 @@ public void shouldRemoveActivityByForeignId() throws IOException, StreamClientEx } @Test public void shouldGetActivitiesWithFilter() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldGetActivitiesWithFilter"); Feed feed = streamClient.newFeed("user", userId); @@ -516,7 +518,7 @@ public void shouldGetActivitiesWithFilter() throws IOException, StreamClientExce @Test public void shouldGetActivitiesWithIdFilter() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldGetActivitiesWithIdFilter"); SimpleActivity activity = new SimpleActivity(); @@ -555,7 +557,7 @@ public void shouldGetActivitiesWithIdFilter() throws IOException, StreamClientEx @Test(expected = InvalidOrMissingInputException.class) public void shouldGetInvalidOrMissingInputException() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); Feed feed = streamClient.newFeed("foo", "2"); @@ -566,7 +568,7 @@ public void shouldGetInvalidOrMissingInputException() throws IOException, Stream @Test(expected = AuthenticationFailedException.class) public void shouldGetAuthenticationFailed() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, "foo"); Feed feed = streamClient.newFeed("user", "2"); @@ -576,7 +578,7 @@ public void shouldGetAuthenticationFailed() throws IOException, StreamClientExce @Test public void shouldGetActivitiesFromNotificationFeed() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = getTestUserId("shouldGetActivitiesFromNotificationFeed"); Feed feed = streamClient.newFeed("notification", userId); @@ -589,7 +591,7 @@ public void shouldGetActivitiesFromNotificationFeed() throws IOException, Stream @Test public void shouldGetActivitiesFromNotificationFeedAndMarkThem() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = getTestUserId("shouldGetActivitiesFromNotificationFeedAndMarkThem"); Feed feed = streamClient.newFeed("notification", userId); @@ -624,7 +626,7 @@ public void shouldGetActivitiesFromNotificationFeedAndMarkThem() throws IOExcept @Test public void shouldGetActivitiesFromNotificationFeedAndMarkThemById() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = getTestUserId("shouldGetActivitiesFromNotificationFeedAndMarkThemById"); Feed feed = streamClient.newFeed("notification", userId); @@ -664,7 +666,7 @@ public void shouldGetActivitiesFromNotificationFeedAndMarkThemById() throws IOEx @Test public void shouldGetActivitiesFromEmptyAggregatedFeed() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("2"); @@ -678,7 +680,7 @@ public void shouldGetActivitiesFromEmptyAggregatedFeed() throws IOException, Str @Test public void shouldGetActivitiesFromAggregatedFeed() throws IOException, StreamClientException, InterruptedException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = getTestUserId("shouldGetActivitiesFromAggregatedFeed"); @@ -715,7 +717,7 @@ public void shouldGetActivitiesFromAggregatedFeed() throws IOException, StreamCl @Test public void shouldHaveToken() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); Feed feed = streamClient.newFeed("aggregated", "whatever"); String token = feed.getToken(); diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index f2110c3a..9e620e6c 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableList; import io.getstream.client.StreamClient; import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.config.StreamRegion; import io.getstream.client.exception.AuthenticationFailedException; import io.getstream.client.exception.InvalidOrMissingInputException; import io.getstream.client.exception.StreamClientException; @@ -47,7 +48,8 @@ public class IntegrationTest { public static final String API_KEY = "aygdeg2vhjxg"; public static final String API_SECRET = "4vknf33hn4n94exgrg367jbmg4jxetem93bqcg3nkdf2xau3q8pmy3pftytq4w8v"; - + public static final ClientConfiguration CLIENT_CONFIGURATION = new ClientConfiguration(StreamRegion.QA_TEST); + public String getTestUserId(String userId) { long millis = System.currentTimeMillis(); return String.format("%s_%d", userId, millis); @@ -55,7 +57,7 @@ public String getTestUserId(String userId) { @Test public void shouldGetReadOnlyToken() throws IOException, StreamClientException, NoSuchAlgorithmException, SignatureException, JWTVerifyException, InvalidKeyException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); Feed feed = streamClient.newFeed("user", "1"); @@ -67,7 +69,7 @@ public void shouldGetReadOnlyToken() throws IOException, StreamClientException, @Test public void shouldGetFollowers() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String followerId = this.getTestUserId("shouldGetFollowers"); String followedId = this.getTestUserId("shouldGetFollowersFollowed"); @@ -88,7 +90,7 @@ public void shouldGetFollowers() throws IOException, StreamClientException { @Test public void shouldFollow() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String followerId = this.getTestUserId("follower"); @@ -113,7 +115,7 @@ public void shouldFollow() throws IOException, StreamClientException { @Test public void shouldFollowWithActivityCopyLimit() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String followerId = this.getTestUserId("shouldFollow"); @@ -132,7 +134,7 @@ public void shouldFollowWithActivityCopyLimit() throws IOException, StreamClient @Test public void shouldFollowMany() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String followerId = this.getTestUserId("follower"); @@ -160,7 +162,7 @@ public void shouldFollowMany() throws IOException, StreamClientException { @Test public void shouldFollowManyWithActivityCopyLimit() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String followerId = this.getTestUserId("follower"); @@ -188,7 +190,7 @@ public void shouldFollowManyWithActivityCopyLimit() throws IOException, StreamCl @Test public void shouldHaveOriginField() throws IOException, StreamClientException, InterruptedException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String producerId = this.getTestUserId("shouldHaveOriginField1"); @@ -217,7 +219,7 @@ public void shouldHaveOriginField() throws IOException, StreamClientException, I @Test public void shouldUnfollow() throws IOException, StreamClientException, InterruptedException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String followerId = this.getTestUserId("follower"); @@ -242,7 +244,7 @@ public void shouldUnfollow() throws IOException, StreamClientException, Interrup @Test public void shouldGetActivities() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldGetActivities"); @@ -262,7 +264,7 @@ public void shouldGetActivities() throws IOException, StreamClientException { @Test public void shouldAddActivityWithTime() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddActivity"); @@ -280,7 +282,7 @@ public void shouldAddActivityWithTime() throws IOException, StreamClientExceptio @Test public void shouldAddActivity() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddActivity"); @@ -297,7 +299,7 @@ public void shouldAddActivity() throws IOException, StreamClientException { @Test public void shouldAddActivities() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddActivity"); @@ -329,7 +331,7 @@ public void shouldAddActivities() throws IOException, StreamClientException { @Test public void shouldUpdateActivity() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddActivity"); @@ -351,7 +353,7 @@ public void shouldUpdateActivity() throws IOException, StreamClientException { @Test public void shouldAddActivityToMany() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddActivity"); @@ -372,7 +374,7 @@ public void shouldAddActivityToMany() throws IOException, StreamClientException @Test public void shouldAddActivityToRecipients() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); Feed feed = streamClient.newFeed("user", "2"); @@ -389,7 +391,7 @@ public void shouldAddActivityToRecipients() throws IOException, StreamClientExce @Test public void shouldAddAndRetrieveActivity() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddAndRetrieveActivityToRecipients"); @@ -410,7 +412,7 @@ public void shouldAddAndRetrieveActivity() throws IOException, StreamClientExcep @Test public void shouldAddAndRetrieveActivityToRecipients() throws IOException, StreamClientException, InterruptedException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldAddAndRetrieveActivityToRecipients"); String recipientId1 = this.getTestUserId("shouldAddAndRetrieveActivityToRecipients1"); @@ -451,7 +453,7 @@ public void shouldAddAndRetrieveActivityToRecipients() throws IOException, Strea @Test public void shouldReturnActivityIdAfterInsert() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldReturnActivityId"); @@ -471,7 +473,7 @@ public void shouldReturnActivityIdAfterInsert() throws IOException, StreamClient @Test public void shouldActivityShouldHaveId() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldActivityShouldHaveId"); @@ -493,7 +495,7 @@ public void shouldActivityShouldHaveId() throws IOException, StreamClientExcepti @Test public void shouldRemoveActivity() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldRemoveActivity"); @@ -522,7 +524,7 @@ public void shouldRemoveActivity() throws IOException, StreamClientException { @Test public void shouldRemoveActivityByForeignId() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldRemoveActivity"); @@ -551,7 +553,7 @@ public void shouldRemoveActivityByForeignId() throws IOException, StreamClientEx } @Test public void shouldGetActivitiesWithFilter() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldGetActivitiesWithFilter"); Feed feed = streamClient.newFeed("user", userId); @@ -562,7 +564,7 @@ public void shouldGetActivitiesWithFilter() throws IOException, StreamClientExce @Test public void shouldGetActivitiesWithIdFilter() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldGetActivitiesWithIdFilter"); SimpleActivity activity = new SimpleActivity(); @@ -601,7 +603,7 @@ public void shouldGetActivitiesWithIdFilter() throws IOException, StreamClientEx @Test(expected = InvalidOrMissingInputException.class) public void shouldGetInvalidOrMissingInputException() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); Feed feed = streamClient.newFeed("foo", "2"); @@ -612,7 +614,7 @@ public void shouldGetInvalidOrMissingInputException() throws IOException, Stream @Test(expected = AuthenticationFailedException.class) public void shouldGetAuthenticationFailed() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, "foo"); Feed feed = streamClient.newFeed("user", "2"); @@ -622,7 +624,7 @@ public void shouldGetAuthenticationFailed() throws IOException, StreamClientExce @Test public void shouldGetActivitiesFromNotificationFeed() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = getTestUserId("shouldGetActivitiesFromNotificationFeed"); Feed feed = streamClient.newFeed("notification", userId); @@ -635,7 +637,7 @@ public void shouldGetActivitiesFromNotificationFeed() throws IOException, Stream @Test public void shouldGetActivitiesFromNotificationFeedAndMarkThem() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = getTestUserId("shouldGetActivitiesFromNotificationFeedAndMarkThem"); Feed feed = streamClient.newFeed("notification", userId); @@ -670,7 +672,7 @@ public void shouldGetActivitiesFromNotificationFeedAndMarkThem() throws IOExcept @Test public void shouldGetActivitiesFromNotificationFeedAndMarkThemById() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = getTestUserId("shouldGetActivitiesFromNotificationFeedAndMarkThemById"); Feed feed = streamClient.newFeed("notification", userId); @@ -710,7 +712,7 @@ public void shouldGetActivitiesFromNotificationFeedAndMarkThemById() throws IOEx @Test public void shouldGetActivitiesFromEmptyAggregatedFeed() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("2"); @@ -724,7 +726,7 @@ public void shouldGetActivitiesFromEmptyAggregatedFeed() throws IOException, Str @Test public void shouldGetActivitiesFromAggregatedFeed() throws IOException, StreamClientException, InterruptedException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); String userId = this.getTestUserId("shouldGetActivitiesFromAggregatedFeed"); @@ -758,7 +760,7 @@ public void shouldGetActivitiesFromAggregatedFeed() throws IOException, StreamCl @Test public void shouldHaveToken() throws IOException, StreamClientException { - StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), API_KEY, + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); Feed feed = streamClient.newFeed("aggregated", "whatever"); String token = feed.getToken(); From 8645e2525c9ad23189cdc3d411a04cb96bb40601 Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 21 Dec 2016 17:40:38 +0100 Subject: [PATCH 037/320] [maven-release-plugin] prepare release stream-java-1.2.1 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index d64c82de..86bbb510 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.3.0-RC1-SNAPSHOT + 1.2.1 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-1.2.1 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 37d86782..1c3bc794 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.0-RC1-SNAPSHOT + 1.2.1 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index f91963fa..0f72c412 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.0-RC1-SNAPSHOT + 1.2.1 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 8ddd1e1a..f2478c06 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.0-RC1-SNAPSHOT + 1.2.1 4.0.0 From eb65fd5c4d6ec5787cb4641930f336c059275875 Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 21 Dec 2016 17:40:46 +0100 Subject: [PATCH 038/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 86bbb510..efd8beed 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.2.1 + 1.2.2-RC1-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-1.2.1 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 1c3bc794..0764b456 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.1 + 1.2.2-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 0f72c412..af81720b 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.1 + 1.2.2-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index f2478c06..0083ff5c 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.1 + 1.2.2-RC1-SNAPSHOT 4.0.0 From 42adf1a11c8ab47fcf6dd2a248f7b168d5cb3bca Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 21 Dec 2016 17:47:53 +0100 Subject: [PATCH 039/320] Updated version on README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6a407d03..a9e1819f 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 1.2.0 + 1.2.1 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:1.2.0' +compile 'io.getstream.client:stream-repo-apache:1.2.1' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -34,14 +34,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 1.2.0 + 1.2.1 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:1.2.0' +compile 'io.getstream.client:stream-repo-okhttp:1.2.1' ``` In case you want to download the artifact and put it manually into your project, From 09d56aab461dabb27c680e357e14fc2cc00aee36 Mon Sep 17 00:00:00 2001 From: Dwight Gunning Date: Wed, 15 Mar 2017 17:38:47 +0100 Subject: [PATCH 040/320] Update copyright for 2017. Add copyright and license section to README --- LICENSE | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 6 ++++++ 2 files changed, 54 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..8a25cc4d --- /dev/null +++ b/LICENSE @@ -0,0 +1,48 @@ +Copyright (c) 2016-2017 Stream.io Inc, and individual contributors. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted +provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of + conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +This software incorporates additional Open Source components. You can find the source code of these +open source projects along with license information below. + + Base64.java: + + https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/Base64.java + + Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index a9e1819f..c19c3a0f 100644 --- a/README.md +++ b/README.md @@ -155,3 +155,9 @@ For more examples have a look [here](https://github.com/GetStream/stream-java/tr Docs are available on [GetStream.io](http://getstream.io/docs/). Javadocs are available [here](https://getstream.github.io/stream-java/). + +### Copyright and License Information + +Copyright (c) 2016-2017 Stream.io Inc, and individual contributors. All rights reserved. + +See the file "LICENSE" for information on the history of this software, terms & conditions for usage, and a DISCLAIMER OF ALL WARRANTIES. From f89d6530b38369583ba1cdfc8befc72fa66f2a57 Mon Sep 17 00:00:00 2001 From: Dwight Gunning Date: Wed, 15 Mar 2017 17:40:21 +0100 Subject: [PATCH 041/320] Update pom manifests to BSD-3 License and remove file license headers --- pom.xml | 4 +-- stream-core/pom.xml | 4 +-- .../io/getstream/client/StreamClient.java | 30 ------------------- .../AuthenticationHandlerConfiguration.java | 30 ------------------- .../client/config/ClientConfiguration.java | 30 ------------------- .../getstream/client/config/StreamRegion.java | 30 ------------------- .../AuthenticationFailedException.java | 30 ------------------- .../exception/InternalServerException.java | 30 ------------------- .../exception/InvalidFeedNameException.java | 30 ------------------- .../InvalidOrMissingInputException.java | 30 ------------------- .../exception/ResourceNotFoundException.java | 30 ------------------- .../exception/StreamClientException.java | 30 ------------------- .../client/exception/UriBuilderException.java | 30 ------------------- .../ActivitySignedRecipientDeserializer.java | 30 ------------------- .../model/activities/AggregatedActivity.java | 30 ------------------- .../client/model/activities/BaseActivity.java | 30 ------------------- .../activities/NotificationActivity.java | 30 ------------------- .../model/activities/SimpleActivity.java | 30 ------------------- .../model/activities/WrappedActivity.java | 30 ------------------- .../client/model/beans/FeedFollow.java | 30 ------------------- .../client/model/beans/MarkedActivity.java | 30 ------------------- .../model/beans/StreamActivitiesResponse.java | 30 ------------------- .../model/beans/StreamErrorResponse.java | 30 ------------------- .../client/model/beans/StreamResponse.java | 30 ------------------- .../client/model/feeds/BaseFeed.java | 30 ------------------- .../client/model/feeds/BaseFeedFactory.java | 30 ------------------- .../io/getstream/client/model/feeds/Feed.java | 30 ------------------- .../client/model/feeds/FeedFactory.java | 30 ------------------- .../client/model/filters/FeedFilter.java | 30 ------------------- .../client/repo/StreamRepoFactory.java | 30 ------------------- .../client/repo/StreamRepository.java | 30 ------------------- .../service/AbstractActivityService.java | 30 ------------------- .../service/AggregatedActivityService.java | 30 ------------------- .../AggregatedActivityServiceImpl.java | 30 ------------------- .../client/service/FlatActivityService.java | 30 ------------------- .../service/FlatActivityServiceImpl.java | 30 ------------------- .../service/NotificationActivityService.java | 30 ------------------- .../NotificationActivityServiceImpl.java | 30 ------------------- .../client/service/UserActivityService.java | 30 ------------------- .../service/UserActivityServiceImpl.java | 30 ------------------- .../io/getstream/client/util/InfoUtil.java | 30 ------------------- stream-repo-apache/pom.xml | 4 +-- .../client/apache/StreamClientImpl.java | 30 ------------------- .../apache/repo/StreamActivityRepository.java | 30 ------------------- .../apache/repo/StreamRepoFactoryImpl.java | 30 ------------------- .../apache/repo/StreamRepositoryImpl.java | 30 ------------------- .../repo/handlers/StreamExceptionHandler.java | 30 ------------------- .../apache/repo/utils/SignatureUtils.java | 30 ------------------- .../apache/repo/utils/StreamRepoUtils.java | 30 ------------------- .../client/apache/repo/utils/UriBuilder.java | 30 ------------------- stream-repo-okhttp/pom.xml | 4 +-- .../client/okhttp/StreamClientImpl.java | 30 ------------------- .../okhttp/repo/StreamActivityRepository.java | 30 ------------------- .../okhttp/repo/StreamRepoFactoryImpl.java | 30 ------------------- .../okhttp/repo/StreamRepositoryImpl.java | 30 ------------------- .../repo/handlers/StreamExceptionHandler.java | 30 ------------------- .../okhttp/repo/utils/SignatureUtils.java | 30 ------------------- .../okhttp/repo/utils/StreamRepoUtils.java | 30 ------------------- .../client/okhttp/repo/utils/UriBuilder.java | 30 ------------------- 59 files changed, 8 insertions(+), 1658 deletions(-) diff --git a/pom.xml b/pom.xml index efd8beed..cefaea58 100644 --- a/pom.xml +++ b/pom.xml @@ -13,8 +13,8 @@ - The New BSD License - http://www.opensource.org/licenses/bsd-license.html + The 3-Clause BSD License + https://opensource.org/licenses/BSD-3-Clause Apache License, Version 2.0 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 0764b456..025b4e60 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -9,8 +9,8 @@ - The New BSD License - http://www.opensource.org/licenses/bsd-license.html + The 3-Clause BSD License + https://opensource.org/licenses/BSD-3-Clause Apache License, Version 2.0 diff --git a/stream-core/src/main/java/io/getstream/client/StreamClient.java b/stream-core/src/main/java/io/getstream/client/StreamClient.java index e5a988af..a6bce0ba 100644 --- a/stream-core/src/main/java/io/getstream/client/StreamClient.java +++ b/stream-core/src/main/java/io/getstream/client/StreamClient.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client; import io.getstream.client.exception.InvalidFeedNameException; diff --git a/stream-core/src/main/java/io/getstream/client/config/AuthenticationHandlerConfiguration.java b/stream-core/src/main/java/io/getstream/client/config/AuthenticationHandlerConfiguration.java index 356b57e0..fcd0054f 100644 --- a/stream-core/src/main/java/io/getstream/client/config/AuthenticationHandlerConfiguration.java +++ b/stream-core/src/main/java/io/getstream/client/config/AuthenticationHandlerConfiguration.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.config; /** diff --git a/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java b/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java index 403a6a4a..95f0117e 100644 --- a/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java +++ b/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.config; import com.fasterxml.jackson.core.type.TypeReference; diff --git a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java index 11163851..2fad465b 100644 --- a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java +++ b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.config; import io.getstream.client.exception.UriBuilderException; diff --git a/stream-core/src/main/java/io/getstream/client/exception/AuthenticationFailedException.java b/stream-core/src/main/java/io/getstream/client/exception/AuthenticationFailedException.java index af3e8d11..a3a80474 100644 --- a/stream-core/src/main/java/io/getstream/client/exception/AuthenticationFailedException.java +++ b/stream-core/src/main/java/io/getstream/client/exception/AuthenticationFailedException.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.exception; /** diff --git a/stream-core/src/main/java/io/getstream/client/exception/InternalServerException.java b/stream-core/src/main/java/io/getstream/client/exception/InternalServerException.java index d13ffe81..b99200b6 100644 --- a/stream-core/src/main/java/io/getstream/client/exception/InternalServerException.java +++ b/stream-core/src/main/java/io/getstream/client/exception/InternalServerException.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.exception; /** diff --git a/stream-core/src/main/java/io/getstream/client/exception/InvalidFeedNameException.java b/stream-core/src/main/java/io/getstream/client/exception/InvalidFeedNameException.java index d18448f8..dc5fe7a0 100644 --- a/stream-core/src/main/java/io/getstream/client/exception/InvalidFeedNameException.java +++ b/stream-core/src/main/java/io/getstream/client/exception/InvalidFeedNameException.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.exception; /** diff --git a/stream-core/src/main/java/io/getstream/client/exception/InvalidOrMissingInputException.java b/stream-core/src/main/java/io/getstream/client/exception/InvalidOrMissingInputException.java index 106cbe36..0c2f7f0e 100644 --- a/stream-core/src/main/java/io/getstream/client/exception/InvalidOrMissingInputException.java +++ b/stream-core/src/main/java/io/getstream/client/exception/InvalidOrMissingInputException.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.exception; /** diff --git a/stream-core/src/main/java/io/getstream/client/exception/ResourceNotFoundException.java b/stream-core/src/main/java/io/getstream/client/exception/ResourceNotFoundException.java index 55cb9354..b0658c57 100644 --- a/stream-core/src/main/java/io/getstream/client/exception/ResourceNotFoundException.java +++ b/stream-core/src/main/java/io/getstream/client/exception/ResourceNotFoundException.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.exception; /** diff --git a/stream-core/src/main/java/io/getstream/client/exception/StreamClientException.java b/stream-core/src/main/java/io/getstream/client/exception/StreamClientException.java index 51819aa8..716bc098 100644 --- a/stream-core/src/main/java/io/getstream/client/exception/StreamClientException.java +++ b/stream-core/src/main/java/io/getstream/client/exception/StreamClientException.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.exception; import com.google.common.base.MoreObjects; diff --git a/stream-core/src/main/java/io/getstream/client/exception/UriBuilderException.java b/stream-core/src/main/java/io/getstream/client/exception/UriBuilderException.java index 488ee897..a503c8e8 100644 --- a/stream-core/src/main/java/io/getstream/client/exception/UriBuilderException.java +++ b/stream-core/src/main/java/io/getstream/client/exception/UriBuilderException.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.exception; /** diff --git a/stream-core/src/main/java/io/getstream/client/model/activities/ActivitySignedRecipientDeserializer.java b/stream-core/src/main/java/io/getstream/client/model/activities/ActivitySignedRecipientDeserializer.java index eae66aa3..0c68fff1 100644 --- a/stream-core/src/main/java/io/getstream/client/model/activities/ActivitySignedRecipientDeserializer.java +++ b/stream-core/src/main/java/io/getstream/client/model/activities/ActivitySignedRecipientDeserializer.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.activities; import com.fasterxml.jackson.core.JsonParser; diff --git a/stream-core/src/main/java/io/getstream/client/model/activities/AggregatedActivity.java b/stream-core/src/main/java/io/getstream/client/model/activities/AggregatedActivity.java index 43a5f81c..6c3a54ac 100644 --- a/stream-core/src/main/java/io/getstream/client/model/activities/AggregatedActivity.java +++ b/stream-core/src/main/java/io/getstream/client/model/activities/AggregatedActivity.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.activities; public class AggregatedActivity extends WrappedActivity { diff --git a/stream-core/src/main/java/io/getstream/client/model/activities/BaseActivity.java b/stream-core/src/main/java/io/getstream/client/model/activities/BaseActivity.java index e9017bcc..b401feac 100644 --- a/stream-core/src/main/java/io/getstream/client/model/activities/BaseActivity.java +++ b/stream-core/src/main/java/io/getstream/client/model/activities/BaseActivity.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.activities; import com.fasterxml.jackson.annotation.JsonFormat; diff --git a/stream-core/src/main/java/io/getstream/client/model/activities/NotificationActivity.java b/stream-core/src/main/java/io/getstream/client/model/activities/NotificationActivity.java index f91dd002..6a26cfa9 100644 --- a/stream-core/src/main/java/io/getstream/client/model/activities/NotificationActivity.java +++ b/stream-core/src/main/java/io/getstream/client/model/activities/NotificationActivity.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.activities; import com.fasterxml.jackson.annotation.JsonIgnore; diff --git a/stream-core/src/main/java/io/getstream/client/model/activities/SimpleActivity.java b/stream-core/src/main/java/io/getstream/client/model/activities/SimpleActivity.java index bd9cb0c8..7b06de8f 100644 --- a/stream-core/src/main/java/io/getstream/client/model/activities/SimpleActivity.java +++ b/stream-core/src/main/java/io/getstream/client/model/activities/SimpleActivity.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.activities; /** diff --git a/stream-core/src/main/java/io/getstream/client/model/activities/WrappedActivity.java b/stream-core/src/main/java/io/getstream/client/model/activities/WrappedActivity.java index 22e2bf34..9cc0a55d 100644 --- a/stream-core/src/main/java/io/getstream/client/model/activities/WrappedActivity.java +++ b/stream-core/src/main/java/io/getstream/client/model/activities/WrappedActivity.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.activities; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/FeedFollow.java b/stream-core/src/main/java/io/getstream/client/model/beans/FeedFollow.java index ec7940ff..336d0130 100644 --- a/stream-core/src/main/java/io/getstream/client/model/beans/FeedFollow.java +++ b/stream-core/src/main/java/io/getstream/client/model/beans/FeedFollow.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.beans; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/MarkedActivity.java b/stream-core/src/main/java/io/getstream/client/model/beans/MarkedActivity.java index d0b56374..03723e27 100644 --- a/stream-core/src/main/java/io/getstream/client/model/beans/MarkedActivity.java +++ b/stream-core/src/main/java/io/getstream/client/model/beans/MarkedActivity.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.beans; import com.google.common.base.Joiner; diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java b/stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java index 5d6b050e..c62c5831 100644 --- a/stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java +++ b/stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.beans; import io.getstream.client.model.activities.BaseActivity; diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/StreamErrorResponse.java b/stream-core/src/main/java/io/getstream/client/model/beans/StreamErrorResponse.java index c77f2862..687d3839 100644 --- a/stream-core/src/main/java/io/getstream/client/model/beans/StreamErrorResponse.java +++ b/stream-core/src/main/java/io/getstream/client/model/beans/StreamErrorResponse.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.beans; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/StreamResponse.java b/stream-core/src/main/java/io/getstream/client/model/beans/StreamResponse.java index bfde24f8..93afb9d4 100644 --- a/stream-core/src/main/java/io/getstream/client/model/beans/StreamResponse.java +++ b/stream-core/src/main/java/io/getstream/client/model/beans/StreamResponse.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.beans; import java.util.List; diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java index c93cf553..0c066b9d 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.feeds; import io.getstream.client.exception.StreamClientException; diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeedFactory.java b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeedFactory.java index 275b467b..de76f58c 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeedFactory.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeedFactory.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.feeds; import io.getstream.client.exception.InvalidFeedNameException; diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java b/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java index 46aca1c3..740a9425 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.feeds; import io.getstream.client.exception.StreamClientException; diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java b/stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java index d5066493..e6ca0836 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.feeds; import io.getstream.client.exception.InvalidFeedNameException; diff --git a/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java b/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java index f8ebf6c0..1928ea7b 100644 --- a/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java +++ b/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.model.filters; import java.util.List; diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamRepoFactory.java b/stream-core/src/main/java/io/getstream/client/repo/StreamRepoFactory.java index 32caa66d..4843e5c6 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamRepoFactory.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamRepoFactory.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.repo; import io.getstream.client.config.AuthenticationHandlerConfiguration; diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java index 4d173592..28a933a0 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.repo; import io.getstream.client.exception.StreamClientException; diff --git a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java index e36c2393..1076509e 100644 --- a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java +++ b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.service; import io.getstream.client.exception.StreamClientException; diff --git a/stream-core/src/main/java/io/getstream/client/service/AggregatedActivityService.java b/stream-core/src/main/java/io/getstream/client/service/AggregatedActivityService.java index 0892a60c..b37bfb98 100644 --- a/stream-core/src/main/java/io/getstream/client/service/AggregatedActivityService.java +++ b/stream-core/src/main/java/io/getstream/client/service/AggregatedActivityService.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.service; import io.getstream.client.exception.StreamClientException; diff --git a/stream-core/src/main/java/io/getstream/client/service/AggregatedActivityServiceImpl.java b/stream-core/src/main/java/io/getstream/client/service/AggregatedActivityServiceImpl.java index 8e0f3c07..74aee01f 100644 --- a/stream-core/src/main/java/io/getstream/client/service/AggregatedActivityServiceImpl.java +++ b/stream-core/src/main/java/io/getstream/client/service/AggregatedActivityServiceImpl.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.service; import io.getstream.client.exception.StreamClientException; diff --git a/stream-core/src/main/java/io/getstream/client/service/FlatActivityService.java b/stream-core/src/main/java/io/getstream/client/service/FlatActivityService.java index bc0b581e..4e3b9584 100644 --- a/stream-core/src/main/java/io/getstream/client/service/FlatActivityService.java +++ b/stream-core/src/main/java/io/getstream/client/service/FlatActivityService.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.service; import io.getstream.client.exception.StreamClientException; diff --git a/stream-core/src/main/java/io/getstream/client/service/FlatActivityServiceImpl.java b/stream-core/src/main/java/io/getstream/client/service/FlatActivityServiceImpl.java index 0f0fb009..8b1418df 100644 --- a/stream-core/src/main/java/io/getstream/client/service/FlatActivityServiceImpl.java +++ b/stream-core/src/main/java/io/getstream/client/service/FlatActivityServiceImpl.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.service; import io.getstream.client.model.activities.BaseActivity; diff --git a/stream-core/src/main/java/io/getstream/client/service/NotificationActivityService.java b/stream-core/src/main/java/io/getstream/client/service/NotificationActivityService.java index 64df69e4..dca97a90 100644 --- a/stream-core/src/main/java/io/getstream/client/service/NotificationActivityService.java +++ b/stream-core/src/main/java/io/getstream/client/service/NotificationActivityService.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.service; import io.getstream.client.exception.StreamClientException; diff --git a/stream-core/src/main/java/io/getstream/client/service/NotificationActivityServiceImpl.java b/stream-core/src/main/java/io/getstream/client/service/NotificationActivityServiceImpl.java index 72113002..c24f7c9b 100644 --- a/stream-core/src/main/java/io/getstream/client/service/NotificationActivityServiceImpl.java +++ b/stream-core/src/main/java/io/getstream/client/service/NotificationActivityServiceImpl.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.service; import io.getstream.client.exception.StreamClientException; diff --git a/stream-core/src/main/java/io/getstream/client/service/UserActivityService.java b/stream-core/src/main/java/io/getstream/client/service/UserActivityService.java index 8ca422a4..5ca1afee 100644 --- a/stream-core/src/main/java/io/getstream/client/service/UserActivityService.java +++ b/stream-core/src/main/java/io/getstream/client/service/UserActivityService.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.service; import io.getstream.client.exception.StreamClientException; diff --git a/stream-core/src/main/java/io/getstream/client/service/UserActivityServiceImpl.java b/stream-core/src/main/java/io/getstream/client/service/UserActivityServiceImpl.java index c409b353..2c96ac91 100644 --- a/stream-core/src/main/java/io/getstream/client/service/UserActivityServiceImpl.java +++ b/stream-core/src/main/java/io/getstream/client/service/UserActivityServiceImpl.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.service; import io.getstream.client.exception.StreamClientException; diff --git a/stream-core/src/main/java/io/getstream/client/util/InfoUtil.java b/stream-core/src/main/java/io/getstream/client/util/InfoUtil.java index f1d5e15a..d3b1c0e0 100644 --- a/stream-core/src/main/java/io/getstream/client/util/InfoUtil.java +++ b/stream-core/src/main/java/io/getstream/client/util/InfoUtil.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.util; import com.google.common.io.Resources; diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index af81720b..4d89ae1e 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -11,8 +11,8 @@ - The New BSD License - http://www.opensource.org/licenses/bsd-license.html + The 3-Clause BSD License + https://opensource.org/licenses/BSD-3-Clause Apache License, Version 2.0 diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java index f706a933..8e9311fa 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.apache; import com.google.common.base.Preconditions; diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java index 978e9161..3400e0ac 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.apache.repo; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepoFactoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepoFactoryImpl.java index a88c212e..0965509f 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepoFactoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepoFactoryImpl.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.apache.repo; import io.getstream.client.config.AuthenticationHandlerConfiguration; diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index 9d815377..7e530c2a 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.apache.repo; import com.fasterxml.jackson.core.type.TypeReference; diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java index 67a9f40e..2a9e1ea6 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.apache.repo.handlers; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/SignatureUtils.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/SignatureUtils.java index e9706dce..0d14ec31 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/SignatureUtils.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/SignatureUtils.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.apache.repo.utils; import com.google.common.collect.ImmutableList; diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java index d89e3fdf..63586540 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.apache.repo.utils; import io.getstream.client.model.feeds.BaseFeed; diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/UriBuilder.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/UriBuilder.java index ba85dd20..c0c6b5e1 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/UriBuilder.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/UriBuilder.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.apache.repo.utils; import io.getstream.client.exception.UriBuilderException; diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 0083ff5c..0e9abec1 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -11,8 +11,8 @@ - The New BSD License - http://www.opensource.org/licenses/bsd-license.html + The 3-Clause BSD License + https://opensource.org/licenses/BSD-3-Clause Apache License, Version 2.0 diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java index 43d8e123..74370208 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.okhttp; import io.getstream.client.exception.InvalidFeedNameException; diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java index fd565de0..488cf310 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.okhttp.repo; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepoFactoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepoFactoryImpl.java index f630cf44..ff93b403 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepoFactoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepoFactoryImpl.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.okhttp.repo; import com.squareup.okhttp.ConnectionPool; diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index 03415ee3..01311575 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.okhttp.repo; import com.fasterxml.jackson.core.type.TypeReference; diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java index 81f36cbc..dcd2b908 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.okhttp.repo.handlers; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/SignatureUtils.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/SignatureUtils.java index edec6224..b7b128fc 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/SignatureUtils.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/SignatureUtils.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.okhttp.repo.utils; import com.google.common.collect.ImmutableList; diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java index 6a95ef84..1b89650e 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.okhttp.repo.utils; import com.squareup.okhttp.Request; diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/UriBuilder.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/UriBuilder.java index 55cbd69b..a5cacdb5 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/UriBuilder.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/UriBuilder.java @@ -1,33 +1,3 @@ -/** - - Copyright (c) 2015, Alessandro Pieri - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - - */ package io.getstream.client.okhttp.repo.utils; import io.getstream.client.exception.UriBuilderException; From 7b3577a1355ec3a0ca95489257b09867309bb7cf Mon Sep 17 00:00:00 2001 From: Dwight Gunning Date: Thu, 16 Mar 2017 14:12:01 +0100 Subject: [PATCH 042/320] Add Alessandro Pieri to contributors list --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index c19c3a0f..272b5e06 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,12 @@ Docs are available on [GetStream.io](http://getstream.io/docs/). Javadocs are available [here](https://getstream.github.io/stream-java/). +### Credits & Contributors + +This project was originally contributed by [Alessandro Pieri](sirio7g), prior to him joining Stream as an employee. + +We continue to welcome pull requests from community members. + ### Copyright and License Information Copyright (c) 2016-2017 Stream.io Inc, and individual contributors. All rights reserved. From f08cb56604077191a8674e3516a62e63400934c8 Mon Sep 17 00:00:00 2001 From: Tommaso Barbugli Date: Tue, 11 Apr 2017 15:17:00 +0200 Subject: [PATCH 043/320] try overwriting travis build step --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 32a3b469..045cdf8e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,5 +6,6 @@ env: - secure: TmI+K6gSOfDy5oa5EgLCGijimKdR5cHAwM6RASDegTjlRQ/sWVf8BNF4IPJHnAYFWNCgyX6vLdfPS3IJNrYS9iI1Er2a1Ctcq1TbCZfZpn4eIj8mcUXxr2Fo6hLJh2KeuXj3OQwfUy/Jul1Own/9R5YoVDJYD0ntnt1HJgFqq+0= - secure: DethMgIykOufLLQn9Jykmg7rdvZp4ONXD4A1XVQNaEVQytv20Fb2QidEPmVEocuDmpmU6SjWNMhAeBdlWnyGB4lECMG9594HJpSnNkyFQzzsfSWdOwHixiUCuD+rMJlEPRJDM4ayxhilPnK1gkycKBAZ1gtutriC4O/BdEOCN6A= - secure: F6jGxeoyhD1tmC0ovRW2RqeEQDN5t5Kfqktmtcj0Lz3S4ddgzMwC6RYKyYiiu9T3FSfh/hEMrx2SrMK+Neu2ctfYflNibUjgZJVPZHR7DA3S+g30teyj10XWspb6+OLC7U0DnGbdLee/w0KkuugQHYNv1aM9oEPtLWi+3VpvIIU= +script: mvn clean install -DskipITs=false after_success: - ".travis/publish.sh" From f2d6ac5613efb76c1fe5f8ca7f9a78e4a2a939e4 Mon Sep 17 00:00:00 2001 From: Tommaso Barbugli Date: Tue, 11 Apr 2017 15:20:18 +0200 Subject: [PATCH 044/320] dont install twice --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 045cdf8e..79f71044 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,6 @@ env: - secure: TmI+K6gSOfDy5oa5EgLCGijimKdR5cHAwM6RASDegTjlRQ/sWVf8BNF4IPJHnAYFWNCgyX6vLdfPS3IJNrYS9iI1Er2a1Ctcq1TbCZfZpn4eIj8mcUXxr2Fo6hLJh2KeuXj3OQwfUy/Jul1Own/9R5YoVDJYD0ntnt1HJgFqq+0= - secure: DethMgIykOufLLQn9Jykmg7rdvZp4ONXD4A1XVQNaEVQytv20Fb2QidEPmVEocuDmpmU6SjWNMhAeBdlWnyGB4lECMG9594HJpSnNkyFQzzsfSWdOwHixiUCuD+rMJlEPRJDM4ayxhilPnK1gkycKBAZ1gtutriC4O/BdEOCN6A= - secure: F6jGxeoyhD1tmC0ovRW2RqeEQDN5t5Kfqktmtcj0Lz3S4ddgzMwC6RYKyYiiu9T3FSfh/hEMrx2SrMK+Neu2ctfYflNibUjgZJVPZHR7DA3S+g30teyj10XWspb6+OLC7U0DnGbdLee/w0KkuugQHYNv1aM9oEPtLWi+3VpvIIU= -script: mvn clean install -DskipITs=false +script: mvn test -B -DskipITs=false after_success: - ".travis/publish.sh" From debc62650d89958f7a532c961df0a89d7dfb339a Mon Sep 17 00:00:00 2001 From: Tommaso Barbugli Date: Tue, 11 Apr 2017 15:27:48 +0200 Subject: [PATCH 045/320] disable deploy step --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 79f71044..f7a92c9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,5 +7,5 @@ env: - secure: DethMgIykOufLLQn9Jykmg7rdvZp4ONXD4A1XVQNaEVQytv20Fb2QidEPmVEocuDmpmU6SjWNMhAeBdlWnyGB4lECMG9594HJpSnNkyFQzzsfSWdOwHixiUCuD+rMJlEPRJDM4ayxhilPnK1gkycKBAZ1gtutriC4O/BdEOCN6A= - secure: F6jGxeoyhD1tmC0ovRW2RqeEQDN5t5Kfqktmtcj0Lz3S4ddgzMwC6RYKyYiiu9T3FSfh/hEMrx2SrMK+Neu2ctfYflNibUjgZJVPZHR7DA3S+g30teyj10XWspb6+OLC7U0DnGbdLee/w0KkuugQHYNv1aM9oEPtLWi+3VpvIIU= script: mvn test -B -DskipITs=false -after_success: -- ".travis/publish.sh" +#after_success: +#- ".travis/publish.sh" From e5ce85578919c6787c6be7e249b4d3c5f070e7f3 Mon Sep 17 00:00:00 2001 From: Tommaso Barbugli Date: Tue, 11 Apr 2017 20:19:05 +0200 Subject: [PATCH 046/320] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f7a92c9c..80f39e31 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,6 @@ env: - secure: TmI+K6gSOfDy5oa5EgLCGijimKdR5cHAwM6RASDegTjlRQ/sWVf8BNF4IPJHnAYFWNCgyX6vLdfPS3IJNrYS9iI1Er2a1Ctcq1TbCZfZpn4eIj8mcUXxr2Fo6hLJh2KeuXj3OQwfUy/Jul1Own/9R5YoVDJYD0ntnt1HJgFqq+0= - secure: DethMgIykOufLLQn9Jykmg7rdvZp4ONXD4A1XVQNaEVQytv20Fb2QidEPmVEocuDmpmU6SjWNMhAeBdlWnyGB4lECMG9594HJpSnNkyFQzzsfSWdOwHixiUCuD+rMJlEPRJDM4ayxhilPnK1gkycKBAZ1gtutriC4O/BdEOCN6A= - secure: F6jGxeoyhD1tmC0ovRW2RqeEQDN5t5Kfqktmtcj0Lz3S4ddgzMwC6RYKyYiiu9T3FSfh/hEMrx2SrMK+Neu2ctfYflNibUjgZJVPZHR7DA3S+g30teyj10XWspb6+OLC7U0DnGbdLee/w0KkuugQHYNv1aM9oEPtLWi+3VpvIIU= -script: mvn test -B -DskipITs=false +script: mvn clean install -DskipITs=false #after_success: #- ".travis/publish.sh" From 1cc0e106a1d1ecee8708c394c9eaa113a456247b Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 14 Apr 2017 13:14:45 +0200 Subject: [PATCH 047/320] Forced locale (Locale.ENGLISH) to generated Date fields used during authentication --- .../java/io/getstream/client/util/HttpSignatureHandler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stream-core/src/main/java/io/getstream/client/util/HttpSignatureHandler.java b/stream-core/src/main/java/io/getstream/client/util/HttpSignatureHandler.java index 98a13de4..04f77779 100644 --- a/stream-core/src/main/java/io/getstream/client/util/HttpSignatureHandler.java +++ b/stream-core/src/main/java/io/getstream/client/util/HttpSignatureHandler.java @@ -7,6 +7,7 @@ import javax.crypto.spec.SecretKeySpec; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Locale; import java.util.TimeZone; /** @@ -43,7 +44,7 @@ protected Signer getSigner() { * @return A string representing the date of today */ protected String getTodayDate() { - final SimpleDateFormat today = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz"); + final SimpleDateFormat today = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH); today.setTimeZone(TimeZone.getTimeZone("GMT")); return today.format(new Date()); } From e0bbe12d648ebc9576a9dac2a7127264bdd11117 Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 14 Apr 2017 13:19:43 +0200 Subject: [PATCH 048/320] Changed default connection timeout to a higher value (1500ms) --- .../java/io/getstream/client/config/ClientConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java b/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java index 403a6a4a..825d1ffa 100644 --- a/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java +++ b/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java @@ -50,7 +50,7 @@ public class ClientConfiguration { /** * Connection timeout in ms. */ - private int connectionTimeout = 500; + private int connectionTimeout = 1500; /** * TimeToLive in ms. From dc4a8a9da4cba7a417a4921f4c548adf63386c18 Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 14 Apr 2017 13:28:05 +0200 Subject: [PATCH 049/320] [maven-release-plugin] prepare release stream-java-1.2.2 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index cefaea58..22d769bd 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.2.2-RC1-SNAPSHOT + 1.2.2 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-1.2.2 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 025b4e60..aa25703d 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.2-RC1-SNAPSHOT + 1.2.2 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 4d89ae1e..80ff5d57 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.2-RC1-SNAPSHOT + 1.2.2 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 0e9abec1..36440872 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.2-RC1-SNAPSHOT + 1.2.2 4.0.0 From a62b41c458e66472335a6fd837b2ca373791329e Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 14 Apr 2017 13:28:12 +0200 Subject: [PATCH 050/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 22d769bd..88105210 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.2.2 + 1.2.3-RC1-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-1.2.2 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index aa25703d..ecf2e17c 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.2 + 1.2.3-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 80ff5d57..1036129e 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.2 + 1.2.3-RC1-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 36440872..a0e5f80e 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.2 + 1.2.3-RC1-SNAPSHOT 4.0.0 From e0f238be55f776465815811ce967550611a30237 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Fri, 14 Apr 2017 14:18:16 +0200 Subject: [PATCH 051/320] Update README.md Update version number --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 272b5e06..8610f388 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 1.2.1 + 1.2.2 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:1.2.1' +compile 'io.getstream.client:stream-repo-apache:1.2.2' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -34,14 +34,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 1.2.1 + 1.2.2 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:1.2.1' +compile 'io.getstream.client:stream-repo-okhttp:1.2.2' ``` In case you want to download the artifact and put it manually into your project, From c1c7433534ad39383a0b9789b4a229dc6a587074 Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 14 Apr 2017 16:50:55 +0200 Subject: [PATCH 052/320] Fixed integration test --- .../client/apache/IntegrationTest.java | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index f01560f2..7b5c48fe 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -612,15 +612,13 @@ public void shouldGetActivitiesFromNotificationFeedAndMarkThem() throws IOExcept assertThat((int)responseAfter.getUnread(), is(1)); assertThat((int) responseAfter.getUnseen(), is(1)); - StreamResponse> responseAfterMark = - notificationActivityService.getActivities(new FeedFilter.Builder().build(), true, false); - assertThat((int)responseAfterMark.getUnread(), is(0)); - assertThat((int) responseAfterMark.getUnseen(), is(1)); + /* updated marked seen and read */ + notificationActivityService.getActivities(new FeedFilter.Builder().build(), true, true); - StreamResponse> responseAfterMark2 = + StreamResponse> responseAfterMark = notificationActivityService.getActivities(new FeedFilter.Builder().build(), false, true); - assertThat((int)responseAfterMark2.getUnread(), is(0)); - assertThat((int) responseAfterMark2.getUnseen(), is(0)); + assertThat((int)responseAfterMark.getUnread(), is(0)); + assertThat((int) responseAfterMark.getUnseen(), is(0)); streamClient.shutdown(); } @@ -648,17 +646,15 @@ public void shouldGetActivitiesFromNotificationFeedAndMarkThemById() throws IOEx assertThat((int)responseAfter.getUnread(), is(1)); assertThat((int)responseAfter.getUnseen(), is(1)); + /* update marked read and seen */ String aid = responseAfter.getResults().get(0).getId(); MarkedActivity marker = new MarkedActivity.Builder().withActivityId(aid).build(); - StreamResponse> responseAfterMark = - notificationActivityService.getActivities(new FeedFilter.Builder().build(), marker, new MarkedActivity.Builder().build()); - assertThat((int)responseAfterMark.getUnread(), is(0)); - assertThat((int)responseAfterMark.getUnseen(), is(1)); + notificationActivityService.getActivities(new FeedFilter.Builder().build(), marker, marker); - StreamResponse> responseAfterMark2 = + StreamResponse> responseAfterMark = notificationActivityService.getActivities(new FeedFilter.Builder().build(), new MarkedActivity.Builder().build(), marker); - assertThat((int)responseAfterMark2.getUnread(), is(0)); - assertThat((int)responseAfterMark2.getUnseen(), is(0)); + assertThat((int)responseAfterMark.getUnread(), is(0)); + assertThat((int)responseAfterMark.getUnseen(), is(0)); streamClient.shutdown(); } From 26e82ee7d304afd536fa5e274757c1c2c0ddf66c Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 14 Apr 2017 16:55:32 +0200 Subject: [PATCH 053/320] Fixed integration test --- .../client/okhttp/IntegrationTest.java | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index 9e620e6c..5c713e3d 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -658,15 +658,13 @@ public void shouldGetActivitiesFromNotificationFeedAndMarkThem() throws IOExcept assertThat((int)responseAfter.getUnread(), is(1)); assertThat((int) responseAfter.getUnseen(), is(1)); - StreamResponse> responseAfterMark = - notificationActivityService.getActivities(new FeedFilter.Builder().build(), true, false); - assertThat((int)responseAfterMark.getUnread(), is(0)); - assertThat((int) responseAfterMark.getUnseen(), is(1)); + /* updated marked seen and read */ + notificationActivityService.getActivities(new FeedFilter.Builder().build(), true, true); - StreamResponse> responseAfterMark2 = + StreamResponse> responseAfterMark = notificationActivityService.getActivities(new FeedFilter.Builder().build(), false, true); - assertThat((int)responseAfterMark2.getUnread(), is(0)); - assertThat((int) responseAfterMark2.getUnseen(), is(0)); + assertThat((int)responseAfterMark.getUnread(), is(0)); + assertThat((int) responseAfterMark.getUnseen(), is(0)); streamClient.shutdown(); } @@ -681,13 +679,12 @@ public void shouldGetActivitiesFromNotificationFeedAndMarkThemById() throws IOEx StreamResponse> response = notificationActivityService.getActivities(); assertThat((int)response.getUnread(), is(0)); - assertThat((int)response.getUnseen(), is(0)); + assertThat((int) response.getUnseen(), is(0)); SimpleActivity activity = new SimpleActivity(); activity.setActor("actor"); activity.setObject("object"); activity.setTarget("target"); activity.setVerb("like"); - notificationActivityService.addActivity(activity); StreamResponse> responseAfter = @@ -695,17 +692,15 @@ public void shouldGetActivitiesFromNotificationFeedAndMarkThemById() throws IOEx assertThat((int)responseAfter.getUnread(), is(1)); assertThat((int)responseAfter.getUnseen(), is(1)); + /* update marked read and seen */ String aid = responseAfter.getResults().get(0).getId(); MarkedActivity marker = new MarkedActivity.Builder().withActivityId(aid).build(); - StreamResponse> responseAfterMark = - notificationActivityService.getActivities(new FeedFilter.Builder().build(), marker, new MarkedActivity.Builder().build()); - assertThat((int)responseAfterMark.getUnread(), is(0)); - assertThat((int)responseAfterMark.getUnseen(), is(1)); + notificationActivityService.getActivities(new FeedFilter.Builder().build(), marker, marker); - StreamResponse> responseAfterMark2 = + StreamResponse> responseAfterMark = notificationActivityService.getActivities(new FeedFilter.Builder().build(), new MarkedActivity.Builder().build(), marker); - assertThat((int)responseAfterMark2.getUnread(), is(0)); - assertThat((int)responseAfterMark2.getUnseen(), is(0)); + assertThat((int)responseAfterMark.getUnread(), is(0)); + assertThat((int)responseAfterMark.getUnseen(), is(0)); streamClient.shutdown(); } From d42710970ffcfdc16e34fb0f0fed04665c9b1e4e Mon Sep 17 00:00:00 2001 From: Dwight Gunning Date: Wed, 26 Apr 2017 14:45:30 +0200 Subject: [PATCH 054/320] Tidied up readme documentation references --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8610f388..ecabb1dc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,9 @@ stream-java =========== [![Build Status](https://travis-ci.org/GetStream/stream-java.svg?branch=master)](https://travis-ci.org/GetStream/stream-java) -stream-java is a Java client for [Stream](https://getstream.io/). +[stream-java](https://github.com/GetStream/stream-java) is a Java client for [Stream](https://getstream.io/). + +You can sign up for a Stream account at https://getstream.io/get_started. The Stream's Java client come in two different flavours, you should decide which one to drag into your project. Those two implementations differ according to the underlying library used to handle HTTP connections: @@ -49,6 +51,10 @@ you can download it from [here](https://github.com/GetStream/stream-java/release Snapshots of the development version are available in [Sonatype](https://oss.sonatype.org/content/repositories/snapshots/io/getstream/client/) snapshots repository. +### Full documentation + +Documentation for this Java client are available at the [Stream website](https://getstream.io/docs/?language=java). + ### Usage ```java From fdb2ae8fd1fd984cfed7e352300ac2a674bb8557 Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 17 May 2017 18:01:51 +0200 Subject: [PATCH 055/320] Added SNI endpoint (for testing purpose) --- .../src/main/java/io/getstream/client/config/StreamRegion.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java index 2fad465b..1ac5ac0a 100644 --- a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java +++ b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java @@ -16,7 +16,8 @@ public enum StreamRegion { AP_NORTH_EAST("https://ap-northeast-api.getstream.io/api"), AP_SOUTH_EAST("https://ap-southeast-api.getstream.io/api"), LOCAL_TEST("http://localhost:8089/api"), /* used for testing purpose only */ - QA_TEST("http://qa-api.getstream.io/api"); /* used for integration test */ + QA_TEST("http://qa-api.getstream.io/api"), /* used for integration test */ + SNI_TEST("https://sni-api.getstream.io/api"); /* used for testing purpose only */ protected final static String VERSION = "v1.0"; From f8a253f1c4403d5a3f0a63d9783d4c8707d1b397 Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 17 May 2017 18:02:55 +0200 Subject: [PATCH 056/320] Added endpoint for API --- .../src/main/java/io/getstream/client/config/StreamRegion.java | 1 + 1 file changed, 1 insertion(+) diff --git a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java index 1ac5ac0a..6e2cadf8 100644 --- a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java +++ b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java @@ -10,6 +10,7 @@ */ public enum StreamRegion { + BASE("https://api.getstream.io/api"), US_EAST("https://us-east-api.getstream.io/api"), US_WEST("https://us-west-api.getstream.io/api"), EU_WEST("https://eu-west-api.getstream.io/api"), From 26bdde148137dd6095673c77da6fd98cc8932f67 Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 24 May 2017 16:21:57 +0200 Subject: [PATCH 057/320] Added method util to build a JWT request for GET request --- .../client/apache/repo/utils/StreamRepoUtils.java | 13 +++++++++++++ .../apache/repo/utils/StreamRepoUtilsTest.java | 12 +++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java index 63586540..e1a5795d 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java @@ -1,6 +1,7 @@ package io.getstream.client.apache.repo.utils; import io.getstream.client.model.feeds.BaseFeed; +import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; @@ -73,4 +74,16 @@ public static HttpPost addJwtAuthentication(String token, HttpPost request) { request.addHeader(HEADER_AUTH_TYPE, "jwt"); return request; } + + /** + * Add authentication headers to the request using the JWT authentication type. + * @param token JWT token + * @param request Outgoing request + * @return The same request with authentication headers. + */ + public static HttpGet addJwtAuthentication(String token, HttpGet request) { + request.addHeader(HEADER_AUTHORIZATION, token); + request.addHeader(HEADER_AUTH_TYPE, "jwt"); + return request; + } } diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/utils/StreamRepoUtilsTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/utils/StreamRepoUtilsTest.java index afe94d2a..9cd6aca2 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/utils/StreamRepoUtilsTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/utils/StreamRepoUtilsTest.java @@ -1,6 +1,7 @@ package io.getstream.client.apache.repo.utils; import io.getstream.client.model.feeds.BaseFeed; +import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.junit.Before; @@ -43,11 +44,20 @@ public void shouldCreateFeedSignature() throws Exception { } @Test - public void shouldAddJwtAuthentication() throws Exception { + public void shouldAddJwtAuthenticationPost() throws Exception { HttpPost request = mock(HttpPost.class); StreamRepoUtils.addJwtAuthentication("token", request); verify(request).addHeader(eq("Authorization"), eq("token")); verify(request).addHeader(eq("stream-auth-type"), eq("jwt")); } + + @Test + public void shouldAddJwtAuthenticationGet() throws Exception { + HttpGet request = mock(HttpGet.class); + + StreamRepoUtils.addJwtAuthentication("token", request); + verify(request).addHeader(eq("Authorization"), eq("token")); + verify(request).addHeader(eq("stream-auth-type"), eq("jwt")); + } } \ No newline at end of file From 2dda114695f1e486e03a37df30bf267983c69ca2 Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 7 Jun 2017 11:39:29 +0200 Subject: [PATCH 058/320] Changed 'follow' from form-urlencoded to application/json --- .../client/apache/repo/StreamRepositoryImpl.java | 7 +++---- .../client/apache/repo/StreamRepositoryImplTest.java | 10 ++-------- .../client/okhttp/repo/StreamRepositoryImpl.java | 6 ++++-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index 7e530c2a..57685075 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -22,7 +22,6 @@ import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.repo.StreamRepository; import io.getstream.client.util.JwtAuthenticationUtil; -import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; @@ -31,7 +30,6 @@ import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.message.BasicNameValuePair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -94,8 +92,9 @@ public void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) th .path("feed").path(feed.getFeedSlug()).path(feed.getUserId()).path("following/") .queryParam("activity_copy_limit", activityCopyLimit) .queryParam(API_KEY, apiKey).build()); - request.setEntity(new UrlEncodedFormEntity( - Collections.singletonList(new BasicNameValuePair("target", targetFeedId)))); + request.setEntity(new StringEntity( + OBJECT_MAPPER.writeValueAsString(Collections.singletonMap("target", targetFeedId)), + APPLICATION_JSON)); fireAndForget(addAuthentication(feed, request)); } diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java index f2bdcbb9..3b2d29f6 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java @@ -1,14 +1,10 @@ package io.getstream.client.apache.repo; import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.tomakehurst.wiremock.client.RequestPatternBuilder; import com.github.tomakehurst.wiremock.junit.WireMockRule; -import io.getstream.client.StreamClient; import io.getstream.client.apache.StreamClientImpl; -import io.getstream.client.config.AuthenticationHandlerConfiguration; import io.getstream.client.config.ClientConfiguration; import io.getstream.client.config.StreamRegion; -import io.getstream.client.exception.InvalidFeedNameException; import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.SimpleActivity; import io.getstream.client.model.beans.FollowMany; @@ -16,16 +12,14 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.junit.Rule; import org.junit.Test; -import org.junit.runner.Result; import java.io.IOException; +import static com.github.tomakehurst.wiremock.client.WireMock.*; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.mock; -import static com.github.tomakehurst.wiremock.client.WireMock.*; - public class StreamRepositoryImplTest { public static final String API_KEY = "nfq26m3qgfyp"; @@ -40,7 +34,7 @@ public class StreamRepositoryImplTest { public StreamRepositoryImplTest() { ClientConfiguration clientConfiguration = new ClientConfiguration(); - clientConfiguration.setRegion(StreamRegion.LOCAL_TEST); + clientConfiguration.setRegion(StreamRegion.QA_TEST); streamClient = new StreamClientImpl(clientConfiguration, API_KEY, API_SECRET); streamRepository = new StreamRepositoryImpl(clientConfiguration, mock(CloseableHttpClient.class)); } diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index 01311575..22f598ec 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -5,7 +5,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.SerializationFeature; -import com.squareup.okhttp.FormEncodingBuilder; import com.squareup.okhttp.MediaType; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; @@ -35,6 +34,7 @@ import java.io.IOException; import java.net.URI; +import java.util.Collections; import java.util.List; /** @@ -95,7 +95,9 @@ public void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) th .path("feed").path(feed.getFeedSlug()).path(feed.getUserId()).path("following/") .queryParam("activity_copy_limit", activityCopyLimit) .queryParam(API_KEY, apiKey).build().toURL()); - requestBuilder.post(new FormEncodingBuilder().add("target", targetFeedId).build()); + requestBuilder.post( + RequestBody.create(MediaType.parse(APPLICATION_JSON), + OBJECT_MAPPER.writeValueAsString(Collections.singletonMap("target", targetFeedId)))); Request request = addAuthentication(feed, requestBuilder).build(); fireAndForget(request); From 6c04e0b5f4bc026bdde0e39ef5d00331b79e685f Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 7 Jun 2017 12:20:55 +0200 Subject: [PATCH 059/320] Changed 'follow' from form-urlencoded to application/json (fixed test) --- .../getstream/client/apache/repo/StreamRepositoryImplTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java index 3b2d29f6..1f21d2d6 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java @@ -34,7 +34,7 @@ public class StreamRepositoryImplTest { public StreamRepositoryImplTest() { ClientConfiguration clientConfiguration = new ClientConfiguration(); - clientConfiguration.setRegion(StreamRegion.QA_TEST); + clientConfiguration.setRegion(StreamRegion.LOCAL_TEST); streamClient = new StreamClientImpl(clientConfiguration, API_KEY, API_SECRET); streamRepository = new StreamRepositoryImpl(clientConfiguration, mock(CloseableHttpClient.class)); } From 185fd96c1c04a3637f59a773ea3d326f38a59cd6 Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 7 Jun 2017 13:19:36 +0200 Subject: [PATCH 060/320] [maven-release-plugin] prepare release stream-java-1.3.0 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 88105210..de3b41e7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.2.3-RC1-SNAPSHOT + 1.3.0 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-1.3.0 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index ecf2e17c..1cf643ae 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.3-RC1-SNAPSHOT + 1.3.0 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 1036129e..700db772 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.3-RC1-SNAPSHOT + 1.3.0 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index a0e5f80e..3fa6da78 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.2.3-RC1-SNAPSHOT + 1.3.0 4.0.0 From 1f34563172e17cc9cbd5f90a763f6e63dda60044 Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 7 Jun 2017 13:19:42 +0200 Subject: [PATCH 061/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index de3b41e7..8434f833 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.3.0 + 1.3.1-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-1.3.0 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 1cf643ae..f4d5caf0 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.0 + 1.3.1-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 700db772..8c00e8b9 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.0 + 1.3.1-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 3fa6da78..92a50cac 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.0 + 1.3.1-SNAPSHOT 4.0.0 From c29f27e454ca28a3fd629355f6f314d0c31da4a1 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 7 Jun 2017 13:38:27 +0200 Subject: [PATCH 062/320] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ecabb1dc..eaaac38d 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 1.2.2 + 1.3.0 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:1.2.2' +compile 'io.getstream.client:stream-repo-apache:1.3.0' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -36,14 +36,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 1.2.2 + 1.3.0 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:1.2.2' +compile 'io.getstream.client:stream-repo-okhttp:1.3.0' ``` In case you want to download the artifact and put it manually into your project, From 56685668f46c20d03f614f87f0378f325b750700 Mon Sep 17 00:00:00 2001 From: alessandro Date: Mon, 31 Jul 2017 11:39:08 +0200 Subject: [PATCH 063/320] Added support for Personalization feed. For more info: https://getstream.io/docs_analytics/ --- pom.xml | 5 +- .../io/getstream/client/StreamClient.java | 11 ++ .../client/config/ClientConfiguration.java | 14 ++ .../activities/PersonalizedActivity.java | 31 ++++ .../client/model/beans/MetaResponse.java | 40 +++++ .../client/model/beans/StreamResponse.java | 15 ++ .../client/model/feeds/BaseFeedFactory.java | 24 ++- .../client/model/feeds/FeedFactory.java | 10 ++ .../client/model/feeds/PersonalizedFeed.java | 62 ++++++++ .../model/feeds/PersonalizedFeedImpl.java | 49 ++++++ .../repo/StreamPersonalizedRepository.java | 53 +++++++ .../client/repo/StreamRepoFactory.java | 4 +- .../getstream/client/util/EndpointUtil.java | 37 +++++ .../util/PersonalizedDateDeserializer.java | 45 ++++++ .../AggregatedActivityServiceImplTest.java | 2 - .../service/FlatActivityServiceImplTest.java | 1 - .../NotificationActivityServiceImplTest.java | 5 +- .../service/UserActivityServiceImplTest.java | 3 - .../client/apache/StreamClientImpl.java | 88 ++++++++++- .../StreamPersonalizedRepositoryImpl.java | 131 ++++++++++++++++ .../apache/repo/StreamRepoFactoryImpl.java | 60 -------- .../apache/repo/StreamRepositoryImpl.java | 35 ++--- .../apache/PersonalizedIntegrationTest.java | 144 ++++++++++++++++++ .../apache/repo/StreamRepositoryImplTest.java | 2 +- .../client/okhttp/StreamClientImpl.java | 91 ++++++++++- .../StreamPersonalizedRepositoryImpl.java | 128 ++++++++++++++++ .../okhttp/repo/StreamRepoFactoryImpl.java | 62 -------- .../okhttp/repo/StreamRepositoryImpl.java | 37 ++--- .../okhttp/PersonalizedIntegrationTest.java | 137 +++++++++++++++++ 29 files changed, 1140 insertions(+), 186 deletions(-) create mode 100644 stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java create mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/MetaResponse.java create mode 100644 stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeed.java create mode 100644 stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeedImpl.java create mode 100644 stream-core/src/main/java/io/getstream/client/repo/StreamPersonalizedRepository.java create mode 100644 stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java create mode 100644 stream-core/src/main/java/io/getstream/client/util/PersonalizedDateDeserializer.java create mode 100644 stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImpl.java delete mode 100644 stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepoFactoryImpl.java create mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/PersonalizedIntegrationTest.java create mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java delete mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepoFactoryImpl.java create mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/PersonalizedIntegrationTest.java diff --git a/pom.xml b/pom.xml index 8434f833..0ba7e821 100644 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,7 @@ 4.11 1.10.19 2.1.0 + 1.57 true false @@ -127,7 +128,7 @@ com.github.tomakehurst wiremock - 1.57 + ${wiremock.version} test @@ -249,7 +250,7 @@ ${skipTests} - **/IntegrationTest.java + **/*IntegrationTest.java
diff --git a/stream-core/src/main/java/io/getstream/client/StreamClient.java b/stream-core/src/main/java/io/getstream/client/StreamClient.java index a6bce0ba..5265c611 100644 --- a/stream-core/src/main/java/io/getstream/client/StreamClient.java +++ b/stream-core/src/main/java/io/getstream/client/StreamClient.java @@ -2,6 +2,7 @@ import io.getstream.client.exception.InvalidFeedNameException; import io.getstream.client.model.feeds.Feed; +import io.getstream.client.model.feeds.PersonalizedFeed; import java.io.IOException; @@ -20,6 +21,16 @@ public interface StreamClient { */ Feed newFeed(String feedSlug, String id) throws InvalidFeedNameException; + /** + * Get a new Personalized feed + * + * @param feedSlug Feed slug + * @param id Feed id + * @return A new feed + * @throws InvalidFeedNameException if the feed name is not valid + */ + PersonalizedFeed newPersonalizedFeed(String feedSlug, String id) throws InvalidFeedNameException; + /** * Send the shutdown signal to the client. * diff --git a/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java b/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java index 730c971f..2fb167ee 100644 --- a/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java +++ b/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java @@ -47,6 +47,12 @@ public class ClientConfiguration { */ private StreamRegion region = StreamRegion.US_EAST; + /** + * Personalized feed endpoint + */ + private String personalizedFeedEndpoint; + + private AuthenticationHandlerConfiguration authenticationHandlerConfiguration; /** @@ -141,4 +147,12 @@ public long getKeepAlive() { public void setKeepAlive(long keepAlive) { this.keepAlive = keepAlive; } + + public String getPersonalizedFeedEndpoint() { + return personalizedFeedEndpoint; + } + + public void setPersonalizedFeedEndpoint(String personalizedFeedEndpoint) { + this.personalizedFeedEndpoint = personalizedFeedEndpoint; + } } diff --git a/stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java b/stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java new file mode 100644 index 00000000..9eb14dba --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java @@ -0,0 +1,31 @@ +package io.getstream.client.model.activities; + +/** + * Personalized activities are subset of {@see io.getstream.client.model.activities.BaseActivity}. + * Any custom personalized activity must be a subclasses of PersonalizedActivity. + */ +public class PersonalizedActivity extends BaseActivity { + + protected String tags; + protected String text; + + public PersonalizedActivity() { + super(); + } + + public String getTags() { + return tags; + } + + public void setTags(String tags) { + this.tags = tags; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } +} diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/MetaResponse.java b/stream-core/src/main/java/io/getstream/client/model/beans/MetaResponse.java new file mode 100644 index 00000000..30f8b5af --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/model/beans/MetaResponse.java @@ -0,0 +1,40 @@ +package io.getstream.client.model.beans; + +/** + * Wrapper object for the response coming from the Meta endpoint. + */ +public class MetaResponse { + + private double duration; + + private int responseCode; + + public MetaResponse() { + + } + + public MetaResponse(double duration, int responseCode) { + this.duration = duration; + this.responseCode = responseCode; + } + + public double getDuration() { + return duration; + } + + public void setDuration(double duration) { + this.duration = duration; + } + + /** + * Return the HTTP response code from the previous call. + * @return HTTP response code + */ + public int getResponseCode() { + return responseCode; + } + + public void setResponseCode(int responseCode) { + this.responseCode = responseCode; + } +} diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/StreamResponse.java b/stream-core/src/main/java/io/getstream/client/model/beans/StreamResponse.java index 93afb9d4..28f7ecac 100644 --- a/stream-core/src/main/java/io/getstream/client/model/beans/StreamResponse.java +++ b/stream-core/src/main/java/io/getstream/client/model/beans/StreamResponse.java @@ -1,5 +1,7 @@ package io.getstream.client.model.beans; +import com.fasterxml.jackson.annotation.JsonProperty; + import java.util.List; /** @@ -19,6 +21,11 @@ public class StreamResponse { private long unseen; + private String version; + + @JsonProperty("app_id") + private Long appId; + public List getResults() { return results; } @@ -38,4 +45,12 @@ public long getUnread() { public long getUnseen() { return unseen; } + + public String getVersion() { + return version; + } + + public Long getAppId() { + return appId; + } } diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeedFactory.java b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeedFactory.java index de76f58c..65088b73 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeedFactory.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeedFactory.java @@ -1,6 +1,8 @@ package io.getstream.client.model.feeds; +import com.google.common.base.Optional; import io.getstream.client.exception.InvalidFeedNameException; +import io.getstream.client.repo.StreamPersonalizedRepository; import io.getstream.client.repo.StreamRepository; import java.util.regex.Pattern; @@ -14,9 +16,17 @@ public final class BaseFeedFactory implements FeedFactory { private final static Pattern FEED_ID_PATTERN = Pattern.compile(FEED_ID_ALLOWED_PATTERN); private final StreamRepository streamRepository; + private final Optional streamPersonalizedRepository; - public BaseFeedFactory(final StreamRepository streamRepository) { + /** + * Build a FeedFactory by giving the actual implementation of the repositories. + * @param streamRepository Repository for Stream API + * @param streamPersonalizedRepository Repository for Personalized API + */ + public BaseFeedFactory(final StreamRepository streamRepository, + final Optional streamPersonalizedRepository) { this.streamRepository = streamRepository; + this.streamPersonalizedRepository = streamPersonalizedRepository; } @Override @@ -26,4 +36,16 @@ public Feed createFeed(final String feedSlug, final String id) throws InvalidFee } throw new InvalidFeedNameException("Either feedSlug or id are not valid. Feed slug only accept words, feed id accepts words and hyphens"); } + + @Override + public PersonalizedFeed createPersonalizedFeed(final String feedSlug, final String id) throws InvalidFeedNameException { + if (!streamPersonalizedRepository.isPresent()) { + throw new UnsupportedOperationException("Personalized feed not properly initialized." + + "Please provide a working endpoint for Personalization."); + } + if (FEED_SLUG_PATTERN.matcher(feedSlug).matches() && FEED_ID_PATTERN.matcher(id).matches()) { + return new PersonalizedFeedImpl(streamPersonalizedRepository.get(), feedSlug, id); + } + throw new InvalidFeedNameException("Either feedSlug or id are not valid. Feed slug only accept words, feed id accepts words and hyphens"); + } } diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java b/stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java index e6ca0836..debce8de 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java @@ -26,4 +26,14 @@ public interface FeedFactory { * @throws InvalidFeedNameException if the name of the feed is not valid */ Feed createFeed(String feedSlug, String id) throws InvalidFeedNameException; + + /** + * Create new personalized feed. + * + * @param feedSlug feed slug. + * @param id feed id. + * @return A new feed + * @throws InvalidFeedNameException if the name of the feed is not valid + */ + PersonalizedFeed createPersonalizedFeed(String feedSlug, String id) throws InvalidFeedNameException; } diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeed.java b/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeed.java new file mode 100644 index 00000000..5719d78b --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeed.java @@ -0,0 +1,62 @@ +package io.getstream.client.model.feeds; + +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.PersonalizedActivity; +import io.getstream.client.model.beans.MetaResponse; + +import java.io.IOException; +import java.io.Serializable; +import java.util.List; + +/** + * Provide basic operation to perform against a feed. + */ +public interface PersonalizedFeed { + + /** + * Read a personalized feed.
+ * The response is deserialized by using Jackson, therefore Jackson's annotations and custom deserializers are honored. + * @param type Since the personalized feed can be heavily customized, we need to know which class to use to perform deserialized. + * @param Type of the class to use to perform deserialization. + * @return Personalized feed + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + List get(Class type) throws IOException, StreamClientException; + + /** + * "Certain objects such as user profiles, product details etc. aren't part of the feeds. They can however be useful for personalization."
+ * Use this method to sync this data to Stream.
+ * The meta payload is serialized by using Jackson, therefore Jackson's annotations and custom serializers are honored. + * @param feed The feed you want to enrich with meta-data + * @param metaPayload The meta object can be customized by the customer. The method accepts any Serializable object. + * @return Short response about the call. + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + MetaResponse addMeta(PersonalizedFeed feed, Serializable metaPayload) throws IOException, StreamClientException; + + /** + * Read the taste/ endpoint.
+ * The response is deserialized by using Jackson, therefore Jackson's annotations and custom deserializers are honored.
+ * This endpoint is not provided by default and is activated to selected customer. + * @param type Since the personalized feed can be heavily customized, we need to know which class to use to perform deserialized. + * @param Type of the class to use to perform deserialization. + * @return Taste results + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + List getInterest(Class type) throws IOException, StreamClientException; + + /** + * Get the feed's user ID + * @return User ID + */ + String getUserId(); + + /** + * Get the feed slug + * @return Feed slug + */ + String getSlug(); +} diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeedImpl.java b/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeedImpl.java new file mode 100644 index 00000000..d5d3c44f --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeedImpl.java @@ -0,0 +1,49 @@ +package io.getstream.client.model.feeds; + +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.PersonalizedActivity; +import io.getstream.client.model.beans.MetaResponse; +import io.getstream.client.repo.StreamPersonalizedRepository; + +import java.io.IOException; +import java.io.Serializable; +import java.util.List; + +/** + * Mediator class to interact with the actual repository. + */ +public class PersonalizedFeedImpl implements PersonalizedFeed { + + protected final StreamPersonalizedRepository streamRepository; + private String slug; + private String userId; + + public PersonalizedFeedImpl(StreamPersonalizedRepository streamRepository, String feedSlug, String userId) { + this.streamRepository = streamRepository; + this.slug = feedSlug; + this.userId = userId; + } + + @Override + public List get(Class type) throws IOException, StreamClientException { + return this.streamRepository.get(this, type); + } + + @Override + public MetaResponse addMeta(PersonalizedFeed feed, Serializable metaPayload) throws IOException, StreamClientException { + return this.streamRepository.addMeta(this, metaPayload); + } + + @Override + public List getInterest(Class type) throws IOException, StreamClientException { + return this.streamRepository.getInterest(this, type); + } + + public String getSlug() { + return slug; + } + + public String getUserId() { + return userId; + } +} diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamPersonalizedRepository.java b/stream-core/src/main/java/io/getstream/client/repo/StreamPersonalizedRepository.java new file mode 100644 index 00000000..1a4c8008 --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamPersonalizedRepository.java @@ -0,0 +1,53 @@ +package io.getstream.client.repo; + +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.PersonalizedActivity; +import io.getstream.client.model.beans.MetaResponse; +import io.getstream.client.model.feeds.PersonalizedFeed; + +import java.io.IOException; +import java.io.Serializable; +import java.util.List; + +/** + * Provide low-level access to the GetStream.io Personalized REST API. + */ +public interface StreamPersonalizedRepository { + + /** + * Read a personalized feed.
+ * The response is deserialized by using Jackson, therefore Jackson's annotations and custom deserializers are honored. + * @param feed the feed you want to read from + * @param type Since the personalized feed can be heavily customized, we need to know which class to use to perform deserialized. + * @param Type of the class to use to perform deserialization. + * @return Personalized feed + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + List get(PersonalizedFeed feed, Class type) throws IOException, StreamClientException; + + /** + * "Certain objects such as user profiles, product details etc. aren't part of the feeds. They can however be useful for personalization."
+ * Use this method to sync this data to Stream.
+ * The meta payload is serialized by using Jackson, therefore Jackson's annotations and custom serializers are honored. + * @param feed The feed you want to enrich with meta-data + * @param metaPayload The meta object can be customized by the customer. The method accepts any Serializable object. + * @return Short response about the call. + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + MetaResponse addMeta(PersonalizedFeed feed, Serializable metaPayload) throws IOException, StreamClientException; + + /** + * Read the taste/ endpoint.
+ * The response is deserialized by using Jackson, therefore Jackson's annotations and custom deserializers are honored.
+ * This endpoint is not provided by default and is activated to selected customer. + * @param feed the feed you want to read from + * @param type Since the personalized feed can be heavily customized, we need to know which class to use to perform deserialized. + * @param Type of the class to use to perform deserialization. + * @return Taste results + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + List getInterest(PersonalizedFeed feed, Class type) throws IOException, StreamClientException; +} diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamRepoFactory.java b/stream-core/src/main/java/io/getstream/client/repo/StreamRepoFactory.java index 4843e5c6..99cb2136 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamRepoFactory.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamRepoFactory.java @@ -9,14 +9,14 @@ public interface StreamRepoFactory { /** - * * Create a new StreamRepository instance. + * Create a new StreamRepository instance. * * @param clientConfiguration Client configuration holder * @param authenticationHandlerConfiguration * Authentication handler (contains API key and secret key). * @return A new instance of a {@link StreamRepository} */ - StreamRepository newInstance(final ClientConfiguration clientConfiguration, + StreamRepository newHttpClient(final ClientConfiguration clientConfiguration, final AuthenticationHandlerConfiguration authenticationHandlerConfiguration); } diff --git a/stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java b/stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java new file mode 100644 index 00000000..ebdeb05b --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java @@ -0,0 +1,37 @@ +package io.getstream.client.util; + +import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.exception.UriBuilderException; + +import java.net.URI; +import java.net.URISyntaxException; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Utility class to parse and build up the Personalized feed endpoint. + */ +public class EndpointUtil { + + private EndpointUtil() { + } + + /** + * Get the personalized endpoint. + * @param streamClient StreamClient's configuration which contain the Personalized endpoint. + * @return The personalized endpoint. + */ + public static URI getPersonalizedEndpoint(ClientConfiguration streamClient) { + final String endpoint = streamClient.getPersonalizedFeedEndpoint(); + checkNotNull(endpoint, "Personalized url cannot be null"); + try { + if (endpoint.endsWith("/")) { + return new URI(endpoint); + } else { + return new URI(endpoint.concat("/")); + } + } catch (URISyntaxException e) { + throw new UriBuilderException("Malformed personalized feed's URL."); + } + } +} diff --git a/stream-core/src/main/java/io/getstream/client/util/PersonalizedDateDeserializer.java b/stream-core/src/main/java/io/getstream/client/util/PersonalizedDateDeserializer.java new file mode 100644 index 00000000..18a66a7f --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/util/PersonalizedDateDeserializer.java @@ -0,0 +1,45 @@ +package io.getstream.client.util; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; +import java.util.regex.Pattern; + +/** + * Deserialize date discarding microseconds. It should be enabled only on Jdk7 + */ +public class PersonalizedDateDeserializer extends JsonDeserializer { + + private final static Pattern MICROSECONDS_PATTERN = Pattern.compile("^(.*)\\.[0-9]{6}$"); + private static final String DEFAULT_TIMEZONE = "UTC"; + private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"; + + @Override + public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException { + ObjectCodec oc = jsonParser.getCodec(); + JsonNode node = oc.readTree(jsonParser); + String sourceTimestamp = node.asText(); + + if ( MICROSECONDS_PATTERN.matcher(sourceTimestamp).matches() ) { + sourceTimestamp = sourceTimestamp.substring(0, sourceTimestamp.length()-3); + } + + try { + SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); + dateFormat.setTimeZone(TimeZone.getTimeZone(DEFAULT_TIMEZONE)); + return dateFormat.parse(sourceTimestamp); + } catch (ParseException e) { + throw new JsonParseException("Cannot parse input date " + sourceTimestamp, jsonParser.getCurrentLocation()); + } + } +} diff --git a/stream-core/src/test/java/io/getstream/client/service/AggregatedActivityServiceImplTest.java b/stream-core/src/test/java/io/getstream/client/service/AggregatedActivityServiceImplTest.java index 8ecf13b5..5a3e5163 100644 --- a/stream-core/src/test/java/io/getstream/client/service/AggregatedActivityServiceImplTest.java +++ b/stream-core/src/test/java/io/getstream/client/service/AggregatedActivityServiceImplTest.java @@ -2,13 +2,11 @@ import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.AggregatedActivity; -import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.SimpleActivity; import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.repo.StreamRepository; -import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/stream-core/src/test/java/io/getstream/client/service/FlatActivityServiceImplTest.java b/stream-core/src/test/java/io/getstream/client/service/FlatActivityServiceImplTest.java index ca9c8700..da4d4eb8 100644 --- a/stream-core/src/test/java/io/getstream/client/service/FlatActivityServiceImplTest.java +++ b/stream-core/src/test/java/io/getstream/client/service/FlatActivityServiceImplTest.java @@ -1,7 +1,6 @@ package io.getstream.client.service; import io.getstream.client.exception.StreamClientException; -import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.SimpleActivity; import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.BaseFeed; diff --git a/stream-core/src/test/java/io/getstream/client/service/NotificationActivityServiceImplTest.java b/stream-core/src/test/java/io/getstream/client/service/NotificationActivityServiceImplTest.java index 04f9c396..580e8c39 100644 --- a/stream-core/src/test/java/io/getstream/client/service/NotificationActivityServiceImplTest.java +++ b/stream-core/src/test/java/io/getstream/client/service/NotificationActivityServiceImplTest.java @@ -1,7 +1,6 @@ package io.getstream.client.service; import io.getstream.client.exception.StreamClientException; -import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.NotificationActivity; import io.getstream.client.model.activities.SimpleActivity; import io.getstream.client.model.beans.MarkedActivity; @@ -19,9 +18,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsNull.notNullValue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.*; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/stream-core/src/test/java/io/getstream/client/service/UserActivityServiceImplTest.java b/stream-core/src/test/java/io/getstream/client/service/UserActivityServiceImplTest.java index 5d67f3d8..46d90169 100644 --- a/stream-core/src/test/java/io/getstream/client/service/UserActivityServiceImplTest.java +++ b/stream-core/src/test/java/io/getstream/client/service/UserActivityServiceImplTest.java @@ -2,7 +2,6 @@ import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.SimpleActivity; -import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; @@ -17,9 +16,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsNull.notNullValue; -import static org.junit.Assert.*; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java index 8e9311fa..9c12d728 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java @@ -1,24 +1,49 @@ package io.getstream.client.apache; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; import io.getstream.client.StreamClient; +import io.getstream.client.apache.repo.HttpSignatureInterceptor; +import io.getstream.client.apache.repo.StreamPersonalizedRepositoryImpl; +import io.getstream.client.apache.repo.StreamRepositoryImpl; import io.getstream.client.config.AuthenticationHandlerConfiguration; import io.getstream.client.config.ClientConfiguration; import io.getstream.client.exception.InvalidFeedNameException; import io.getstream.client.model.feeds.BaseFeedFactory; import io.getstream.client.model.feeds.Feed; import io.getstream.client.model.feeds.FeedFactory; -import io.getstream.client.apache.repo.StreamRepoFactoryImpl; +import io.getstream.client.model.feeds.PersonalizedFeed; +import io.getstream.client.repo.StreamPersonalizedRepository; import io.getstream.client.repo.StreamRepository; +import io.getstream.client.util.InfoUtil; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import java.io.IOException; +import java.util.Properties; +import java.util.concurrent.TimeUnit; import static com.google.common.base.Preconditions.checkNotNull; public class StreamClientImpl implements StreamClient { + private static final String USER_AGENT_PREFIX = "stream-java-apache-%s"; + private FeedFactory feedFactory; private final StreamRepository streamRepository; + private final Optional streamPersonalizedRepository; + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() + .setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); public StreamClientImpl(final ClientConfiguration clientConfiguration, final String key, final String secretKey) { Preconditions.checkNotNull(clientConfiguration, "Client configuration cannot be null."); @@ -26,8 +51,12 @@ public StreamClientImpl(final ClientConfiguration clientConfiguration, final Str authenticationHandlerConfiguration.setApiKey(checkNotNull(key, "API key cannot be null.")); authenticationHandlerConfiguration.setSecretKey(checkNotNull(secretKey, "API secret key cannot be null.")); clientConfiguration.setAuthenticationHandlerConfiguration(authenticationHandlerConfiguration); - this.streamRepository = new StreamRepoFactoryImpl().newInstance(clientConfiguration, authenticationHandlerConfiguration); - this.feedFactory = new BaseFeedFactory(this.streamRepository); + + CloseableHttpClient closeableHttpClient = initClient(clientConfiguration, authenticationHandlerConfiguration); + + this.streamRepository = new StreamRepositoryImpl(OBJECT_MAPPER, clientConfiguration, closeableHttpClient); + this.streamPersonalizedRepository = initPersonalizedRepo(clientConfiguration, closeableHttpClient); + this.feedFactory = new BaseFeedFactory(this.streamRepository, this.streamPersonalizedRepository); } @Override @@ -35,6 +64,17 @@ public Feed newFeed(final String feedSlug, final String id) throws InvalidFeedNa return this.feedFactory.createFeed(feedSlug, id); } + @Override + public PersonalizedFeed newPersonalizedFeed(final String feedSlug, + final String id) throws InvalidFeedNameException { + return this.feedFactory.createPersonalizedFeed(feedSlug, id); + } + + @Override + public void shutdown() throws IOException { + this.streamRepository.shutdown(); + } + protected FeedFactory getFeedFactory() { return feedFactory; } @@ -43,8 +83,44 @@ protected void setFeedFactory(FeedFactory feedFactory) { this.feedFactory = feedFactory; } - @Override - public void shutdown() throws IOException { - this.streamRepository.shutdown(); + private Optional initPersonalizedRepo(ClientConfiguration config, CloseableHttpClient closeableHttpClient) { + final Optional endpoint = Optional.fromNullable(config.getPersonalizedFeedEndpoint()); + if (endpoint.isPresent()) { + return Optional.of(new StreamPersonalizedRepositoryImpl(OBJECT_MAPPER, config, closeableHttpClient)); + } + return Optional.absent(); + } + + private String getUserAgent() { + String version = "undefined"; + Properties properties = InfoUtil.getProperties(); + if (null != properties) { + version = properties.getProperty(InfoUtil.VERSION); + } + return String.format(USER_AGENT_PREFIX, version); + } + + private CloseableHttpClient initClient(final ClientConfiguration config, + AuthenticationHandlerConfiguration authConfig) { + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(config.getTimeToLive(), + TimeUnit.MILLISECONDS); + connectionManager.setDefaultMaxPerRoute(config.getMaxConnectionsPerRoute()); + connectionManager.setMaxTotal(config.getMaxConnections()); + + return HttpClients.custom() + .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) + .setUserAgent(getUserAgent()) + .setDefaultRequestConfig(RequestConfig.custom() + .setConnectTimeout(config.getConnectionTimeout()) + .setSocketTimeout(config.getTimeout()).build()) + .setMaxConnPerRoute(config.getMaxConnectionsPerRoute()) + .setMaxConnTotal(config.getMaxConnections()) + .setConnectionManager(connectionManager) + .addInterceptorLast(new HttpSignatureInterceptor(authConfig)) + .build(); + } + + public static ObjectMapper getObjectMapper() { + return OBJECT_MAPPER; } } \ No newline at end of file diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImpl.java new file mode 100644 index 00000000..22187b2f --- /dev/null +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImpl.java @@ -0,0 +1,131 @@ +package io.getstream.client.apache.repo; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.getstream.client.apache.repo.handlers.StreamExceptionHandler; +import io.getstream.client.apache.repo.utils.StreamRepoUtils; +import io.getstream.client.apache.repo.utils.UriBuilder; +import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.PersonalizedActivity; +import io.getstream.client.model.beans.MetaResponse; +import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.feeds.PersonalizedFeed; +import io.getstream.client.repo.StreamPersonalizedRepository; +import io.getstream.client.repo.StreamRepository; +import io.getstream.client.util.EndpointUtil; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.entity.InputStreamEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.Serializable; +import java.net.URI; +import java.util.Collections; +import java.util.List; + +import static io.getstream.client.util.JwtAuthenticationUtil.ALL; +import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; +import static org.apache.http.entity.ContentType.APPLICATION_JSON; + +public class StreamPersonalizedRepositoryImpl implements StreamPersonalizedRepository { + + private static final Logger LOG = LoggerFactory.getLogger(StreamRepositoryImpl.class); + + static final String API_KEY = "api_key"; + + private final ObjectMapper objectMapper; + private final URI baseEndpoint; + private final String apiKey; + private final String secretKey; + private final StreamExceptionHandler exceptionHandler; + + private final CloseableHttpClient httpClient; + + /** + * Create a new {@link StreamRepository} using the given configuration {@link ClientConfiguration} and + * a pre-instantiated HttpClient {@link CloseableHttpClient}. + * + * @param streamClient Client configuration + * @param closeableHttpClient Actual instance of Apache client + */ + public StreamPersonalizedRepositoryImpl(ObjectMapper objectMapper, + ClientConfiguration streamClient, + CloseableHttpClient closeableHttpClient) { + this.objectMapper = objectMapper; + this.baseEndpoint = EndpointUtil.getPersonalizedEndpoint(streamClient); + this.apiKey = streamClient.getAuthenticationHandlerConfiguration().getApiKey(); + this.secretKey = streamClient.getAuthenticationHandlerConfiguration().getSecretKey(); + this.exceptionHandler = new StreamExceptionHandler(objectMapper); + this.httpClient = closeableHttpClient; + } + + + public List get(PersonalizedFeed feed, Class type) throws IOException, StreamClientException { + HttpGet request = new HttpGet(UriBuilder.fromEndpoint(baseEndpoint) + .path("personalized_feed/") + .path(feed.getUserId().concat("/")) + .queryParam(API_KEY, apiKey).build()); + LOG.debug("Invoking url: '{}'", request.getURI()); + + request = StreamRepoUtils.addJwtAuthentication(generateToken(secretKey, ALL, ALL, null, feed.getUserId()), request); + try (CloseableHttpResponse response = httpClient.execute(request, HttpClientContext.create())) { + handleResponseCode(response); + + StreamResponse streamResponse = objectMapper.readValue(response.getEntity().getContent(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, type)); + return streamResponse.getResults(); + } + } + + @Override + public MetaResponse addMeta(PersonalizedFeed feed, Serializable metaPayload) throws IOException, StreamClientException { + HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) + .path("meta/") + .queryParam(API_KEY, apiKey).build()); + LOG.debug("Invoking url: '{}'", request.getURI()); + + request.setEntity(new InputStreamEntity(new ByteArrayInputStream( + objectMapper.writeValueAsBytes(Collections.singletonMap("data", + Collections.singletonMap(String.format("%s:%s", feed.getSlug(), feed.getUserId()), metaPayload)))), APPLICATION_JSON)); + + request = StreamRepoUtils.addJwtAuthentication(generateToken(secretKey, ALL, ALL, null, feed.getUserId()), request); + try (CloseableHttpResponse response = httpClient.execute(request, HttpClientContext.create())) { + handleResponseCode(response); + + double duration = 0L; + StreamResponse responseValue = objectMapper.readValue(response.getEntity().getContent(), StreamResponse.class); + if (responseValue != null) { + duration = Double.parseDouble(responseValue.getDuration()); + } + return new MetaResponse(duration, response.getStatusLine().getStatusCode()); + } + } + + @Override + public List getInterest(PersonalizedFeed feed, Class type) throws IOException, StreamClientException { + HttpGet request = new HttpGet(UriBuilder.fromEndpoint(baseEndpoint) + .path("taste/") + .path(feed.getUserId().concat("/")) + .queryParam(API_KEY, apiKey).build()); + LOG.debug("Invoking url: '{}'", request.getURI()); + + request = StreamRepoUtils.addJwtAuthentication(generateToken(secretKey, ALL, ALL, null, feed.getUserId()), request); + try (CloseableHttpResponse response = httpClient.execute(request, HttpClientContext.create())) { + handleResponseCode(response); + + StreamResponse streamResponse = objectMapper.readValue(response.getEntity().getContent(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, type)); + return streamResponse.getResults(); + } + } + + private void handleResponseCode(CloseableHttpResponse response) throws StreamClientException, IOException { + exceptionHandler.handleResponseCode(response); + } +} diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepoFactoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepoFactoryImpl.java deleted file mode 100644 index 0965509f..00000000 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepoFactoryImpl.java +++ /dev/null @@ -1,60 +0,0 @@ -package io.getstream.client.apache.repo; - -import io.getstream.client.config.AuthenticationHandlerConfiguration; -import io.getstream.client.config.ClientConfiguration; -import io.getstream.client.repo.StreamRepoFactory; -import io.getstream.client.repo.StreamRepository; -import io.getstream.client.util.InfoUtil; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; - -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -/** - * Create a new StreamRepository using the ApacheHttpClient. - */ -public class StreamRepoFactoryImpl implements StreamRepoFactory { - - private static final String USER_AGENT_PREFIX = "stream-java-apache-%s"; - - private final String userAgent; - - public StreamRepoFactoryImpl() { - String version = "undefined"; - Properties properties = InfoUtil.getProperties(); - if (null != properties) { - version = properties.getProperty(InfoUtil.VERSION); - } - this.userAgent = String.format(USER_AGENT_PREFIX, version); - } - - @Override - public StreamRepository newInstance(ClientConfiguration clientConfiguration, - AuthenticationHandlerConfiguration authenticationHandlerConfiguration) { - return new StreamRepositoryImpl(clientConfiguration, initClient(clientConfiguration, authenticationHandlerConfiguration)); - } - - private CloseableHttpClient initClient(final ClientConfiguration config, - AuthenticationHandlerConfiguration authConfig) { - PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(config.getTimeToLive(), - TimeUnit.MILLISECONDS); - connectionManager.setDefaultMaxPerRoute(config.getMaxConnectionsPerRoute()); - connectionManager.setMaxTotal(config.getMaxConnections()); - - return HttpClients.custom() - .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) - .setUserAgent(userAgent) - .setDefaultRequestConfig(RequestConfig.custom() - .setConnectTimeout(config.getConnectionTimeout()) - .setSocketTimeout(config.getTimeout()).build()) - .setMaxConnPerRoute(config.getMaxConnectionsPerRoute()) - .setMaxConnTotal(config.getMaxConnections()) - .setConnectionManager(connectionManager) - .addInterceptorLast(new HttpSignatureInterceptor(authConfig)) - .build(); - } -} diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index 57685075..f432a092 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -1,10 +1,8 @@ package io.getstream.client.apache.repo; import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.SerializationFeature; +import io.getstream.client.apache.StreamClientImpl; import io.getstream.client.apache.repo.handlers.StreamExceptionHandler; import io.getstream.client.apache.repo.utils.StreamRepoUtils; import io.getstream.client.apache.repo.utils.UriBuilder; @@ -50,12 +48,7 @@ public class StreamRepositoryImpl implements StreamRepository { static final String API_KEY = "api_key"; - /* will convert camelStyle to lower_case_style */ - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() - .setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES) - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - + private final ObjectMapper objectMapper; private final URI baseEndpoint; private final String apiKey; private final String secretKey; @@ -68,16 +61,18 @@ public class StreamRepositoryImpl implements StreamRepository { * Create a new {@link StreamRepository} using the given configuration {@link ClientConfiguration} and * a pre-instantiated HttpClient {@link CloseableHttpClient}. * + * @param objectMapper Json Object Mapper * @param streamClient Client configuration * @param closeableHttpClient Actual instance of Apache client */ - public StreamRepositoryImpl(ClientConfiguration streamClient, CloseableHttpClient closeableHttpClient) { + public StreamRepositoryImpl(ObjectMapper objectMapper, ClientConfiguration streamClient, CloseableHttpClient closeableHttpClient) { + this.objectMapper = objectMapper; this.baseEndpoint = streamClient.getRegion().getEndpoint(); this.apiKey = streamClient.getAuthenticationHandlerConfiguration().getApiKey(); this.secretKey = streamClient.getAuthenticationHandlerConfiguration().getSecretKey(); - this.exceptionHandler = new StreamExceptionHandler(OBJECT_MAPPER); + this.exceptionHandler = new StreamExceptionHandler(objectMapper); this.httpClient = closeableHttpClient; - this.streamActivityRepository = new StreamActivityRepository(OBJECT_MAPPER, baseEndpoint, apiKey, exceptionHandler, + this.streamActivityRepository = new StreamActivityRepository(objectMapper, baseEndpoint, apiKey, exceptionHandler, httpClient, secretKey); } @@ -93,7 +88,7 @@ public void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) th .queryParam("activity_copy_limit", activityCopyLimit) .queryParam(API_KEY, apiKey).build()); request.setEntity(new StringEntity( - OBJECT_MAPPER.writeValueAsString(Collections.singletonMap("target", targetFeedId)), + objectMapper.writeValueAsString(Collections.singletonMap("target", targetFeedId)), APPLICATION_JSON)); fireAndForget(addAuthentication(feed, request)); } @@ -105,7 +100,7 @@ public void followMany(BaseFeed feed, FollowMany followManyInput, int activityCo .queryParam("activity_copy_limit", activityCopyLimit) .build()); request.addHeader(HttpSignatureInterceptor.X_API_KEY_HEADER, apiKey); - request.setEntity(new StringEntity(OBJECT_MAPPER.writeValueAsString(followManyInput), APPLICATION_JSON)); + request.setEntity(new StringEntity(objectMapper.writeValueAsString(followManyInput), APPLICATION_JSON)); fireAndForget(request); } @@ -126,7 +121,7 @@ public List getFollowing(BaseFeed feed, FeedFilter filter) throws St LOG.debug("Invoking url: '{}'", request.getURI()); try (CloseableHttpResponse response = httpClient.execute(addAuthentication(feed, request), HttpClientContext.create())) { handleResponseCode(response); - StreamResponse streamResponse = OBJECT_MAPPER.readValue(response.getEntity().getContent(), + StreamResponse streamResponse = objectMapper.readValue(response.getEntity().getContent(), new TypeReference>() { }); return streamResponse.getResults(); @@ -141,7 +136,7 @@ public List getFollowers(BaseFeed feed, FeedFilter filter) throws St LOG.debug("Invoking url: '{}'", request.getURI()); try (CloseableHttpResponse response = httpClient.execute(addAuthentication(feed, request), HttpClientContext.create())) { handleResponseCode(response); - StreamResponse streamResponse = OBJECT_MAPPER.readValue(response.getEntity().getContent(), + StreamResponse streamResponse = objectMapper.readValue(response.getEntity().getContent(), new TypeReference>() { }); return streamResponse.getResults(); @@ -228,7 +223,13 @@ private HttpRequestBase addAuthentication(BaseFeed feed, HttpRequestBase httpReq return StreamRepoUtils.addAuthentication(feed, secretKey, httpRequest); } + /** + * Get Jackson's object mapper. This method is deprecated. + * Please use StreamClientImpl.getObjectMapper() instead. + * @return Object mapper + */ + @Deprecated public static ObjectMapper getObjectMapper() { - return OBJECT_MAPPER; + return StreamClientImpl.getObjectMapper(); } } diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/PersonalizedIntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/PersonalizedIntegrationTest.java new file mode 100644 index 00000000..1d99276a --- /dev/null +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/PersonalizedIntegrationTest.java @@ -0,0 +1,144 @@ +package io.getstream.client.apache; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.getstream.client.StreamClient; +import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.config.StreamRegion; +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.PersonalizedActivity; +import io.getstream.client.model.beans.MetaResponse; +import io.getstream.client.model.feeds.PersonalizedFeed; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertTrue; + +public class PersonalizedIntegrationTest { + + public static final String API_KEY = "qssg44g3xjqu"; + public static final String API_SECRET = "kq3ueg2wpxz9qjqkuxgfmhn8p768mxygg4tqtvxymnbbrfsdktf3ntz8ndg9eg53"; + public static final ClientConfiguration CLIENT_CONFIGURATION = new ClientConfiguration(StreamRegion.QA_TEST); + + @BeforeClass + public static void setLog() { + System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); + System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); + System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "DEBUG"); + } + + @BeforeClass + public static void initClient() { + CLIENT_CONFIGURATION.setPersonalizedFeedEndpoint("http://ml-api.staging.gtstrm.com:85/fullmeasureed"); + } + + @Test + public void shouldGetPersonalizedFeed() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); + + PersonalizedFeed feed = streamClient.newPersonalizedFeed("aggregated", "2"); + List response = feed.get(PersonalizedActivity.class); + assertTrue(response.size() > 0); + + streamClient.shutdown(); + } + + @Test + public void shouldGetPersonalizedFeedInterest() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); + + PersonalizedFeed feed = streamClient.newPersonalizedFeed("aggregated", "2"); + List response = feed.getInterest(Interest.class); + assertTrue(response.size() > 0); + + streamClient.shutdown(); + } + + + @Test + public void shouldSendMeta() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); + + PersonalizedFeed feed = streamClient.newPersonalizedFeed("user", "2"); + + MetaResponse response = feed.addMeta(feed, new MetaInterest(Collections.singletonList("java"))); + assertThat(response.getResponseCode(), is(201)); + + streamClient.shutdown(); + } + + + class MetaInterest implements Serializable { + + private List interests = null; + + public MetaInterest() { + } + + public MetaInterest(List interests) { + this.interests = interests; + } + + public List getInterests() { + return interests; + } + + public void setInterests(List interests) { + this.interests = interests; + } + } + + class Interest implements Serializable { + + @JsonProperty("user_id") + private String userId; + + @JsonProperty("consumption_history") + private List consumptionHistory; + + @JsonProperty("profile_strength") + private Card profileStrength; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public List getConsumptionHistory() { + return consumptionHistory; + } + + public void setConsumptionHistory(List consumptionHistory) { + this.consumptionHistory = consumptionHistory; + } + + public Card getProfileStrength() { + return profileStrength; + } + + public void setProfileStrength(Card profileStrength) { + this.profileStrength = profileStrength; + } + } + + class Card implements Serializable { + private int card; + + public int getCard() { + return card; + } + + public void setCard(int card) { + this.card = card; + } + } +} \ No newline at end of file diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java index 1f21d2d6..686ce4ca 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java @@ -36,7 +36,7 @@ public StreamRepositoryImplTest() { ClientConfiguration clientConfiguration = new ClientConfiguration(); clientConfiguration.setRegion(StreamRegion.LOCAL_TEST); streamClient = new StreamClientImpl(clientConfiguration, API_KEY, API_SECRET); - streamRepository = new StreamRepositoryImpl(clientConfiguration, mock(CloseableHttpClient.class)); + streamRepository = new StreamRepositoryImpl(mock(ObjectMapper.class), clientConfiguration, mock(CloseableHttpClient.class)); } @Test diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java index 74370208..4f48e508 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java @@ -1,33 +1,61 @@ package io.getstream.client.okhttp; -import io.getstream.client.exception.InvalidFeedNameException; -import io.getstream.client.okhttp.repo.StreamRepoFactoryImpl; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import com.squareup.okhttp.ConnectionPool; +import com.squareup.okhttp.Interceptor; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Response; import io.getstream.client.StreamClient; import io.getstream.client.config.AuthenticationHandlerConfiguration; import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.exception.InvalidFeedNameException; import io.getstream.client.model.feeds.BaseFeedFactory; import io.getstream.client.model.feeds.Feed; import io.getstream.client.model.feeds.FeedFactory; +import io.getstream.client.model.feeds.PersonalizedFeed; +import io.getstream.client.okhttp.repo.HttpSignatureinterceptor; +import io.getstream.client.okhttp.repo.StreamPersonalizedRepositoryImpl; +import io.getstream.client.okhttp.repo.StreamRepositoryImpl; +import io.getstream.client.repo.StreamPersonalizedRepository; import io.getstream.client.repo.StreamRepository; +import io.getstream.client.util.InfoUtil; import java.io.IOException; +import java.util.Properties; +import java.util.concurrent.TimeUnit; import static com.google.common.base.Preconditions.checkNotNull; public class StreamClientImpl implements StreamClient { + private static final String USER_AGENT_PREFIX = "stream-java-okhttp-%s"; + + private final Optional streamPersonalizedRepository; private FeedFactory feedFactory; private final StreamRepository streamRepository; + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() + .setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + public StreamClientImpl(final ClientConfiguration clientConfiguration, final String key, final String secretKey) { Preconditions.checkNotNull(clientConfiguration, "Client configuration cannot be null."); AuthenticationHandlerConfiguration authenticationHandlerConfiguration = new AuthenticationHandlerConfiguration(); authenticationHandlerConfiguration.setApiKey(checkNotNull(key, "API key cannot be null.")); authenticationHandlerConfiguration.setSecretKey(checkNotNull(secretKey, "API secret key cannot be null.")); clientConfiguration.setAuthenticationHandlerConfiguration(authenticationHandlerConfiguration); - this.streamRepository = new StreamRepoFactoryImpl().newInstance(clientConfiguration, authenticationHandlerConfiguration); - this.feedFactory = new BaseFeedFactory(this.streamRepository); + + OkHttpClient httpClient = initClient(clientConfiguration, authenticationHandlerConfiguration); + + this.streamRepository = new StreamRepositoryImpl(OBJECT_MAPPER, clientConfiguration, httpClient); + this.streamPersonalizedRepository = initPersonalizedRepo(clientConfiguration, httpClient); + this.feedFactory = new BaseFeedFactory(this.streamRepository, this.streamPersonalizedRepository); } @Override @@ -35,6 +63,17 @@ public Feed newFeed(final String feedSlug, final String id) throws InvalidFeedNa return this.feedFactory.createFeed(feedSlug, id); } + @Override + public PersonalizedFeed newPersonalizedFeed(final String feedSlug, + final String id) throws InvalidFeedNameException { + return this.feedFactory.createPersonalizedFeed(feedSlug, id); + } + + @Override + public void shutdown() throws IOException { + this.streamRepository.shutdown(); + } + protected FeedFactory getFeedFactory() { return feedFactory; } @@ -43,8 +82,46 @@ protected void setFeedFactory(FeedFactory feedFactory) { this.feedFactory = feedFactory; } - @Override - public void shutdown() throws IOException { - this.streamRepository.shutdown(); + private OkHttpClient initClient(final ClientConfiguration config, AuthenticationHandlerConfiguration authConfig) { + OkHttpClient client = new OkHttpClient(); + client.setConnectTimeout(config.getConnectionTimeout(), TimeUnit.MILLISECONDS); + client.setReadTimeout(config.getTimeout(), TimeUnit.MILLISECONDS); + client.setWriteTimeout(config.getTimeout(), TimeUnit.MILLISECONDS); + client.setRetryOnConnectionFailure(true); + client.interceptors().add(new UserAgentInterceptor()); + client.interceptors().add(new HttpSignatureinterceptor(authConfig)); + client.setConnectionPool(new ConnectionPool(config.getMaxConnections(), config.getKeepAlive())); + return client; + } + + private Optional initPersonalizedRepo(ClientConfiguration config, OkHttpClient httpClient) { + final Optional endpoint = Optional.fromNullable(config.getPersonalizedFeedEndpoint()); + if (endpoint.isPresent()) { + return Optional.of(new StreamPersonalizedRepositoryImpl(OBJECT_MAPPER, config, httpClient)); + } + return Optional.absent(); + } + + /** + * Add custom user-agent to the request. + */ + class UserAgentInterceptor implements Interceptor { + @Override + public Response intercept(Chain chain) throws IOException { + return chain.proceed(chain.request().newBuilder().header("User-Agent", getUserAgent()).build()); + } + } + + private String getUserAgent() { + String version = "undefined"; + Properties properties = InfoUtil.getProperties(); + if (null != properties) { + version = properties.getProperty(InfoUtil.VERSION); + } + return String.format(USER_AGENT_PREFIX, version); + } + + public static ObjectMapper getObjectMapper() { + return OBJECT_MAPPER; } } \ No newline at end of file diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java new file mode 100644 index 00000000..ddb7088e --- /dev/null +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java @@ -0,0 +1,128 @@ +package io.getstream.client.okhttp.repo; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.squareup.okhttp.MediaType; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.RequestBody; +import com.squareup.okhttp.Response; +import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.PersonalizedActivity; +import io.getstream.client.model.beans.MetaResponse; +import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.feeds.PersonalizedFeed; +import io.getstream.client.okhttp.repo.handlers.StreamExceptionHandler; +import io.getstream.client.okhttp.repo.utils.StreamRepoUtils; +import io.getstream.client.okhttp.repo.utils.UriBuilder; +import io.getstream.client.repo.StreamPersonalizedRepository; +import io.getstream.client.util.EndpointUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.Serializable; +import java.net.URI; +import java.util.Collections; +import java.util.List; + +import static io.getstream.client.util.JwtAuthenticationUtil.ALL; +import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; + +public class StreamPersonalizedRepositoryImpl implements StreamPersonalizedRepository { + + private static final Logger LOG = LoggerFactory.getLogger(StreamRepositoryImpl.class); + + private static final String API_KEY = "api_key"; + private static final String APPLICATION_JSON = "application/json; charset=utf-8"; + + private final ObjectMapper objectMapper; + private final URI baseEndpoint; + private final String apiKey; + private final String secretKey; + private final StreamExceptionHandler exceptionHandler; + + private final OkHttpClient httpClient; + + public StreamPersonalizedRepositoryImpl(ObjectMapper objectMapper, + ClientConfiguration streamClient, + OkHttpClient closeableHttpClient) { + this.objectMapper = objectMapper; + this.baseEndpoint = EndpointUtil.getPersonalizedEndpoint(streamClient); + this.apiKey = streamClient.getAuthenticationHandlerConfiguration().getApiKey(); + this.secretKey = streamClient.getAuthenticationHandlerConfiguration().getSecretKey(); + this.exceptionHandler = new StreamExceptionHandler(objectMapper); + this.httpClient = closeableHttpClient; + } + + @Override + public List get(PersonalizedFeed feed, Class type) throws IOException, StreamClientException { + Request.Builder requestBuilder = new Request.Builder().url( + UriBuilder.fromEndpoint(baseEndpoint) + .path("personalized_feed/") + .path(feed.getUserId().concat("/")) + .queryParam(API_KEY, apiKey).build().toURL()).get(); + + Request request = StreamRepoUtils.addJwtAuthentication( + generateToken(secretKey, ALL, ALL, null, feed.getUserId()), + requestBuilder).build(); + LOG.debug("Invoking url: '{}", request.urlString()); + + Response response = httpClient.newCall(request).execute(); + handleResponseCode(response); + StreamResponse streamResponse = objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, type)); + return streamResponse.getResults(); + } + + @Override + public MetaResponse addMeta(PersonalizedFeed feed, Serializable metaPayload) throws IOException, StreamClientException { + double duration = 0L; + + Request.Builder requestBuilder = new Request.Builder().url(UriBuilder.fromEndpoint(baseEndpoint) + .path("meta/") + .queryParam(API_KEY, apiKey).build().toURL()); + + requestBuilder.post(RequestBody.create(MediaType.parse(APPLICATION_JSON), + objectMapper.writeValueAsBytes(Collections.singletonMap("data", + Collections.singletonMap(String.format("%s:%s", feed.getSlug(), feed.getUserId()), metaPayload))))); + + Request request = StreamRepoUtils.addJwtAuthentication( + generateToken(secretKey, ALL, ALL, null, feed.getUserId()), requestBuilder).build(); + + LOG.debug("Invoking url: '{}", request.urlString()); + + Response response = httpClient.newCall(request).execute(); + handleResponseCode(response); + + StreamResponse responseValue = objectMapper.readValue(response.body().byteStream(), StreamResponse.class); + if (responseValue != null) { + duration = Double.parseDouble(responseValue.getDuration()); + } + return new MetaResponse(duration, response.code()); + } + + @Override + public List getInterest(PersonalizedFeed feed, Class type) throws IOException, StreamClientException { + Request.Builder requestBuilder = new Request.Builder().url( + UriBuilder.fromEndpoint(baseEndpoint) + .path("taste/") + .path(feed.getUserId().concat("/")) + .queryParam(API_KEY, apiKey).build().toURL()).get(); + + Request request = StreamRepoUtils.addJwtAuthentication( + generateToken(secretKey, ALL, ALL, null, feed.getUserId()), + requestBuilder).build(); + LOG.debug("Invoking url: '{}", request.urlString()); + + Response response = httpClient.newCall(request).execute(); + handleResponseCode(response); + StreamResponse streamResponse = objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, type)); + return streamResponse.getResults(); + } + + private void handleResponseCode(Response response) throws StreamClientException, IOException { + exceptionHandler.handleResponseCode(response); + } +} diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepoFactoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepoFactoryImpl.java deleted file mode 100644 index ff93b403..00000000 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepoFactoryImpl.java +++ /dev/null @@ -1,62 +0,0 @@ -package io.getstream.client.okhttp.repo; - -import com.squareup.okhttp.ConnectionPool; -import com.squareup.okhttp.Interceptor; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Response; -import io.getstream.client.config.AuthenticationHandlerConfiguration; -import io.getstream.client.config.ClientConfiguration; -import io.getstream.client.repo.StreamRepoFactory; -import io.getstream.client.repo.StreamRepository; -import io.getstream.client.util.InfoUtil; - -import java.io.IOException; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -/** - * Create a new StreamRepository using the ApacheHttpClient. - */ -public class StreamRepoFactoryImpl implements StreamRepoFactory { - - private static final String USER_AGENT_PREFIX = "stream-java-okhttp-%s"; - - private final String userAgent; - - public StreamRepoFactoryImpl() { - String version = "undefined"; - Properties properties = InfoUtil.getProperties(); - if (null != properties) { - version = properties.getProperty(InfoUtil.VERSION); - } - this.userAgent = String.format(USER_AGENT_PREFIX, version); - } - - @Override - public StreamRepository newInstance(ClientConfiguration clientConfiguration, - AuthenticationHandlerConfiguration authenticationHandlerConfiguration) { - return new StreamRepositoryImpl(clientConfiguration, initClient(clientConfiguration, authenticationHandlerConfiguration)); - } - - private OkHttpClient initClient(final ClientConfiguration config, AuthenticationHandlerConfiguration authConfig) { - OkHttpClient client = new OkHttpClient(); - client.setConnectTimeout(config.getConnectionTimeout(), TimeUnit.MILLISECONDS); - client.setReadTimeout(config.getTimeout(), TimeUnit.MILLISECONDS); - client.setWriteTimeout(config.getTimeout(), TimeUnit.MILLISECONDS); - client.setRetryOnConnectionFailure(true); - client.interceptors().add(new UserAgentInterceptor()); - client.interceptors().add(new HttpSignatureinterceptor(authConfig)); - client.setConnectionPool(new ConnectionPool(config.getMaxConnections(), config.getKeepAlive())); - return client; - } - - /** - * Add custom user-agent to the request. - */ - class UserAgentInterceptor implements Interceptor { - @Override - public Response intercept(Chain chain) throws IOException { - return chain.proceed(chain.request().newBuilder().header("User-Agent", userAgent).build()); - } - } -} diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index 22f598ec..897399ab 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -1,10 +1,7 @@ package io.getstream.client.okhttp.repo; import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.SerializationFeature; import com.squareup.okhttp.MediaType; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; @@ -22,6 +19,7 @@ import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; +import io.getstream.client.okhttp.StreamClientImpl; import io.getstream.client.okhttp.repo.handlers.StreamExceptionHandler; import io.getstream.client.okhttp.repo.utils.FeedFilterUtils; import io.getstream.client.okhttp.repo.utils.StreamRepoUtils; @@ -48,34 +46,31 @@ public class StreamRepositoryImpl implements StreamRepository { static final String API_KEY = "api_key"; - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().setPropertyNamingStrategy( - /* will convert camelStyle to lower_case_style */ - PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES) - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - + private final ObjectMapper objectMapper; private final URI baseEndpoint; private final String apiKey; private final String secretKey; private final StreamExceptionHandler exceptionHandler; - private final OkHttpClient httpClient; + private final OkHttpClient httpClient; private final StreamActivityRepository streamActivityRepository; /** * Create a new {@link StreamRepository} using the given configuration {@link ClientConfiguration} and * a pre-instantiated HttpClient {@link OkHttpClient}. * + * @param objectMapper Json Object Mapper * @param streamClient Client configuration * @param closeableHttpClient Actual instance of OkHTTP client */ - public StreamRepositoryImpl(ClientConfiguration streamClient, OkHttpClient closeableHttpClient) { + public StreamRepositoryImpl(ObjectMapper objectMapper, ClientConfiguration streamClient, OkHttpClient closeableHttpClient) { this.baseEndpoint = streamClient.getRegion().getEndpoint(); this.apiKey = streamClient.getAuthenticationHandlerConfiguration().getApiKey(); this.secretKey = streamClient.getAuthenticationHandlerConfiguration().getSecretKey(); - this.exceptionHandler = new StreamExceptionHandler(OBJECT_MAPPER); + this.exceptionHandler = new StreamExceptionHandler(objectMapper); this.httpClient = closeableHttpClient; - this.streamActivityRepository = new StreamActivityRepository(OBJECT_MAPPER, baseEndpoint, apiKey, exceptionHandler, + this.objectMapper = objectMapper; + this.streamActivityRepository = new StreamActivityRepository(objectMapper, baseEndpoint, apiKey, exceptionHandler, httpClient, secretKey); } @@ -97,7 +92,7 @@ public void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) th .queryParam(API_KEY, apiKey).build().toURL()); requestBuilder.post( RequestBody.create(MediaType.parse(APPLICATION_JSON), - OBJECT_MAPPER.writeValueAsString(Collections.singletonMap("target", targetFeedId)))); + objectMapper.writeValueAsString(Collections.singletonMap("target", targetFeedId)))); Request request = addAuthentication(feed, requestBuilder).build(); fireAndForget(request); @@ -111,7 +106,7 @@ public void followMany(BaseFeed feed, FollowMany followManyInput, int activityCo .queryParam("activity_copy_limit", activityCopyLimit) .build().toURL()); requestBuilder.addHeader(HttpSignatureHandler.X_API_KEY_HEADER, apiKey); - requestBuilder.post(RequestBody.create(MediaType.parse(APPLICATION_JSON), OBJECT_MAPPER.writeValueAsString(followManyInput))); + requestBuilder.post(RequestBody.create(MediaType.parse(APPLICATION_JSON), objectMapper.writeValueAsString(followManyInput))); fireAndForget(requestBuilder.build()); } @@ -135,7 +130,7 @@ public List getFollowing(BaseFeed feed, FeedFilter filter) throws St Response response = httpClient.newCall(request).execute(); handleResponseCode(response); - StreamResponse streamResponse = OBJECT_MAPPER.readValue(response.body().byteStream(), + StreamResponse streamResponse = objectMapper.readValue(response.body().byteStream(), new TypeReference>() {}); return streamResponse.getResults(); } @@ -151,7 +146,7 @@ public List getFollowers(BaseFeed feed, FeedFilter filter) throws St Response response = httpClient.newCall(request).execute(); handleResponseCode(response); - StreamResponse streamResponse = OBJECT_MAPPER.readValue(response.body().byteStream(), + StreamResponse streamResponse = objectMapper.readValue(response.body().byteStream(), new TypeReference>() {}); return streamResponse.getResults(); } @@ -229,7 +224,13 @@ private Request.Builder addAuthentication(BaseFeed feed, Request.Builder httpReq return StreamRepoUtils.addAuthentication(feed, secretKey, httpRequest); } + /** + * Get Jackson's object mapper. This method is deprecated. + * Please use StreamClientImpl.getObjectMapper() instead. + * @return Object mapper + */ + @Deprecated public static ObjectMapper getObjectMapper() { - return OBJECT_MAPPER; + return StreamClientImpl.getObjectMapper(); } } \ No newline at end of file diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/PersonalizedIntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/PersonalizedIntegrationTest.java new file mode 100644 index 00000000..33986369 --- /dev/null +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/PersonalizedIntegrationTest.java @@ -0,0 +1,137 @@ +package io.getstream.client.okhttp; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.getstream.client.StreamClient; +import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.config.StreamRegion; +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.PersonalizedActivity; +import io.getstream.client.model.beans.MetaResponse; +import io.getstream.client.model.feeds.PersonalizedFeed; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertTrue; + +public class PersonalizedIntegrationTest { + + public static final String API_KEY = "qssg44g3xjqu"; + public static final String API_SECRET = "kq3ueg2wpxz9qjqkuxgfmhn8p768mxygg4tqtvxymnbbrfsdktf3ntz8ndg9eg53"; + public static final ClientConfiguration CLIENT_CONFIGURATION = new ClientConfiguration(StreamRegion.QA_TEST); + + @BeforeClass + public static void initClient() { + CLIENT_CONFIGURATION.setPersonalizedFeedEndpoint("http://ml-api.staging.gtstrm.com:85/fullmeasureed"); + } + + @Test + public void shouldGetPersonalizedFeed() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); + + PersonalizedFeed feed = streamClient.newPersonalizedFeed("aggregated", "2"); + List response = feed.get(PersonalizedActivity.class); + assertTrue(response.size() > 0); + + streamClient.shutdown(); + } + + @Test + public void shouldGetPersonalizedFeedInterest() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); + + PersonalizedFeed feed = streamClient.newPersonalizedFeed("aggregated", "2"); + List response = feed.getInterest(Interest.class); + assertTrue(response.size() > 0); + + streamClient.shutdown(); + } + + + @Test + public void shouldSendMeta() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); + + PersonalizedFeed feed = streamClient.newPersonalizedFeed("user", "2"); + + MetaResponse response = feed.addMeta(feed, new MetaInterest(Collections.singletonList("java"))); + assertThat(response.getResponseCode(), is(201)); + + streamClient.shutdown(); + } + + + class MetaInterest implements Serializable { + + private List interests = null; + + public MetaInterest() { + } + + public MetaInterest(List interests) { + this.interests = interests; + } + + public List getInterests() { + return interests; + } + + public void setInterests(List interests) { + this.interests = interests; + } + } + + class Interest implements Serializable { + + @JsonProperty("user_id") + private String userId; + + @JsonProperty("consumption_history") + private List consumptionHistory; + + @JsonProperty("profile_strength") + private Card profileStrength; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public List getConsumptionHistory() { + return consumptionHistory; + } + + public void setConsumptionHistory(List consumptionHistory) { + this.consumptionHistory = consumptionHistory; + } + + public Card getProfileStrength() { + return profileStrength; + } + + public void setProfileStrength(Card profileStrength) { + this.profileStrength = profileStrength; + } + } + + class Card implements Serializable { + private int card; + + public int getCard() { + return card; + } + + public void setCard(int card) { + this.card = card; + } + } +} \ No newline at end of file From 5b816e517db8d457428aa7315079068a392ac3e9 Mon Sep 17 00:00:00 2001 From: alessandro Date: Mon, 31 Jul 2017 13:25:25 +0200 Subject: [PATCH 064/320] Added test cases for personalized feed --- .../activities/PersonalizedActivity.java | 8 +- .../getstream/client/util/EndpointUtil.java | 8 +- .../client/util/EndpointUtilTest.java | 38 +++++ .../StreamPersonalizedRepositoryImplTest.java | 159 ++++++++++++++++++ stream-repo-okhttp/pom.xml | 6 + .../StreamPersonalizedRepositoryImplTest.java | 150 +++++++++++++++++ 6 files changed, 364 insertions(+), 5 deletions(-) create mode 100644 stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java create mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImplTest.java create mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java diff --git a/stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java b/stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java index 9eb14dba..b9b8cc92 100644 --- a/stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java +++ b/stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java @@ -1,23 +1,25 @@ package io.getstream.client.model.activities; +import java.util.List; + /** * Personalized activities are subset of {@see io.getstream.client.model.activities.BaseActivity}. * Any custom personalized activity must be a subclasses of PersonalizedActivity. */ public class PersonalizedActivity extends BaseActivity { - protected String tags; + protected List tags; protected String text; public PersonalizedActivity() { super(); } - public String getTags() { + public List getTags() { return tags; } - public void setTags(String tags) { + public void setTags(List tags) { this.tags = tags; } diff --git a/stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java b/stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java index ebdeb05b..1f83b0d2 100644 --- a/stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java +++ b/stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java @@ -3,8 +3,10 @@ import io.getstream.client.config.ClientConfiguration; import io.getstream.client.exception.UriBuilderException; +import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; +import java.net.URL; import static com.google.common.base.Preconditions.checkNotNull; @@ -26,10 +28,12 @@ public static URI getPersonalizedEndpoint(ClientConfiguration streamClient) { checkNotNull(endpoint, "Personalized url cannot be null"); try { if (endpoint.endsWith("/")) { - return new URI(endpoint); + return new URL(endpoint).toURI(); } else { - return new URI(endpoint.concat("/")); + return new URL(endpoint.concat("/")).toURI(); } + } catch (MalformedURLException e) { + throw new UriBuilderException("Malformed personalized feed's URL."); } catch (URISyntaxException e) { throw new UriBuilderException("Malformed personalized feed's URL."); } diff --git a/stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java b/stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java new file mode 100644 index 00000000..ce9d98d4 --- /dev/null +++ b/stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java @@ -0,0 +1,38 @@ +package io.getstream.client.util; + +import io.getstream.client.config.ClientConfiguration; +import org.junit.Test; + +import java.net.URI; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class EndpointUtilTest { + + @Test + public void shouldGetPersonalizedEndpoint() throws Exception { + ClientConfiguration clientConfiguration = new ClientConfiguration(); + clientConfiguration.setPersonalizedFeedEndpoint("http://yourcompany.getstream.io/yourcompany"); + + URI personalizedEndpoint = EndpointUtil.getPersonalizedEndpoint(clientConfiguration); + assertThat(personalizedEndpoint.toString(), is("http://yourcompany.getstream.io/yourcompany/")); + } + + @Test + public void shouldGetPersonalizedEndpointWithoutDoubleSlash() throws Exception { + ClientConfiguration clientConfiguration = new ClientConfiguration(); + clientConfiguration.setPersonalizedFeedEndpoint("http://yourcompany.getstream.io/yourcompany/"); + + URI personalizedEndpoint = EndpointUtil.getPersonalizedEndpoint(clientConfiguration); + assertThat(personalizedEndpoint.toString(), is("http://yourcompany.getstream.io/yourcompany/")); + } + + @Test(expected = NullPointerException.class) + public void shouldFail() throws Exception { + ClientConfiguration clientConfiguration = new ClientConfiguration(); + clientConfiguration.setPersonalizedFeedEndpoint(null); + + EndpointUtil.getPersonalizedEndpoint(clientConfiguration); + } +} \ No newline at end of file diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImplTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImplTest.java new file mode 100644 index 00000000..134e1ed4 --- /dev/null +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImplTest.java @@ -0,0 +1,159 @@ +package io.getstream.client.apache.repo; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import io.getstream.client.apache.StreamClientImpl; +import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.config.StreamRegion; +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.PersonalizedActivity; +import io.getstream.client.model.feeds.PersonalizedFeed; +import io.getstream.client.util.JwtAuthenticationUtil; +import org.apache.http.impl.client.CloseableHttpClient; +import org.hamcrest.Matcher; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.mock; + +public class StreamPersonalizedRepositoryImplTest { + + public static final String API_KEY = "nfq26m3qgfyp"; + public static final String API_SECRET = "245nvvjm49s3uwrs5e4h3gadsw34mnwste6v3rdnd69ztb35bqspvq8kfzt9v7h2"; + + @Rule + public WireMockRule wireMockRule = new WireMockRule(8089); // No-args constructor defaults to port 8080 + + private final StreamPersonalizedRepositoryImpl streamRepository; + + private final StreamClientImpl streamClient; + + @BeforeClass + public static void setLog() { + System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); + System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); + System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "DEBUG"); + } + + public StreamPersonalizedRepositoryImplTest() { + ClientConfiguration clientConfiguration = new ClientConfiguration(); + clientConfiguration.setRegion(StreamRegion.LOCAL_TEST); + clientConfiguration.setPersonalizedFeedEndpoint("http://localhost:8089/yourcompany/"); + streamClient = new StreamClientImpl(clientConfiguration, API_KEY, API_SECRET); + streamRepository = new StreamPersonalizedRepositoryImpl(mock(ObjectMapper.class), clientConfiguration, mock(CloseableHttpClient.class)); + } + + @Test + public void shouldGet() throws StreamClientException, IOException { + stubFor(get(urlEqualTo("/yourcompany/personalized_feed/1234/?api_key=" + API_KEY)) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody("{\"duration\": \"7ms\", \"results\":[{\"tags\":[\"foo\", \"bar\"]}]}"))); + + PersonalizedFeed feed = streamClient.newPersonalizedFeed("user", "1234"); + List personalizedActivities = feed.get(PersonalizedActivity.class); + + System.out.println(JwtAuthenticationUtil.generateToken(API_SECRET, "*", "*", null, "1234")); + verify(getRequestedFor(urlEqualTo("/yourcompany/personalized_feed/1234/?api_key=" + API_KEY)) + .withHeader("stream-auth-type", equalTo("jwt")) + .withHeader("Authorization", containing(JwtAuthenticationUtil.generateToken(API_SECRET, "*", "*", null, "1234")))); + assertThat(personalizedActivities.get(0).getTags(), (Matcher) hasItems("foo", "bar")); + } + + @Test + public void shouldSendMeta() throws StreamClientException, IOException { + stubFor(post(urlEqualTo("/yourcompany/meta/?api_key=" + API_KEY)) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody("{\"duration\": \"0.07\"}"))); + + PersonalizedFeed feed = streamClient.newPersonalizedFeed("user", "1234"); + feed.addMeta(feed, new MetaInterest(Collections.singletonList("baseball"))); + + verify(postRequestedFor(urlEqualTo("/yourcompany/meta/?api_key=" + API_KEY)) + .withHeader("stream-auth-type", equalTo("jwt")) + .withHeader("Authorization", containing(JwtAuthenticationUtil.generateToken(API_SECRET, "*", "*", null, "1234"))) + .withRequestBody(containing("{\"data\":{\"user:1234\":{\"interests\":[\"baseball\"]}}}"))); + } + + class MetaInterest implements Serializable { + + private List interests = null; + + public MetaInterest() { + } + + public MetaInterest(List interests) { + this.interests = interests; + } + + public List getInterests() { + return interests; + } + + public void setInterests(List interests) { + this.interests = interests; + } + } + + class Interest implements Serializable { + + @JsonProperty("user_id") + private String userId; + + @JsonProperty("consumption_history") + private List consumptionHistory; + + @JsonProperty("profile_strength") + private Card profileStrength; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public List getConsumptionHistory() { + return consumptionHistory; + } + + public void setConsumptionHistory(List consumptionHistory) { + this.consumptionHistory = consumptionHistory; + } + + public Card getProfileStrength() { + return profileStrength; + } + + public void setProfileStrength(Card profileStrength) { + this.profileStrength = profileStrength; + } + } + + class Card implements Serializable { + private int card; + + public int getCard() { + return card; + } + + public void setCard(int card) { + this.card = card; + } + } +} \ No newline at end of file diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 92a50cac..bb09b6bf 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -75,6 +75,12 @@ mockito-core test + + com.github.tomakehurst + wiremock + standalone + test + diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java new file mode 100644 index 00000000..43d0fb37 --- /dev/null +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java @@ -0,0 +1,150 @@ +package io.getstream.client.okhttp.repo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import com.squareup.okhttp.OkHttpClient; +import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.config.StreamRegion; +import io.getstream.client.exception.StreamClientException; +import io.getstream.client.model.activities.PersonalizedActivity; +import io.getstream.client.model.feeds.PersonalizedFeed; +import io.getstream.client.okhttp.StreamClientImpl; +import io.getstream.client.util.JwtAuthenticationUtil; +import org.hamcrest.Matcher; +import org.junit.Rule; +import org.junit.Test; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.mock; + +public class StreamPersonalizedRepositoryImplTest { + + public static final String API_KEY = "nfq26m3qgfyp"; + public static final String API_SECRET = "245nvvjm49s3uwrs5e4h3gadsw34mnwste6v3rdnd69ztb35bqspvq8kfzt9v7h2"; + + @Rule + public WireMockRule wireMockRule = new WireMockRule(8089); // No-args constructor defaults to port 8080 + + private final StreamPersonalizedRepositoryImpl streamRepository; + + private final StreamClientImpl streamClient; + + public StreamPersonalizedRepositoryImplTest() { + ClientConfiguration clientConfiguration = new ClientConfiguration(); + clientConfiguration.setRegion(StreamRegion.LOCAL_TEST); + clientConfiguration.setPersonalizedFeedEndpoint("http://localhost:8089/yourcompany/"); + streamClient = new StreamClientImpl(clientConfiguration, API_KEY, API_SECRET); + streamRepository = new StreamPersonalizedRepositoryImpl(mock(ObjectMapper.class), clientConfiguration, mock(OkHttpClient.class)); + } + + @Test + public void shouldGet() throws StreamClientException, IOException { + stubFor(get(urlEqualTo("/yourcompany/personalized_feed/1234/?api_key=" + API_KEY)) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody("{\"duration\": \"7ms\", \"results\":[{\"tags\":[\"foo\", \"bar\"]}]}"))); + + PersonalizedFeed feed = streamClient.newPersonalizedFeed("user", "1234"); + List personalizedActivities = feed.get(PersonalizedActivity.class); + + System.out.println(JwtAuthenticationUtil.generateToken(API_SECRET, "*", "*", null, "1234")); + verify(getRequestedFor(urlEqualTo("/yourcompany/personalized_feed/1234/?api_key=" + API_KEY)) + .withHeader("stream-auth-type", equalTo("jwt")) + .withHeader("Authorization", containing(JwtAuthenticationUtil.generateToken(API_SECRET, "*", "*", null, "1234")))); + assertThat(personalizedActivities.get(0).getTags(), (Matcher) hasItems("foo", "bar")); + } + + @Test + public void shouldSendMeta() throws StreamClientException, IOException { + stubFor(post(urlEqualTo("/yourcompany/meta/?api_key=" + API_KEY)) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody("{\"duration\": \"0.07\"}"))); + + PersonalizedFeed feed = streamClient.newPersonalizedFeed("user", "1234"); + feed.addMeta(feed, new MetaInterest(Collections.singletonList("baseball"))); + + verify(postRequestedFor(urlEqualTo("/yourcompany/meta/?api_key=" + API_KEY)) + .withHeader("stream-auth-type", equalTo("jwt")) + .withHeader("Authorization", containing(JwtAuthenticationUtil.generateToken(API_SECRET, "*", "*", null, "1234"))) + .withRequestBody(containing("{\"data\":{\"user:1234\":{\"interests\":[\"baseball\"]}}}"))); + } + + class MetaInterest implements Serializable { + + private List interests = null; + + public MetaInterest() { + } + + public MetaInterest(List interests) { + this.interests = interests; + } + + public List getInterests() { + return interests; + } + + public void setInterests(List interests) { + this.interests = interests; + } + } + + class Interest implements Serializable { + + @JsonProperty("user_id") + private String userId; + + @JsonProperty("consumption_history") + private List consumptionHistory; + + @JsonProperty("profile_strength") + private Card profileStrength; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public List getConsumptionHistory() { + return consumptionHistory; + } + + public void setConsumptionHistory(List consumptionHistory) { + this.consumptionHistory = consumptionHistory; + } + + public Card getProfileStrength() { + return profileStrength; + } + + public void setProfileStrength(Card profileStrength) { + this.profileStrength = profileStrength; + } + } + + class Card implements Serializable { + private int card; + + public int getCard() { + return card; + } + + public void setCard(int card) { + this.card = card; + } + } +} \ No newline at end of file From 399601ebb638c35e5e0d418a21d5cf887e07eac0 Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 4 Aug 2017 12:07:15 +0200 Subject: [PATCH 065/320] Added filtering on Personalized feeds --- .../client/model/feeds/PersonalizedFeed.java | 14 +++++++------ .../model/feeds/PersonalizedFeedImpl.java | 5 +++-- .../repo/StreamPersonalizedRepository.java | 14 +++++++------ .../StreamPersonalizedRepositoryImpl.java | 8 ++++--- .../apache/repo/utils/FeedFilterUtils.java | 3 +++ .../apache/PersonalizedIntegrationTest.java | 21 ++++++++++++------- .../StreamPersonalizedRepositoryImplTest.java | 2 +- .../StreamPersonalizedRepositoryImpl.java | 8 ++++--- .../okhttp/repo/utils/FeedFilterUtils.java | 3 +++ .../okhttp/PersonalizedIntegrationTest.java | 14 +++++++------ .../StreamPersonalizedRepositoryImplTest.java | 2 +- 11 files changed, 59 insertions(+), 35 deletions(-) diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeed.java b/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeed.java index 5719d78b..9fa00a79 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeed.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeed.java @@ -3,6 +3,7 @@ import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.PersonalizedActivity; import io.getstream.client.model.beans.MetaResponse; +import io.getstream.client.model.filters.FeedFilter; import java.io.IOException; import java.io.Serializable; @@ -14,19 +15,20 @@ public interface PersonalizedFeed { /** - * Read a personalized feed.
+ * Read a personalized feed. * The response is deserialized by using Jackson, therefore Jackson's annotations and custom deserializers are honored. * @param type Since the personalized feed can be heavily customized, we need to know which class to use to perform deserialized. * @param Type of the class to use to perform deserialization. + * @param filter Filter out the results * @return Personalized feed * @throws IOException in case of network/socket exceptions * @throws StreamClientException in case of functional or server-side exception */ - List get(Class type) throws IOException, StreamClientException; + List get(Class type, FeedFilter filter) throws IOException, StreamClientException; /** - * "Certain objects such as user profiles, product details etc. aren't part of the feeds. They can however be useful for personalization."
- * Use this method to sync this data to Stream.
+ * "Certain objects such as user profiles, product details etc. aren't part of the feeds. They can however be useful for personalization." + * Use this method to sync this data to Stream. * The meta payload is serialized by using Jackson, therefore Jackson's annotations and custom serializers are honored. * @param feed The feed you want to enrich with meta-data * @param metaPayload The meta object can be customized by the customer. The method accepts any Serializable object. @@ -37,8 +39,8 @@ public interface PersonalizedFeed { MetaResponse addMeta(PersonalizedFeed feed, Serializable metaPayload) throws IOException, StreamClientException; /** - * Read the taste/ endpoint.
- * The response is deserialized by using Jackson, therefore Jackson's annotations and custom deserializers are honored.
+ * Read the taste/ endpoint. + * The response is deserialized by using Jackson, therefore Jackson's annotations and custom deserializers are honored. * This endpoint is not provided by default and is activated to selected customer. * @param type Since the personalized feed can be heavily customized, we need to know which class to use to perform deserialized. * @param Type of the class to use to perform deserialization. diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeedImpl.java b/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeedImpl.java index d5d3c44f..aafa14ba 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeedImpl.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeedImpl.java @@ -3,6 +3,7 @@ import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.PersonalizedActivity; import io.getstream.client.model.beans.MetaResponse; +import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.repo.StreamPersonalizedRepository; import java.io.IOException; @@ -25,8 +26,8 @@ public PersonalizedFeedImpl(StreamPersonalizedRepository streamRepository, Strin } @Override - public List get(Class type) throws IOException, StreamClientException { - return this.streamRepository.get(this, type); + public List get(Class type, FeedFilter filter) throws IOException, StreamClientException { + return this.streamRepository.get(this, type, filter); } @Override diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamPersonalizedRepository.java b/stream-core/src/main/java/io/getstream/client/repo/StreamPersonalizedRepository.java index 1a4c8008..75e1b547 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamPersonalizedRepository.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamPersonalizedRepository.java @@ -4,6 +4,7 @@ import io.getstream.client.model.activities.PersonalizedActivity; import io.getstream.client.model.beans.MetaResponse; import io.getstream.client.model.feeds.PersonalizedFeed; +import io.getstream.client.model.filters.FeedFilter; import java.io.IOException; import java.io.Serializable; @@ -15,20 +16,21 @@ public interface StreamPersonalizedRepository { /** - * Read a personalized feed.
+ * Read a personalized feed. * The response is deserialized by using Jackson, therefore Jackson's annotations and custom deserializers are honored. * @param feed the feed you want to read from * @param type Since the personalized feed can be heavily customized, we need to know which class to use to perform deserialized. * @param Type of the class to use to perform deserialization. + * @param filter Filter out the results. * @return Personalized feed * @throws IOException in case of network/socket exceptions * @throws StreamClientException in case of functional or server-side exception */ - List get(PersonalizedFeed feed, Class type) throws IOException, StreamClientException; + List get(PersonalizedFeed feed, Class type, FeedFilter filter) throws IOException, StreamClientException; /** - * "Certain objects such as user profiles, product details etc. aren't part of the feeds. They can however be useful for personalization."
- * Use this method to sync this data to Stream.
+ * "Certain objects such as user profiles, product details etc. aren't part of the feeds. They can however be useful for personalization." + * Use this method to sync this data to Stream. * The meta payload is serialized by using Jackson, therefore Jackson's annotations and custom serializers are honored. * @param feed The feed you want to enrich with meta-data * @param metaPayload The meta object can be customized by the customer. The method accepts any Serializable object. @@ -39,8 +41,8 @@ public interface StreamPersonalizedRepository { MetaResponse addMeta(PersonalizedFeed feed, Serializable metaPayload) throws IOException, StreamClientException; /** - * Read the taste/ endpoint.
- * The response is deserialized by using Jackson, therefore Jackson's annotations and custom deserializers are honored.
+ * Read the taste/ endpoint. + * The response is deserialized by using Jackson, therefore Jackson's annotations and custom deserializers are honored. * This endpoint is not provided by default and is activated to selected customer. * @param feed the feed you want to read from * @param type Since the personalized feed can be heavily customized, we need to know which class to use to perform deserialized. diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImpl.java index 22187b2f..56ab4f64 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImpl.java @@ -10,6 +10,7 @@ import io.getstream.client.model.beans.MetaResponse; import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.PersonalizedFeed; +import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.repo.StreamPersonalizedRepository; import io.getstream.client.repo.StreamRepository; import io.getstream.client.util.EndpointUtil; @@ -29,6 +30,7 @@ import java.util.Collections; import java.util.List; +import static io.getstream.client.apache.repo.utils.FeedFilterUtils.apply; import static io.getstream.client.util.JwtAuthenticationUtil.ALL; import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; import static org.apache.http.entity.ContentType.APPLICATION_JSON; @@ -66,11 +68,11 @@ public StreamPersonalizedRepositoryImpl(ObjectMapper objectMapper, } - public List get(PersonalizedFeed feed, Class type) throws IOException, StreamClientException { - HttpGet request = new HttpGet(UriBuilder.fromEndpoint(baseEndpoint) + public List get(PersonalizedFeed feed, Class type, FeedFilter filter) throws IOException, StreamClientException { + HttpGet request = new HttpGet(apply(UriBuilder.fromEndpoint(baseEndpoint) .path("personalized_feed/") .path(feed.getUserId().concat("/")) - .queryParam(API_KEY, apiKey).build()); + .queryParam(API_KEY, apiKey), filter).build()); LOG.debug("Invoking url: '{}'", request.getURI()); request = StreamRepoUtils.addJwtAuthentication(generateToken(secretKey, ALL, ALL, null, feed.getUserId()), request); diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java index 74af4a00..08f7fb21 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java @@ -17,6 +17,9 @@ private FeedFilterUtils() { * @return A {@link UriBuilder} */ public static UriBuilder apply(final UriBuilder uriBuilder, final FeedFilter filter) { + if (null == filter) { + return uriBuilder; + } if (null != filter.getLimit()) { uriBuilder.queryParam(FeedFilter.PARAM_LIMIT, filter.getLimit()); } diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/PersonalizedIntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/PersonalizedIntegrationTest.java index 1d99276a..d11e77ac 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/PersonalizedIntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/PersonalizedIntegrationTest.java @@ -8,6 +8,7 @@ import io.getstream.client.model.activities.PersonalizedActivity; import io.getstream.client.model.beans.MetaResponse; import io.getstream.client.model.feeds.PersonalizedFeed; +import io.getstream.client.model.filters.FeedFilter; import org.junit.BeforeClass; import org.junit.Test; @@ -22,8 +23,9 @@ public class PersonalizedIntegrationTest { - public static final String API_KEY = "qssg44g3xjqu"; - public static final String API_SECRET = "kq3ueg2wpxz9qjqkuxgfmhn8p768mxygg4tqtvxymnbbrfsdktf3ntz8ndg9eg53"; + public static final String PERSONALIZED_FEED_ENDPOINT = ""; + public static final String API_KEY = ""; + public static final String API_SECRET = ""; public static final ClientConfiguration CLIENT_CONFIGURATION = new ClientConfiguration(StreamRegion.QA_TEST); @BeforeClass @@ -35,16 +37,21 @@ public static void setLog() { @BeforeClass public static void initClient() { - CLIENT_CONFIGURATION.setPersonalizedFeedEndpoint("http://ml-api.staging.gtstrm.com:85/fullmeasureed"); + CLIENT_CONFIGURATION.setPersonalizedFeedEndpoint(PERSONALIZED_FEED_ENDPOINT); } @Test public void shouldGetPersonalizedFeed() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); - PersonalizedFeed feed = streamClient.newPersonalizedFeed("aggregated", "2"); - List response = feed.get(PersonalizedActivity.class); + PersonalizedFeed feed = streamClient.newPersonalizedFeed("aggregated", "f4774599-a0e5-46cb-81e8-451cb38d3fc7"); + List response = feed.get(PersonalizedActivity.class, new FeedFilter.Builder().withLimit(20).build()); assertTrue(response.size() > 0); + for (PersonalizedActivity personalizedActivity : response) { + System.out.println(personalizedActivity.getId()); + System.out.println(personalizedActivity.getTime()); + } + streamClient.shutdown(); } @@ -53,7 +60,7 @@ public void shouldGetPersonalizedFeed() throws IOException, StreamClientExceptio public void shouldGetPersonalizedFeedInterest() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); - PersonalizedFeed feed = streamClient.newPersonalizedFeed("aggregated", "2"); + PersonalizedFeed feed = streamClient.newPersonalizedFeed("aggregated", "f4774599-a0e5-46cb-81e8-451cb38d3fc7"); List response = feed.getInterest(Interest.class); assertTrue(response.size() > 0); @@ -65,7 +72,7 @@ public void shouldGetPersonalizedFeedInterest() throws IOException, StreamClient public void shouldSendMeta() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); - PersonalizedFeed feed = streamClient.newPersonalizedFeed("user", "2"); + PersonalizedFeed feed = streamClient.newPersonalizedFeed("user", "f4774599-a0e5-46cb-81e8-451cb38d3fc7"); MetaResponse response = feed.addMeta(feed, new MetaInterest(Collections.singletonList("java"))); assertThat(response.getResponseCode(), is(201)); diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImplTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImplTest.java index 134e1ed4..772049a2 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImplTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImplTest.java @@ -63,7 +63,7 @@ public void shouldGet() throws StreamClientException, IOException { .withBody("{\"duration\": \"7ms\", \"results\":[{\"tags\":[\"foo\", \"bar\"]}]}"))); PersonalizedFeed feed = streamClient.newPersonalizedFeed("user", "1234"); - List personalizedActivities = feed.get(PersonalizedActivity.class); + List personalizedActivities = feed.get(PersonalizedActivity.class, null); System.out.println(JwtAuthenticationUtil.generateToken(API_SECRET, "*", "*", null, "1234")); verify(getRequestedFor(urlEqualTo("/yourcompany/personalized_feed/1234/?api_key=" + API_KEY)) diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java index ddb7088e..bac8ad61 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java @@ -12,6 +12,7 @@ import io.getstream.client.model.beans.MetaResponse; import io.getstream.client.model.beans.StreamResponse; import io.getstream.client.model.feeds.PersonalizedFeed; +import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.okhttp.repo.handlers.StreamExceptionHandler; import io.getstream.client.okhttp.repo.utils.StreamRepoUtils; import io.getstream.client.okhttp.repo.utils.UriBuilder; @@ -26,6 +27,7 @@ import java.util.Collections; import java.util.List; +import static io.getstream.client.okhttp.repo.utils.FeedFilterUtils.apply; import static io.getstream.client.util.JwtAuthenticationUtil.ALL; import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; @@ -56,12 +58,12 @@ public StreamPersonalizedRepositoryImpl(ObjectMapper objectMapper, } @Override - public List get(PersonalizedFeed feed, Class type) throws IOException, StreamClientException { + public List get(PersonalizedFeed feed, Class type, FeedFilter filter) throws IOException, StreamClientException { Request.Builder requestBuilder = new Request.Builder().url( - UriBuilder.fromEndpoint(baseEndpoint) + apply(UriBuilder.fromEndpoint(baseEndpoint) .path("personalized_feed/") .path(feed.getUserId().concat("/")) - .queryParam(API_KEY, apiKey).build().toURL()).get(); + .queryParam(API_KEY, apiKey), filter).build().toURL()).get(); Request request = StreamRepoUtils.addJwtAuthentication( generateToken(secretKey, ALL, ALL, null, feed.getUserId()), diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/FeedFilterUtils.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/FeedFilterUtils.java index 430fb474..f8a4e731 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/FeedFilterUtils.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/FeedFilterUtils.java @@ -17,6 +17,9 @@ private FeedFilterUtils() { * @return A {@link UriBuilder} */ public static UriBuilder apply(final UriBuilder uriBuilder, final FeedFilter filter) { + if (null == filter) { + return uriBuilder; + } if (null != filter.getLimit()) { uriBuilder.queryParam(FeedFilter.PARAM_LIMIT, filter.getLimit()); } diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/PersonalizedIntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/PersonalizedIntegrationTest.java index 33986369..67bdbb3a 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/PersonalizedIntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/PersonalizedIntegrationTest.java @@ -8,6 +8,7 @@ import io.getstream.client.model.activities.PersonalizedActivity; import io.getstream.client.model.beans.MetaResponse; import io.getstream.client.model.feeds.PersonalizedFeed; +import io.getstream.client.model.filters.FeedFilter; import org.junit.BeforeClass; import org.junit.Test; @@ -22,21 +23,22 @@ public class PersonalizedIntegrationTest { - public static final String API_KEY = "qssg44g3xjqu"; - public static final String API_SECRET = "kq3ueg2wpxz9qjqkuxgfmhn8p768mxygg4tqtvxymnbbrfsdktf3ntz8ndg9eg53"; + public static final String PERSONALIZED_FEED_ENDPOINT = ""; + public static final String API_KEY = ""; + public static final String API_SECRET = ""; public static final ClientConfiguration CLIENT_CONFIGURATION = new ClientConfiguration(StreamRegion.QA_TEST); @BeforeClass public static void initClient() { - CLIENT_CONFIGURATION.setPersonalizedFeedEndpoint("http://ml-api.staging.gtstrm.com:85/fullmeasureed"); + CLIENT_CONFIGURATION.setPersonalizedFeedEndpoint(PERSONALIZED_FEED_ENDPOINT); } @Test public void shouldGetPersonalizedFeed() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); - PersonalizedFeed feed = streamClient.newPersonalizedFeed("aggregated", "2"); - List response = feed.get(PersonalizedActivity.class); + PersonalizedFeed feed = streamClient.newPersonalizedFeed("aggregated", "f4774599-a0e5-46cb-81e8-451cb38d3fc7"); + List response = feed.get(PersonalizedActivity.class, new FeedFilter.Builder().withLimit(20).build()); assertTrue(response.size() > 0); streamClient.shutdown(); @@ -46,7 +48,7 @@ public void shouldGetPersonalizedFeed() throws IOException, StreamClientExceptio public void shouldGetPersonalizedFeedInterest() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); - PersonalizedFeed feed = streamClient.newPersonalizedFeed("aggregated", "2"); + PersonalizedFeed feed = streamClient.newPersonalizedFeed("aggregated", "f4774599-a0e5-46cb-81e8-451cb38d3fc7"); List response = feed.getInterest(Interest.class); assertTrue(response.size() > 0); diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java index 43d0fb37..90561f18 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java @@ -54,7 +54,7 @@ public void shouldGet() throws StreamClientException, IOException { .withBody("{\"duration\": \"7ms\", \"results\":[{\"tags\":[\"foo\", \"bar\"]}]}"))); PersonalizedFeed feed = streamClient.newPersonalizedFeed("user", "1234"); - List personalizedActivities = feed.get(PersonalizedActivity.class); + List personalizedActivities = feed.get(PersonalizedActivity.class, null); System.out.println(JwtAuthenticationUtil.generateToken(API_SECRET, "*", "*", null, "1234")); verify(getRequestedFor(urlEqualTo("/yourcompany/personalized_feed/1234/?api_key=" + API_KEY)) From bc2c23ff49f3dd558f1d496cfebd10937d051aa1 Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 4 Aug 2017 12:23:01 +0200 Subject: [PATCH 066/320] Fixed javadoc --- .../getstream/client/model/activities/PersonalizedActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java b/stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java index b9b8cc92..c6d4f871 100644 --- a/stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java +++ b/stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java @@ -3,7 +3,7 @@ import java.util.List; /** - * Personalized activities are subset of {@see io.getstream.client.model.activities.BaseActivity}. + * Personalized activities are subset of {@link io.getstream.client.model.activities.BaseActivity}. * Any custom personalized activity must be a subclasses of PersonalizedActivity. */ public class PersonalizedActivity extends BaseActivity { From 90053a1cb88c9eaed3509e0e010ea99e83664b9e Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 4 Aug 2017 12:31:14 +0200 Subject: [PATCH 067/320] [maven-release-plugin] prepare release stream-java-1.3.1 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 0ba7e821..8045a973 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.3.1-SNAPSHOT + 1.3.1 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-1.3.1 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index f4d5caf0..7fba27da 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.1-SNAPSHOT + 1.3.1 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 8c00e8b9..04fa040b 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.1-SNAPSHOT + 1.3.1 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index bb09b6bf..4824acf2 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.1-SNAPSHOT + 1.3.1 4.0.0 From 23bb478c41523bb6df08795cc77dd78c37ac005f Mon Sep 17 00:00:00 2001 From: alessandro Date: Fri, 4 Aug 2017 12:31:20 +0200 Subject: [PATCH 068/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 8045a973..1707cc26 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.3.1 + 1.3.2-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-1.3.1 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 7fba27da..d422d8f5 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.1 + 1.3.2-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 04fa040b..be76f6e8 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.1 + 1.3.2-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 4824acf2..f1c4c666 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.1 + 1.3.2-SNAPSHOT 4.0.0 From 383259e9fe5657d6042a47a977028e05b73afe9b Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Fri, 4 Aug 2017 12:37:33 +0200 Subject: [PATCH 069/320] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index eaaac38d..55848b0e 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 1.3.0 + 1.3.1 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:1.3.0' +compile 'io.getstream.client:stream-repo-apache:1.3.1' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -36,14 +36,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 1.3.0 + 1.3.1 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:1.3.0' +compile 'io.getstream.client:stream-repo-okhttp:1.3.1' ``` In case you want to download the artifact and put it manually into your project, From 27e5510480a63617bdaa9d3f05ece0a927449d59 Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 8 Aug 2017 15:32:32 +0200 Subject: [PATCH 070/320] Fixed issue with activity_copy_limit --- .../client/model/beans/FollowRequest.java | 36 +++++++++++++++++++ .../apache/repo/StreamRepositoryImpl.java | 7 ++-- .../client/apache/IntegrationTest.java | 7 +++- .../apache/repo/StreamRepositoryImplTest.java | 1 - .../okhttp/repo/StreamRepositoryImpl.java | 5 ++- .../client/okhttp/IntegrationTest.java | 9 +++-- 6 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/FollowRequest.java diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/FollowRequest.java b/stream-core/src/main/java/io/getstream/client/model/beans/FollowRequest.java new file mode 100644 index 00000000..2d9846f3 --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/model/beans/FollowRequest.java @@ -0,0 +1,36 @@ +package io.getstream.client.model.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class FollowRequest { + + private String target; + + @JsonProperty("activity_copy_limit") + private Integer activityCopyLimit; + + public FollowRequest() { + + } + + public FollowRequest(String target, Integer activityCopyLimit) { + this.target = target; + this.activityCopyLimit = activityCopyLimit; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public Integer getActivityCopyLimit() { + return activityCopyLimit; + } + + public void setActivityCopyLimit(Integer activityCopyLimit) { + this.activityCopyLimit = activityCopyLimit; + } +} diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index f432a092..06d1f497 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -13,6 +13,7 @@ import io.getstream.client.model.activities.NotificationActivity; import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; +import io.getstream.client.model.beans.FollowRequest; import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; @@ -33,7 +34,6 @@ import java.io.IOException; import java.net.URI; -import java.util.Collections; import java.util.List; import static io.getstream.client.apache.repo.utils.FeedFilterUtils.apply; @@ -85,11 +85,10 @@ public String getReadOnlyToken(BaseFeed feed) { public void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) throws StreamClientException, IOException { HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) .path("feed").path(feed.getFeedSlug()).path(feed.getUserId()).path("following/") - .queryParam("activity_copy_limit", activityCopyLimit) .queryParam(API_KEY, apiKey).build()); + request.setEntity(new StringEntity( - objectMapper.writeValueAsString(Collections.singletonMap("target", targetFeedId)), - APPLICATION_JSON)); + objectMapper.writeValueAsString(new FollowRequest(targetFeedId, activityCopyLimit)), APPLICATION_JSON)); fireAndForget(addAuthentication(feed, request)); } diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index 7b5c48fe..e649f150 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -127,14 +127,19 @@ public void shouldFollowWithActivityCopyLimit() throws IOException, StreamClient String followerId = this.getTestUserId("shouldFollow"); Feed feed = streamClient.newFeed("user", followerId); + FlatActivityServiceImpl flatActivityService = feed.newFlatActivityService(SimpleActivity.class); + assertThat(flatActivityService.getActivities().getResults().size(), is(0)); + List following = feed.getFollowing(); assertThat(following.size(), is(0)); - feed.follow("user", "1", 50); + feed.follow("user", "1", 10); List followingAfter = feed.getFollowing(); assertThat(followingAfter.size(), is(1)); + assertThat(flatActivityService.getActivities().getResults().size(), is(10)); + streamClient.shutdown(); } diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java index 686ce4ca..ff6bd222 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java @@ -83,5 +83,4 @@ public void shouldFollowMany() throws StreamClientException, IOException { .withRequestBody(containing("\"target\":\"user:3\"")) ); } - } \ No newline at end of file diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index 897399ab..e52c9de5 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -14,6 +14,7 @@ import io.getstream.client.model.activities.NotificationActivity; import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; +import io.getstream.client.model.beans.FollowRequest; import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; @@ -32,7 +33,6 @@ import java.io.IOException; import java.net.URI; -import java.util.Collections; import java.util.List; /** @@ -88,11 +88,10 @@ public String getToken(BaseFeed feed) { public void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) throws StreamClientException, IOException { Request.Builder requestBuilder = new Request.Builder().url(UriBuilder.fromEndpoint(baseEndpoint) .path("feed").path(feed.getFeedSlug()).path(feed.getUserId()).path("following/") - .queryParam("activity_copy_limit", activityCopyLimit) .queryParam(API_KEY, apiKey).build().toURL()); requestBuilder.post( RequestBody.create(MediaType.parse(APPLICATION_JSON), - objectMapper.writeValueAsString(Collections.singletonMap("target", targetFeedId)))); + objectMapper.writeValueAsString(new FollowRequest(targetFeedId, activityCopyLimit)))); Request request = addAuthentication(feed, requestBuilder).build(); fireAndForget(request); diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index 5c713e3d..c4a58a53 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -118,17 +118,22 @@ public void shouldFollowWithActivityCopyLimit() throws IOException, StreamClient StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); - String followerId = this.getTestUserId("shouldFollow"); + String followerId = this.getTestUserId("shouldFollowOkHttp"); Feed feed = streamClient.newFeed("user", followerId); + FlatActivityServiceImpl flatActivityService = feed.newFlatActivityService(SimpleActivity.class); + assertThat(flatActivityService.getActivities().getResults().size(), is(0)); + List following = feed.getFollowing(); assertThat(following.size(), is(0)); - feed.follow("user", "1", 50); + feed.follow("user", "1", 10); List followingAfter = feed.getFollowing(); assertThat(followingAfter.size(), is(1)); + assertThat(flatActivityService.getActivities().getResults().size(), is(10)); + streamClient.shutdown(); } From 2cdbec12be07ef2e981395d1ee38e3f0782c969a Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 8 Aug 2017 15:37:52 +0200 Subject: [PATCH 071/320] [maven-release-plugin] prepare release stream-java-1.3.2 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 1707cc26..d1a7f968 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.3.2-SNAPSHOT + 1.3.2 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-1.3.2 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index d422d8f5..73594e5a 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.2-SNAPSHOT + 1.3.2 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index be76f6e8..4f2f7bff 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.2-SNAPSHOT + 1.3.2 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index f1c4c666..9eca3ed6 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.2-SNAPSHOT + 1.3.2 4.0.0 From 2be5edc0a48038367f8199b492cea6ec1c3eebaf Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 8 Aug 2017 15:37:58 +0200 Subject: [PATCH 072/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index d1a7f968..9af6067c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.3.2 + 1.3.3-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-1.3.2 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 73594e5a..40af52f5 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.2 + 1.3.3-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 4f2f7bff..61d1fe21 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.2 + 1.3.3-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 9eca3ed6..59c1eb66 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.2 + 1.3.3-SNAPSHOT 4.0.0 From e9b499d64b4236df5053cb3a54abcdad144a5e9b Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 8 Aug 2017 15:42:23 +0200 Subject: [PATCH 073/320] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 55848b0e..cbf8d2c5 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 1.3.1 + 1.3.2 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:1.3.1' +compile 'io.getstream.client:stream-repo-apache:1.3.2' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -36,14 +36,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 1.3.1 + 1.3.2 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:1.3.1' +compile 'io.getstream.client:stream-repo-okhttp:1.3.2' ``` In case you want to download the artifact and put it manually into your project, From 82649acc6368589eb801c0b4515a9820374a53bb Mon Sep 17 00:00:00 2001 From: Dwight Gunning Date: Wed, 23 Aug 2017 10:22:44 +0200 Subject: [PATCH 074/320] Add feedId setter to FeedFilter.Builder sub-class Fixes getstream/stream-java#30. --- .../java/io/getstream/client/model/filters/FeedFilter.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java b/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java index 1928ea7b..17ec5f56 100644 --- a/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java +++ b/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java @@ -115,5 +115,10 @@ public Builder withRanking(String ranking) { feedFilter.ranking = ranking; return this; } + + public Builder withFeedIds(List feeds) { + feedFilter.feedIds = feeds; + return this; + } } } From cd6b3d3e9f44f798f4e8671e618044cbaaaa2e9f Mon Sep 17 00:00:00 2001 From: Dwight Gunning Date: Wed, 23 Aug 2017 11:11:01 +0200 Subject: [PATCH 075/320] Added integration tests --- .../io/getstream/client/apache/IntegrationTest.java | 8 ++++++-- .../io/getstream/client/okhttp/IntegrationTest.java | 12 ++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index e649f150..5c07ecc4 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -164,10 +164,14 @@ public void shouldFollowMany() throws IOException, StreamClientException { List followingAfter = feed.getFollowing(); assertThat(followingAfter.size(), is(3)); - FeedFilter filter = new FeedFilter.Builder().withLimit(1).withOffset(1).build(); - List followingPaged = feed.getFollowing(filter); + FeedFilter filterPaged = new FeedFilter.Builder().withLimit(1).withOffset(1).build(); + List followingPaged = feed.getFollowing(filterPaged); assertThat(followingPaged.size(), is(1)); + FeedFilter filterByIds = new FeedFilter.Builder().withFeedIds(Arrays.asList("user:1", "user:2")).build(); + List followingIds = feed.getFollowing(filterByIds); + assertThat(followingIds.size(), is(2)); + streamClient.shutdown(); } diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index c4a58a53..222d3f4b 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -49,7 +49,7 @@ public class IntegrationTest { public static final String API_KEY = "aygdeg2vhjxg"; public static final String API_SECRET = "4vknf33hn4n94exgrg367jbmg4jxetem93bqcg3nkdf2xau3q8pmy3pftytq4w8v"; public static final ClientConfiguration CLIENT_CONFIGURATION = new ClientConfiguration(StreamRegion.QA_TEST); - + public String getTestUserId(String userId) { long millis = System.currentTimeMillis(); return String.format("%s_%d", userId, millis); @@ -158,10 +158,14 @@ public void shouldFollowMany() throws IOException, StreamClientException { List followingAfter = feed.getFollowing(); assertThat(followingAfter.size(), is(3)); - FeedFilter filter = new FeedFilter.Builder().withLimit(1).withOffset(1).build(); - List followingPaged = feed.getFollowing(filter); + FeedFilter filterPaged = new FeedFilter.Builder().withLimit(1).withOffset(1).build(); + List followingPaged = feed.getFollowing(filterPaged); assertThat(followingPaged.size(), is(1)); + FeedFilter filterByIds = new FeedFilter.Builder().withFeedIds(Arrays.asList("user:1", "user:2")).build(); + List followingIds = feed.getFollowing(filterByIds); + assertThat(followingIds.size(), is(2)); + streamClient.shutdown(); } @@ -771,4 +775,4 @@ private Map verifyToken(final String token) throws SignatureExce byte[] secret = API_SECRET.getBytes(); return new JWTVerifier(secret, "audience").verify(token); } -} \ No newline at end of file +} From f175d7830d88afb0598176e2b5c65fe0fb483e7c Mon Sep 17 00:00:00 2001 From: Dwight Gunning Date: Wed, 23 Aug 2017 11:29:24 +0200 Subject: [PATCH 076/320] Added unit tests for FeedFilter --- .../client/model/FeedFilterTest.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 stream-core/src/test/java/io/getstream/client/model/FeedFilterTest.java diff --git a/stream-core/src/test/java/io/getstream/client/model/FeedFilterTest.java b/stream-core/src/test/java/io/getstream/client/model/FeedFilterTest.java new file mode 100644 index 00000000..d7ff472b --- /dev/null +++ b/stream-core/src/test/java/io/getstream/client/model/FeedFilterTest.java @@ -0,0 +1,61 @@ +package io.getstream.client.model.filters; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +public class FeedFilterTest { + + @Test + public void shouldBuildFeedFilter() { + int limit = 3; + int offset = 4; + String id_gt = "abc"; + String id_gte = "def"; + String id_lt = "ghi"; + String id_lte = "jkl"; + String ranking = "ranking-method"; + List feedIds = Arrays.asList("user:123", "user:456"); + + FeedFilter filter = new FeedFilter.Builder() + .withLimit(limit) + .withOffset(offset) + .withIdGreaterThan(id_gt) + .withIdGreaterThanEquals(id_gte) + .withIdLowerThan(id_lt) + .withIdLowerThanEquals(id_lte) + .withRanking(ranking) + .withFeedIds(feedIds) + .build(); + + assertThat(filter.getLimit(), is(limit)); + assertThat(filter.getOffset(), is(offset)); + assertThat(filter.getIdGreaterThan(), is(id_gt)); + assertThat(filter.getIdGreaterThanEquals(), is(id_gte)); + assertThat(filter.getIdLowerThan(), is(id_lt)); + assertThat(filter.getIdLowerThanEquals(), is(id_lte)); + assertThat(filter.getRanking(), is(ranking)); + assertThat(filter.getFeedIds(), is(feedIds)); + } + + @Test + public void shouldBuildFeedFilterDefaults() { + + FeedFilter filter = new FeedFilter.Builder().build(); + + assertThat(filter.getLimit(), is(25)); + assertThat(filter.getOffset(), is(nullValue())); + assertThat(filter.getIdGreaterThan(), is(nullValue())); + assertThat(filter.getIdGreaterThanEquals(), is(nullValue())); + assertThat(filter.getIdLowerThan(), is(nullValue())); + assertThat(filter.getIdLowerThanEquals(), is(nullValue())); + assertThat(filter.getRanking(), is(nullValue())); + assertThat(filter.getFeedIds(), is(nullValue())); + } + +} From e61d177a0b7d49733ba651669ea6673e32cd83c8 Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 23 Aug 2017 13:43:55 +0200 Subject: [PATCH 077/320] [maven-release-plugin] prepare release stream-java-1.3.3 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 9af6067c..6729198a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.3.3-SNAPSHOT + 1.3.3 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-1.3.3 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 40af52f5..873584c8 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.3-SNAPSHOT + 1.3.3 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 61d1fe21..cce7219b 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.3-SNAPSHOT + 1.3.3 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 59c1eb66..9a55cdfc 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.3-SNAPSHOT + 1.3.3 4.0.0 From eaf820a6a082fe3cd8487ab9342d578f92d316f0 Mon Sep 17 00:00:00 2001 From: alessandro Date: Wed, 23 Aug 2017 13:44:01 +0200 Subject: [PATCH 078/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 6729198a..8aad8085 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.3.3 + 1.3.4-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-1.3.3 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 873584c8..0f554f5f 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.3 + 1.3.4-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index cce7219b..0026dde5 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.3 + 1.3.4-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 9a55cdfc..84df0681 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.3 + 1.3.4-SNAPSHOT 4.0.0 From 1650dab58c6bd21b3f7f0e52ef132f1482cfcf4d Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 23 Aug 2017 13:49:18 +0200 Subject: [PATCH 079/320] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cbf8d2c5..e38252d5 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 1.3.2 + 1.3.3 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:1.3.2' +compile 'io.getstream.client:stream-repo-apache:1.3.3' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -36,14 +36,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 1.3.2 + 1.3.3 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:1.3.2' +compile 'io.getstream.client:stream-repo-okhttp:1.3.3' ``` In case you want to download the artifact and put it manually into your project, From 17483508c712569ceaaefe80e1a664b92da05bf7 Mon Sep 17 00:00:00 2001 From: Dwight Gunning Date: Thu, 12 Oct 2017 14:18:06 +0200 Subject: [PATCH 080/320] Updated StreamRegion to use new stream-io-api.com domain --- .../io/getstream/client/config/StreamRegion.java | 15 +++++++-------- .../getstream/client/config/StreamRegionTest.java | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java index 6e2cadf8..dfd3779d 100644 --- a/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java +++ b/stream-core/src/main/java/io/getstream/client/config/StreamRegion.java @@ -10,15 +10,14 @@ */ public enum StreamRegion { - BASE("https://api.getstream.io/api"), - US_EAST("https://us-east-api.getstream.io/api"), - US_WEST("https://us-west-api.getstream.io/api"), - EU_WEST("https://eu-west-api.getstream.io/api"), - AP_NORTH_EAST("https://ap-northeast-api.getstream.io/api"), - AP_SOUTH_EAST("https://ap-southeast-api.getstream.io/api"), + BASE("https://api.stream-io-api.com/api"), + US_EAST("https://us-east-api.stream-io-api.com/api"), + US_WEST("https://us-west-api.stream-io-api.com/api"), + EU_WEST("https://eu-west-api.stream-io-api.com/api"), + AP_NORTH_EAST("https://ap-northeast-api.stream-io-api.com/api"), + AP_SOUTH_EAST("https://ap-southeast-api.stream-io-api.com/api"), LOCAL_TEST("http://localhost:8089/api"), /* used for testing purpose only */ - QA_TEST("http://qa-api.getstream.io/api"), /* used for integration test */ - SNI_TEST("https://sni-api.getstream.io/api"); /* used for testing purpose only */ + QA_TEST("https://qa-api.stream-io-api.com/api"); /* used for integration test */ protected final static String VERSION = "v1.0"; diff --git a/stream-core/src/test/java/io/getstream/client/config/StreamRegionTest.java b/stream-core/src/test/java/io/getstream/client/config/StreamRegionTest.java index 0a06fe53..81c0f47a 100644 --- a/stream-core/src/test/java/io/getstream/client/config/StreamRegionTest.java +++ b/stream-core/src/test/java/io/getstream/client/config/StreamRegionTest.java @@ -9,6 +9,6 @@ public class StreamRegionTest { @Test public void shouldGetEndpoint() { - assertThat(StreamRegion.US_EAST.getEndpoint().toString(), is("https://us-east-api.getstream.io/api/" + StreamRegion.VERSION)); + assertThat(StreamRegion.US_EAST.getEndpoint().toString(), is("https://us-east-api.stream-io-api.com/api/" + StreamRegion.VERSION)); } -} \ No newline at end of file +} From 020608b8f7a63046083be6e6a14814f62dad401b Mon Sep 17 00:00:00 2001 From: Dwight Gunning Date: Mon, 16 Oct 2017 13:10:01 +0200 Subject: [PATCH 081/320] Added version requirement statement to README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index cbf8d2c5..551e9122 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,12 @@ you can download it from [here](https://github.com/GetStream/stream-java/release Snapshots of the development version are available in [Sonatype](https://oss.sonatype.org/content/repositories/snapshots/io/getstream/client/) snapshots repository. +#### JDK / JVM version requirements + +This API Client project requires Java SE 8. + +See the [Travis configuration](.travis.yml) for details of how it is built, tested and packaged. + ### Full documentation Documentation for this Java client are available at the [Stream website](https://getstream.io/docs/?language=java). From cb3b7c2ed43954af71e77675753031b7737d42eb Mon Sep 17 00:00:00 2001 From: alessandro Date: Mon, 16 Oct 2017 18:06:54 +0200 Subject: [PATCH 082/320] Added a new configuration param to override the default GetStream.io regional endpoint --- .../client/config/ClientConfiguration.java | 16 ++++++++++++++++ .../io/getstream/client/util/EndpointUtil.java | 17 +++++++++++++++++ .../client/util/EndpointUtilTest.java | 18 ++++++++++++++++++ .../apache/repo/StreamRepositoryImpl.java | 3 ++- .../okhttp/repo/StreamRepositoryImpl.java | 3 ++- 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java b/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java index 2fb167ee..96900601 100644 --- a/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java +++ b/stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java @@ -52,6 +52,14 @@ public class ClientConfiguration { */ private String personalizedFeedEndpoint; + /** + * Set a custom endpoint. + * If set the client will use the given endpoint instead of the default one associated with + * the selected region. + * It is usually not needed to provide an endpoint here. + */ + private String defaultEndpoint; + private AuthenticationHandlerConfiguration authenticationHandlerConfiguration; @@ -155,4 +163,12 @@ public String getPersonalizedFeedEndpoint() { public void setPersonalizedFeedEndpoint(String personalizedFeedEndpoint) { this.personalizedFeedEndpoint = personalizedFeedEndpoint; } + + public String getDefaultEndpoint() { + return defaultEndpoint; + } + + public void setDefaultEndpoint(String defaultEndpoint) { + this.defaultEndpoint = defaultEndpoint; + } } diff --git a/stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java b/stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java index 1f83b0d2..81796567 100644 --- a/stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java +++ b/stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java @@ -38,4 +38,21 @@ public static URI getPersonalizedEndpoint(ClientConfiguration streamClient) { throw new UriBuilderException("Malformed personalized feed's URL."); } } + + /** + * Build the base endpoint. + * @param streamClient Configuration container + * @return A valid URI endpoint + * @throws UriBuilderException In case the URI is malformed + */ + public static URI getBaseEndpoint(final ClientConfiguration streamClient) throws UriBuilderException { + if (null != streamClient.getDefaultEndpoint()) { + try { + return new URI(streamClient.getDefaultEndpoint()); + } catch (URISyntaxException e) { + throw new UriBuilderException("Malformed GetStream.io base URL."); + } + } + return streamClient.getRegion().getEndpoint(); + } } diff --git a/stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java b/stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java index ce9d98d4..3952c181 100644 --- a/stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java +++ b/stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java @@ -1,6 +1,7 @@ package io.getstream.client.util; import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.config.StreamRegion; import org.junit.Test; import java.net.URI; @@ -28,6 +29,23 @@ public void shouldGetPersonalizedEndpointWithoutDoubleSlash() throws Exception { assertThat(personalizedEndpoint.toString(), is("http://yourcompany.getstream.io/yourcompany/")); } + @Test + public void shouldGetCustomEndpoint() throws Exception { + ClientConfiguration clientConfiguration = new ClientConfiguration(); + clientConfiguration.setDefaultEndpoint("http://www.example.com/v1"); + + URI personalizedEndpoint = EndpointUtil.getBaseEndpoint(clientConfiguration); + assertThat(personalizedEndpoint.toString(), is("http://www.example.com/v1")); + } + + @Test + public void shouldGetRegionDefaultEndpoint() throws Exception { + ClientConfiguration clientConfiguration = new ClientConfiguration(StreamRegion.US_EAST); + + URI personalizedEndpoint = EndpointUtil.getBaseEndpoint(clientConfiguration); + assertThat(personalizedEndpoint.toString(), is(StreamRegion.US_EAST.getEndpoint().toString())); + } + @Test(expected = NullPointerException.class) public void shouldFail() throws Exception { ClientConfiguration clientConfiguration = new ClientConfiguration(); diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index 06d1f497..b8f6c851 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -20,6 +20,7 @@ import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.repo.StreamRepository; +import io.getstream.client.util.EndpointUtil; import io.getstream.client.util.JwtAuthenticationUtil; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpDelete; @@ -67,7 +68,7 @@ public class StreamRepositoryImpl implements StreamRepository { */ public StreamRepositoryImpl(ObjectMapper objectMapper, ClientConfiguration streamClient, CloseableHttpClient closeableHttpClient) { this.objectMapper = objectMapper; - this.baseEndpoint = streamClient.getRegion().getEndpoint(); + this.baseEndpoint = EndpointUtil.getBaseEndpoint(streamClient); this.apiKey = streamClient.getAuthenticationHandlerConfiguration().getApiKey(); this.secretKey = streamClient.getAuthenticationHandlerConfiguration().getSecretKey(); this.exceptionHandler = new StreamExceptionHandler(objectMapper); diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index e52c9de5..f3e003e8 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -26,6 +26,7 @@ import io.getstream.client.okhttp.repo.utils.StreamRepoUtils; import io.getstream.client.okhttp.repo.utils.UriBuilder; import io.getstream.client.repo.StreamRepository; +import io.getstream.client.util.EndpointUtil; import io.getstream.client.util.HttpSignatureHandler; import io.getstream.client.util.JwtAuthenticationUtil; import org.slf4j.Logger; @@ -64,7 +65,7 @@ public class StreamRepositoryImpl implements StreamRepository { * @param closeableHttpClient Actual instance of OkHTTP client */ public StreamRepositoryImpl(ObjectMapper objectMapper, ClientConfiguration streamClient, OkHttpClient closeableHttpClient) { - this.baseEndpoint = streamClient.getRegion().getEndpoint(); + this.baseEndpoint = EndpointUtil.getBaseEndpoint(streamClient); this.apiKey = streamClient.getAuthenticationHandlerConfiguration().getApiKey(); this.secretKey = streamClient.getAuthenticationHandlerConfiguration().getSecretKey(); this.exceptionHandler = new StreamExceptionHandler(objectMapper); From 406fc4e9f95698ebcb409190e201d38992df490c Mon Sep 17 00:00:00 2001 From: alessandro Date: Mon, 16 Oct 2017 18:07:58 +0200 Subject: [PATCH 083/320] Exception handling improvement --- .../exception/RateLimitExceededException.java | 27 ++++ .../repo/handlers/StreamExceptionHandler.java | 36 ++++-- .../handlers/StreamExceptionHandlerTest.java | 92 ++++++++++++++ .../repo/handlers/StreamExceptionHandler.java | 28 ++++- .../handlers/StreamExceptionHandlerTest.java | 119 ++++++++++++++++++ 5 files changed, 287 insertions(+), 15 deletions(-) create mode 100644 stream-core/src/main/java/io/getstream/client/exception/RateLimitExceededException.java create mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandlerTest.java create mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandlerTest.java diff --git a/stream-core/src/main/java/io/getstream/client/exception/RateLimitExceededException.java b/stream-core/src/main/java/io/getstream/client/exception/RateLimitExceededException.java new file mode 100644 index 00000000..55653f3c --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/exception/RateLimitExceededException.java @@ -0,0 +1,27 @@ +package io.getstream.client.exception; + +/** + * In case you have exceed your allowed calls per time interval (i.e. 1min, 15min or 1hr) + */ +public class RateLimitExceededException extends StreamClientException { + + public RateLimitExceededException() { + super(); + } + + public RateLimitExceededException(String message) { + super(message); + } + + public RateLimitExceededException(String message, Throwable cause) { + super(message, cause); + } + + public RateLimitExceededException(Throwable cause) { + super(cause); + } + + protected RateLimitExceededException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java index 2a9e1ea6..b6fbd9a7 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java @@ -2,13 +2,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.getstream.client.exception.AuthenticationFailedException; -import io.getstream.client.exception.InvalidOrMissingInputException; -import io.getstream.client.exception.StreamClientException; import io.getstream.client.exception.InternalServerException; +import io.getstream.client.exception.InvalidOrMissingInputException; +import io.getstream.client.exception.RateLimitExceededException; import io.getstream.client.exception.ResourceNotFoundException; +import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.beans.StreamErrorResponse; import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.util.EntityUtils; import java.io.IOException; @@ -38,7 +38,15 @@ public StreamExceptionHandler(ObjectMapper objectMapper) { * @throws StreamClientException in case of functional or server-side exception */ public void handleResponseCode(final CloseableHttpResponse response) throws IOException, StreamClientException { - switch (response.getStatusLine().getStatusCode()) { + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode < 200 || statusCode > 299) { + parseException(response); + } + } + + private void parseException(final CloseableHttpResponse response) throws IOException, StreamClientException { + int statusCode = response.getStatusLine().getStatusCode(); + switch (statusCode) { case 400: throw buildException(new InvalidOrMissingInputException(), response); case 401: @@ -47,19 +55,27 @@ public void handleResponseCode(final CloseableHttpResponse response) throws IOEx throw buildException(new AuthenticationFailedException(), response); case 404: throw buildException(new ResourceNotFoundException(), response); + case 429: + throw buildException(new RateLimitExceededException(), response); case 500: throw buildException(new InternalServerException(), response); + default: + StreamClientException e = new InternalServerException(); + e.setCode(statusCode); + e.setHttpStatusCode(statusCode); + throw e; } } private StreamClientException buildException(StreamClientException exception, CloseableHttpResponse response) throws IOException { - String responseMessage = EntityUtils.toString(response.getEntity()); - StreamErrorResponse error = objectMapper.readValue(responseMessage, StreamErrorResponse.class); - exception.setCode(error.getCode()); - exception.setHttpStatusCode(error.getStatusCode()); - exception.setDetail(error.getDetail()); - exception.setExceptionField(error.getException()); + StreamErrorResponse error = objectMapper.readValue(response.getEntity().getContent(), StreamErrorResponse.class); + if (null != error) { + exception.setCode(error.getCode()); + exception.setHttpStatusCode(response.getStatusLine().getStatusCode()); + exception.setDetail(error.getDetail()); + exception.setExceptionField(error.getException()); + } return exception; } } diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandlerTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandlerTest.java new file mode 100644 index 00000000..5a45cf43 --- /dev/null +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandlerTest.java @@ -0,0 +1,92 @@ +package io.getstream.client.apache.repo.handlers; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.getstream.client.exception.AuthenticationFailedException; +import io.getstream.client.exception.InternalServerException; +import io.getstream.client.exception.InvalidOrMissingInputException; +import io.getstream.client.exception.RateLimitExceededException; +import io.getstream.client.exception.ResourceNotFoundException; +import io.getstream.client.exception.StreamClientException; +import org.apache.http.ProtocolVersion; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.entity.StringEntity; +import org.apache.http.message.BasicStatusLine; +import org.junit.Test; + +import java.io.IOException; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class StreamExceptionHandlerTest { + + private final StreamExceptionHandler exceptionHandler; + + public StreamExceptionHandlerTest() { + exceptionHandler = new StreamExceptionHandler(mock(ObjectMapper.class)); + } + + @Test(expected = RateLimitExceededException.class) + public void testError429() throws IOException, StreamClientException { + CloseableHttpResponse response = mock(CloseableHttpResponse.class); + when(response.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 429, "")); + when(response.getEntity()).thenReturn(new StringEntity("")); + exceptionHandler.handleResponseCode(response); + } + + @Test(expected = InvalidOrMissingInputException.class) + public void testError400() throws IOException, StreamClientException { + CloseableHttpResponse response = mock(CloseableHttpResponse.class); + when(response.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 400, "")); + when(response.getEntity()).thenReturn(new StringEntity("")); + exceptionHandler.handleResponseCode(response); + } + + @Test(expected = AuthenticationFailedException.class) + public void testError401() throws IOException, StreamClientException { + CloseableHttpResponse response = mock(CloseableHttpResponse.class); + when(response.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 401, "")); + when(response.getEntity()).thenReturn(new StringEntity("")); + exceptionHandler.handleResponseCode(response); + } + + @Test(expected = AuthenticationFailedException.class) + public void testError403() throws IOException, StreamClientException { + CloseableHttpResponse response = mock(CloseableHttpResponse.class); + when(response.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 403, "")); + when(response.getEntity()).thenReturn(new StringEntity("")); + exceptionHandler.handleResponseCode(response); + } + + @Test(expected = ResourceNotFoundException.class) + public void testError404() throws IOException, StreamClientException { + CloseableHttpResponse response = mock(CloseableHttpResponse.class); + when(response.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 404, "")); + when(response.getEntity()).thenReturn(new StringEntity("")); + exceptionHandler.handleResponseCode(response); + } + + @Test(expected = InternalServerException.class) + public void testError500() throws IOException, StreamClientException { + CloseableHttpResponse response = mock(CloseableHttpResponse.class); + when(response.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 500, "")); + when(response.getEntity()).thenReturn(new StringEntity("")); + exceptionHandler.handleResponseCode(response); + } + + @Test(expected = StreamClientException.class) + public void testError503() throws IOException, StreamClientException { + CloseableHttpResponse response = mock(CloseableHttpResponse.class); + when(response.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 503, "")); + when(response.getEntity()).thenReturn(new StringEntity("")); + exceptionHandler.handleResponseCode(response); + } + + @Test + public void testOk() throws IOException, StreamClientException { + CloseableHttpResponse response = mock(CloseableHttpResponse.class); + when(response.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "")); + when(response.getEntity()).thenReturn(new StringEntity("")); + exceptionHandler.handleResponseCode(response); + } +} \ No newline at end of file diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java index dcd2b908..aaf065f4 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java @@ -5,6 +5,7 @@ import io.getstream.client.exception.AuthenticationFailedException; import io.getstream.client.exception.InternalServerException; import io.getstream.client.exception.InvalidOrMissingInputException; +import io.getstream.client.exception.RateLimitExceededException; import io.getstream.client.exception.ResourceNotFoundException; import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.beans.StreamErrorResponse; @@ -37,7 +38,15 @@ public StreamExceptionHandler(ObjectMapper objectMapper) { * @throws StreamClientException in case of functional or server-side exception */ public void handleResponseCode(final Response response) throws IOException, StreamClientException { - switch (response.code()) { + int statusCode = response.code(); + if (statusCode < 200 || statusCode > 299) { + parseException(response); + } + } + + private void parseException(Response response) throws IOException, StreamClientException { + int statusCode = response.code(); + switch (statusCode) { case 400: throw buildException(new InvalidOrMissingInputException(), response); case 401: @@ -46,18 +55,27 @@ public void handleResponseCode(final Response response) throws IOException, Stre throw buildException(new AuthenticationFailedException(), response); case 404: throw buildException(new ResourceNotFoundException(), response); + case 429: + throw buildException(new RateLimitExceededException(), response); case 500: throw buildException(new InternalServerException(), response); + default: + StreamClientException e = new InternalServerException(); + e.setCode(statusCode); + e.setHttpStatusCode(statusCode); + throw e; } } private StreamClientException buildException(StreamClientException exception, Response response) throws IOException { StreamErrorResponse error = objectMapper.readValue(response.body().byteStream(), StreamErrorResponse.class); - exception.setCode(error.getCode()); - exception.setHttpStatusCode(error.getStatusCode()); - exception.setDetail(error.getDetail()); - exception.setExceptionField(error.getException()); + if (null != error) { + exception.setCode(error.getCode()); + exception.setHttpStatusCode(error.getStatusCode()); + exception.setDetail(error.getDetail()); + exception.setExceptionField(error.getException()); + } return exception; } } diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandlerTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandlerTest.java new file mode 100644 index 00000000..d3b25a59 --- /dev/null +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandlerTest.java @@ -0,0 +1,119 @@ +package io.getstream.client.okhttp.repo.handlers; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.squareup.okhttp.MediaType; +import com.squareup.okhttp.Protocol; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; +import com.squareup.okhttp.internal.http.RealResponseBody; +import io.getstream.client.exception.AuthenticationFailedException; +import io.getstream.client.exception.InternalServerException; +import io.getstream.client.exception.InvalidOrMissingInputException; +import io.getstream.client.exception.RateLimitExceededException; +import io.getstream.client.exception.ResourceNotFoundException; +import io.getstream.client.exception.StreamClientException; +import org.junit.Test; + +import java.io.IOException; + +import static org.mockito.Mockito.mock; + +public class StreamExceptionHandlerTest { + + public static final String APPLICATION_JSON = "application/json"; + public static final String FAKE_URL = "http://www.example.com"; + + private final StreamExceptionHandler exceptionHandler; + + public StreamExceptionHandlerTest() { + exceptionHandler = new StreamExceptionHandler(mock(ObjectMapper.class)); + } + + @Test(expected = RateLimitExceededException.class) + public void testError429() throws IOException, StreamClientException { + exceptionHandler.handleResponseCode(new Response.Builder() + .code(429) + .message("") + .body(RealResponseBody.create(MediaType.parse(APPLICATION_JSON), "")) + .request(new Request.Builder().url(FAKE_URL).build()) + .protocol(Protocol.HTTP_1_1) + .build()); + } + + @Test(expected = InvalidOrMissingInputException.class) + public void testError400() throws IOException, StreamClientException { + exceptionHandler.handleResponseCode(new Response.Builder() + .code(400) + .message("") + .body(RealResponseBody.create(MediaType.parse(APPLICATION_JSON), "")) + .request(new Request.Builder().url(FAKE_URL).build()) + .protocol(Protocol.HTTP_1_1) + .build()); + } + + @Test(expected = AuthenticationFailedException.class) + public void testError401() throws IOException, StreamClientException { + exceptionHandler.handleResponseCode(new Response.Builder() + .code(401) + .message("") + .body(RealResponseBody.create(MediaType.parse(APPLICATION_JSON), "")) + .request(new Request.Builder().url(FAKE_URL).build()) + .protocol(Protocol.HTTP_1_1) + .build()); + } + + @Test(expected = AuthenticationFailedException.class) + public void testError403() throws IOException, StreamClientException { + exceptionHandler.handleResponseCode(new Response.Builder() + .code(403) + .message("") + .body(RealResponseBody.create(MediaType.parse(APPLICATION_JSON), "")) + .request(new Request.Builder().url(FAKE_URL).build()) + .protocol(Protocol.HTTP_1_1) + .build()); + } + + @Test(expected = ResourceNotFoundException.class) + public void testError404() throws IOException, StreamClientException { + exceptionHandler.handleResponseCode(new Response.Builder() + .code(404) + .message("") + .body(RealResponseBody.create(MediaType.parse(APPLICATION_JSON), "")) + .request(new Request.Builder().url(FAKE_URL).build()) + .protocol(Protocol.HTTP_1_1) + .build()); + } + + @Test(expected = InternalServerException.class) + public void testError500() throws IOException, StreamClientException { + exceptionHandler.handleResponseCode(new Response.Builder() + .code(500) + .message("") + .body(RealResponseBody.create(MediaType.parse(APPLICATION_JSON), "")) + .request(new Request.Builder().url(FAKE_URL).build()) + .protocol(Protocol.HTTP_1_1) + .build()); + } + + @Test(expected = StreamClientException.class) + public void testError503() throws IOException, StreamClientException { + exceptionHandler.handleResponseCode(new Response.Builder() + .code(503) + .message("") + .body(RealResponseBody.create(MediaType.parse(APPLICATION_JSON), "")) + .request(new Request.Builder().url(FAKE_URL).build()) + .protocol(Protocol.HTTP_1_1) + .build()); + } + + @Test + public void testOk() throws IOException, StreamClientException { + exceptionHandler.handleResponseCode(new Response.Builder() + .code(201) + .message("") + .body(RealResponseBody.create(MediaType.parse(APPLICATION_JSON), "")) + .request(new Request.Builder().url(FAKE_URL).build()) + .protocol(Protocol.HTTP_1_1) + .build()); + } +} \ No newline at end of file From 89adcca0d7070a38bb24ada78990035ac4af26d5 Mon Sep 17 00:00:00 2001 From: alessandro Date: Mon, 16 Oct 2017 18:15:27 +0200 Subject: [PATCH 084/320] [maven-release-plugin] prepare release stream-java-1.3.4 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 8aad8085..61ba77ea 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.3.4-SNAPSHOT + 1.3.4 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-1.3.4 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 0f554f5f..f4de1551 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.4-SNAPSHOT + 1.3.4 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 0026dde5..353bf28c 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.4-SNAPSHOT + 1.3.4 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 84df0681..57babf6d 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.4-SNAPSHOT + 1.3.4 4.0.0 From 01f6ca603ae13442324a8e0e3d4a0259135583cc Mon Sep 17 00:00:00 2001 From: alessandro Date: Mon, 16 Oct 2017 18:15:40 +0200 Subject: [PATCH 085/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 61ba77ea..ed1e527b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.3.4 + 1.3.5-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-1.3.4 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index f4de1551..57cc507a 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.4 + 1.3.5-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 353bf28c..d103b644 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.4 + 1.3.5-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 57babf6d..5c1c0695 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.4 + 1.3.5-SNAPSHOT 4.0.0 From 72aedb60e32e9599d3d15243730310a20a7fe734 Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 17 Oct 2017 11:05:03 +0200 Subject: [PATCH 086/320] [maven-release-plugin] prepare release stream-java-2.0.0 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index ed1e527b..38d5aa14 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 1.3.5-SNAPSHOT + 2.0.0 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-2.0.0 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 57cc507a..c3b080f6 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.5-SNAPSHOT + 2.0.0 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index d103b644..1049f444 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.5-SNAPSHOT + 2.0.0 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 5c1c0695..3db4ed1f 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 1.3.5-SNAPSHOT + 2.0.0 4.0.0 From 299e65aaa461b753b79f25728e72783a5644f44c Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 17 Oct 2017 11:05:10 +0200 Subject: [PATCH 087/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 38d5aa14..aace37c5 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 2.0.0 + 2.0.1-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-2.0.0 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index c3b080f6..274b33f0 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.0.0 + 2.0.1-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 1049f444..4892fd7c 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.0.0 + 2.0.1-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 3db4ed1f..6b96db4e 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.0.0 + 2.0.1-SNAPSHOT 4.0.0 From ad92e35e1f6e2295c14afda4ff5454e5ada699db Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 18 Oct 2017 12:04:02 +0200 Subject: [PATCH 088/320] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2be8491a..3943edc1 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 1.3.3 + 1.3.4 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:1.3.3' +compile 'io.getstream.client:stream-repo-apache:1.3.4' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -36,14 +36,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 1.3.3 + 1.3.4 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:1.3.3' +compile 'io.getstream.client:stream-repo-okhttp:1.3.4' ``` In case you want to download the artifact and put it manually into your project, From d095bf7b968698b8a6bdbd6adc90490310ba95be Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 18 Oct 2017 15:01:55 +0200 Subject: [PATCH 089/320] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3943edc1..f00c4901 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 1.3.4 + 2.0.0 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:1.3.4' +compile 'io.getstream.client:stream-repo-apache:2.0.0' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -36,14 +36,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 1.3.4 + 2.0.0 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:1.3.4' +compile 'io.getstream.client:stream-repo-okhttp:2.0.0' ``` In case you want to download the artifact and put it manually into your project, From f598b4abad3e29b1049f193c1479ae32fdf90114 Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 16 Jan 2018 14:01:05 +0100 Subject: [PATCH 090/320] Added session in FeedFilter --- .../io/getstream/client/model/filters/FeedFilter.java | 11 +++++++++++ .../client/model/{ => filters}/FeedFilterTest.java | 7 +++++-- .../client/apache/repo/utils/FeedFilterUtils.java | 3 +++ .../client/okhttp/repo/utils/FeedFilterUtils.java | 6 ++++++ 4 files changed, 25 insertions(+), 2 deletions(-) rename stream-core/src/test/java/io/getstream/client/model/{ => filters}/FeedFilterTest.java (94%) diff --git a/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java b/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java index 17ec5f56..8b4e8357 100644 --- a/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java +++ b/stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java @@ -15,6 +15,7 @@ public class FeedFilter { public final static String PARAM_ID_LOWER_THAN_EQUALS = "id_lte"; public final static String PARAM_FEED_IDS = "filter"; public final static String PARAM_RANKING = "ranking"; + public final static String PARAM_SESSION = "session"; private static final int DEFAULT_LIMIT = 25; @@ -25,6 +26,7 @@ public class FeedFilter { private String idLowerThanEquals = null; private String idLowerThan = null; private String ranking = null; + private String session = null; private List feedIds = null; protected FeedFilter() { @@ -62,6 +64,10 @@ public String getRanking() { return ranking; } + public String getSession() { + return session; + } + /** * Builder to build up a {@link FeedFilter}. */ @@ -116,6 +122,11 @@ public Builder withRanking(String ranking) { return this; } + public Builder withSession(String session) { + feedFilter.session = session; + return this; + } + public Builder withFeedIds(List feeds) { feedFilter.feedIds = feeds; return this; diff --git a/stream-core/src/test/java/io/getstream/client/model/FeedFilterTest.java b/stream-core/src/test/java/io/getstream/client/model/filters/FeedFilterTest.java similarity index 94% rename from stream-core/src/test/java/io/getstream/client/model/FeedFilterTest.java rename to stream-core/src/test/java/io/getstream/client/model/filters/FeedFilterTest.java index d7ff472b..f94518d6 100644 --- a/stream-core/src/test/java/io/getstream/client/model/FeedFilterTest.java +++ b/stream-core/src/test/java/io/getstream/client/model/filters/FeedFilterTest.java @@ -1,10 +1,10 @@ package io.getstream.client.model.filters; +import org.junit.Test; + import java.util.Arrays; import java.util.List; -import org.junit.Test; - import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; @@ -20,6 +20,7 @@ public void shouldBuildFeedFilter() { String id_lt = "ghi"; String id_lte = "jkl"; String ranking = "ranking-method"; + String session = "session"; List feedIds = Arrays.asList("user:123", "user:456"); FeedFilter filter = new FeedFilter.Builder() @@ -31,6 +32,7 @@ public void shouldBuildFeedFilter() { .withIdLowerThanEquals(id_lte) .withRanking(ranking) .withFeedIds(feedIds) + .withSession(session) .build(); assertThat(filter.getLimit(), is(limit)); @@ -41,6 +43,7 @@ public void shouldBuildFeedFilter() { assertThat(filter.getIdLowerThanEquals(), is(id_lte)); assertThat(filter.getRanking(), is(ranking)); assertThat(filter.getFeedIds(), is(feedIds)); + assertThat(filter.getSession(), is(session)); } @Test diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java index 08f7fb21..cd638d84 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java @@ -44,6 +44,9 @@ public static UriBuilder apply(final UriBuilder uriBuilder, final FeedFilter fil if (null != filter.getRanking()) { uriBuilder.queryParam(FeedFilter.PARAM_RANKING, filter.getRanking()); } + if (null != filter.getSession()) { + uriBuilder.queryParam(FeedFilter.PARAM_SESSION, filter.getSession()); + } return uriBuilder; } } diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/FeedFilterUtils.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/FeedFilterUtils.java index f8a4e731..bbd7db95 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/FeedFilterUtils.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/FeedFilterUtils.java @@ -41,6 +41,12 @@ public static UriBuilder apply(final UriBuilder uriBuilder, final FeedFilter fil if (null != filter.getFeedIds()) { uriBuilder.queryParam(FeedFilter.PARAM_FEED_IDS, Joiner.on(",").join(filter.getFeedIds())); } + if (null != filter.getRanking()) { + uriBuilder.queryParam(FeedFilter.PARAM_RANKING, filter.getRanking()); + } + if (null != filter.getSession()) { + uriBuilder.queryParam(FeedFilter.PARAM_SESSION, filter.getSession()); + } return uriBuilder; } } From 340f11b03be841dbdabba271d425141a774e23d3 Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 16 Jan 2018 14:08:48 +0100 Subject: [PATCH 091/320] [maven-release-plugin] prepare release stream-java-2.0.1 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index aace37c5..f29bfb9e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 2.0.1-SNAPSHOT + 2.0.1 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-2.0.1 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 274b33f0..eacfd954 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.0.1-SNAPSHOT + 2.0.1 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 4892fd7c..9d93ba11 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.0.1-SNAPSHOT + 2.0.1 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 6b96db4e..7a7dcaeb 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.0.1-SNAPSHOT + 2.0.1 4.0.0 From 8a261e9ca46f96f1da083f065da35892225f9cf4 Mon Sep 17 00:00:00 2001 From: alessandro Date: Tue, 16 Jan 2018 14:08:55 +0100 Subject: [PATCH 092/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index f29bfb9e..27415d57 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 2.0.1 + 2.0.2-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-2.0.1 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index eacfd954..163e2a95 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.0.1 + 2.0.2-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 9d93ba11..f1a9b35a 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.0.1 + 2.0.2-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 7a7dcaeb..51ace33c 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.0.1 + 2.0.2-SNAPSHOT 4.0.0 From 0d33a56f1d47cb758d0c7469974f7330b97a72f1 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 16 Jan 2018 14:15:21 +0100 Subject: [PATCH 093/320] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f00c4901..c54b68ee 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 2.0.0 + 2.0.1 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:2.0.0' +compile 'io.getstream.client:stream-repo-apache:2.0.1' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -36,14 +36,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 2.0.0 + 2.0.1 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:2.0.0' +compile 'io.getstream.client:stream-repo-okhttp:2.0.1' ``` In case you want to download the artifact and put it manually into your project, From 636f4c999e883cbdd30e065ff0515db0b13e84ae Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 11 Mar 2018 13:06:36 +0100 Subject: [PATCH 094/320] Upgrade HTTPClient to Version 4.5.5 --- stream-repo-apache/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index f1a9b35a..42e13e3f 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -21,7 +21,7 @@ - 4.3.6 + 4.5.5 From 9223707d606a3550c6a8b14a223ec43eb0532140 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 11 Mar 2018 16:48:47 +0100 Subject: [PATCH 095/320] [39] Fix Integrationtests --- .../io/getstream/client/apache/IntegrationTest.java | 11 ++--------- .../io/getstream/client/okhttp/IntegrationTest.java | 11 ++--------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index 5c07ecc4..570b0fc6 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -133,12 +133,12 @@ public void shouldFollowWithActivityCopyLimit() throws IOException, StreamClient List following = feed.getFollowing(); assertThat(following.size(), is(0)); - feed.follow("user", "1", 10); + feed.follow("user", "1", 2); List followingAfter = feed.getFollowing(); assertThat(followingAfter.size(), is(1)); - assertThat(flatActivityService.getActivities().getResults().size(), is(10)); + assertThat(flatActivityService.getActivities().getResults().size(), is(2)); streamClient.shutdown(); } @@ -555,13 +555,6 @@ public void shouldGetActivitiesWithIdFilter() throws IOException, StreamClientEx //gte List firstTwoActivities = flatActivityService.getActivities(new FeedFilter.Builder().withIdLowerThan(aid).build()).getResults(); assertThat(firstTwoActivities.size(), is(2)); - //closed interval - List activity3 = flatActivityService.getActivities(new FeedFilter.Builder().withIdLowerThanEquals(aid).withIdGreaterThanEquals(aid).build()).getResults(); - assertThat(activity3.size(), is(1)); - //closed interval empty - List activityNo = flatActivityService.getActivities(new FeedFilter.Builder().withIdLowerThan(aid).withIdGreaterThan(aid).build()).getResults(); - assertThat(activityNo.size(), is(0)); - streamClient.shutdown(); } @Test(expected = InvalidOrMissingInputException.class) diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index 222d3f4b..3e27365b 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -127,12 +127,12 @@ public void shouldFollowWithActivityCopyLimit() throws IOException, StreamClient List following = feed.getFollowing(); assertThat(following.size(), is(0)); - feed.follow("user", "1", 10); + feed.follow("user", "1", 2); List followingAfter = feed.getFollowing(); assertThat(followingAfter.size(), is(1)); - assertThat(flatActivityService.getActivities().getResults().size(), is(10)); + assertThat(flatActivityService.getActivities().getResults().size(), is(2)); streamClient.shutdown(); } @@ -601,13 +601,6 @@ public void shouldGetActivitiesWithIdFilter() throws IOException, StreamClientEx //gte List firstTwoActivities = flatActivityService.getActivities(new FeedFilter.Builder().withIdLowerThan(aid).build()).getResults(); assertThat(firstTwoActivities.size(), is(2)); - //closed interval - List activity3 = flatActivityService.getActivities(new FeedFilter.Builder().withIdLowerThanEquals(aid).withIdGreaterThanEquals(aid).build()).getResults(); - assertThat(activity3.size(), is(1)); - //closed interval empty - List activityNo = flatActivityService.getActivities(new FeedFilter.Builder().withIdLowerThan(aid).withIdGreaterThan(aid).build()).getResults(); - assertThat(activityNo.size(), is(0)); - streamClient.shutdown(); } @Test(expected = InvalidOrMissingInputException.class) From 60869895e3599ad760885d5bdfc8304dcd30f196 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 11 Mar 2018 21:25:06 +0100 Subject: [PATCH 096/320] Cache .m2 directory in travis build --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 80f39e31..fcfa8590 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ language: java jdk: - oraclejdk8 +cache: + directories: + - $HOME/.m2 env: global: - secure: TmI+K6gSOfDy5oa5EgLCGijimKdR5cHAwM6RASDegTjlRQ/sWVf8BNF4IPJHnAYFWNCgyX6vLdfPS3IJNrYS9iI1Er2a1Ctcq1TbCZfZpn4eIj8mcUXxr2Fo6hLJh2KeuXj3OQwfUy/Jul1Own/9R5YoVDJYD0ntnt1HJgFqq+0= From 1bb0195f7ae097581705c74917497b5d0b943b9b Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 11 Mar 2018 13:42:47 +0100 Subject: [PATCH 097/320] Upgrade to okhttp 3 - Cleanup some unnecessarily thrown exceptions in test code --- .../client/util/JwtAuthenticationUtil.java | 8 +-- .../client/util/EndpointUtilTest.java | 21 ++++---- stream-repo-okhttp/pom.xml | 4 +- .../client/okhttp/StreamClientImpl.java | 38 ++++++------- .../okhttp/repo/HttpSignatureinterceptor.java | 19 +++---- .../okhttp/repo/StreamActivityRepository.java | 53 ++++++++++--------- .../StreamPersonalizedRepositoryImpl.java | 41 +++++++------- .../okhttp/repo/StreamRepositoryImpl.java | 29 +++++----- .../repo/handlers/StreamExceptionHandler.java | 6 +-- .../okhttp/repo/utils/StreamRepoUtils.java | 8 +-- .../StreamPersonalizedRepositoryImplTest.java | 38 ++++++++----- .../handlers/StreamExceptionHandlerTest.java | 21 ++++---- .../okhttp/repo/utils/InfoUtilTest.java | 8 +-- .../repo/utils/StreamRepoUtilsTest.java | 23 ++++---- 14 files changed, 169 insertions(+), 148 deletions(-) diff --git a/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java b/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java index 6524d429..4ae505d1 100644 --- a/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java +++ b/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java @@ -1,11 +1,11 @@ package io.getstream.client.util; -import com.auth0.jwt.Algorithm; -import com.auth0.jwt.JWTSigner; - import java.util.LinkedHashMap; import java.util.Map; +import com.auth0.jwt.Algorithm; +import com.auth0.jwt.JWTSigner; + /** * Utility class to generate a JWT token. */ @@ -26,7 +26,7 @@ public class JwtAuthenticationUtil { * @return Token string */ public static String generateToken(final String secretKey, final String action, final String resource, final String feedId, final String userId) { - Map claims = new LinkedHashMap(); + Map claims = new LinkedHashMap<>(); claims.put("action", action); claims.put("resource", resource); if (null != feedId) { diff --git a/stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java b/stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java index 3952c181..4f7d5335 100644 --- a/stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java +++ b/stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java @@ -1,18 +1,19 @@ package io.getstream.client.util; -import io.getstream.client.config.ClientConfiguration; -import io.getstream.client.config.StreamRegion; -import org.junit.Test; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; import java.net.URI; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import org.junit.Test; + +import io.getstream.client.config.ClientConfiguration; +import io.getstream.client.config.StreamRegion; public class EndpointUtilTest { @Test - public void shouldGetPersonalizedEndpoint() throws Exception { + public void shouldGetPersonalizedEndpoint() { ClientConfiguration clientConfiguration = new ClientConfiguration(); clientConfiguration.setPersonalizedFeedEndpoint("http://yourcompany.getstream.io/yourcompany"); @@ -21,7 +22,7 @@ public void shouldGetPersonalizedEndpoint() throws Exception { } @Test - public void shouldGetPersonalizedEndpointWithoutDoubleSlash() throws Exception { + public void shouldGetPersonalizedEndpointWithoutDoubleSlash() { ClientConfiguration clientConfiguration = new ClientConfiguration(); clientConfiguration.setPersonalizedFeedEndpoint("http://yourcompany.getstream.io/yourcompany/"); @@ -30,7 +31,7 @@ public void shouldGetPersonalizedEndpointWithoutDoubleSlash() throws Exception { } @Test - public void shouldGetCustomEndpoint() throws Exception { + public void shouldGetCustomEndpoint() { ClientConfiguration clientConfiguration = new ClientConfiguration(); clientConfiguration.setDefaultEndpoint("http://www.example.com/v1"); @@ -39,7 +40,7 @@ public void shouldGetCustomEndpoint() throws Exception { } @Test - public void shouldGetRegionDefaultEndpoint() throws Exception { + public void shouldGetRegionDefaultEndpoint() { ClientConfiguration clientConfiguration = new ClientConfiguration(StreamRegion.US_EAST); URI personalizedEndpoint = EndpointUtil.getBaseEndpoint(clientConfiguration); @@ -47,7 +48,7 @@ public void shouldGetRegionDefaultEndpoint() throws Exception { } @Test(expected = NullPointerException.class) - public void shouldFail() throws Exception { + public void shouldFail() { ClientConfiguration clientConfiguration = new ClientConfiguration(); clientConfiguration.setPersonalizedFeedEndpoint(null); diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 51ace33c..9ff4b0f4 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -21,7 +21,7 @@ - 2.2.0 + 3.10.0 @@ -47,7 +47,7 @@ guava - com.squareup.okhttp + com.squareup.okhttp3 okhttp ${okhttp.version} diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java index 4f48e508..a6edbe30 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java @@ -1,15 +1,17 @@ package io.getstream.client.okhttp; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.IOException; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.SerializationFeature; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.squareup.okhttp.ConnectionPool; -import com.squareup.okhttp.Interceptor; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Response; import io.getstream.client.StreamClient; import io.getstream.client.config.AuthenticationHandlerConfiguration; import io.getstream.client.config.ClientConfiguration; @@ -24,12 +26,10 @@ import io.getstream.client.repo.StreamPersonalizedRepository; import io.getstream.client.repo.StreamRepository; import io.getstream.client.util.InfoUtil; - -import java.io.IOException; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -import static com.google.common.base.Preconditions.checkNotNull; +import okhttp3.ConnectionPool; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Response; public class StreamClientImpl implements StreamClient { @@ -83,15 +83,15 @@ protected void setFeedFactory(FeedFactory feedFactory) { } private OkHttpClient initClient(final ClientConfiguration config, AuthenticationHandlerConfiguration authConfig) { - OkHttpClient client = new OkHttpClient(); - client.setConnectTimeout(config.getConnectionTimeout(), TimeUnit.MILLISECONDS); - client.setReadTimeout(config.getTimeout(), TimeUnit.MILLISECONDS); - client.setWriteTimeout(config.getTimeout(), TimeUnit.MILLISECONDS); - client.setRetryOnConnectionFailure(true); - client.interceptors().add(new UserAgentInterceptor()); - client.interceptors().add(new HttpSignatureinterceptor(authConfig)); - client.setConnectionPool(new ConnectionPool(config.getMaxConnections(), config.getKeepAlive())); - return client; + return new OkHttpClient().newBuilder() + .connectTimeout(config.getConnectionTimeout(), TimeUnit.MILLISECONDS) + .readTimeout(config.getTimeout(), TimeUnit.MILLISECONDS) + .writeTimeout(config.getTimeout(), TimeUnit.MILLISECONDS) + .retryOnConnectionFailure(true) + .addInterceptor(new UserAgentInterceptor()) + .addInterceptor(new HttpSignatureinterceptor(authConfig)) + .connectionPool(new ConnectionPool(config.getMaxConnections(), config.getKeepAlive(), TimeUnit.MILLISECONDS)) + .build(); } private Optional initPersonalizedRepo(ClientConfiguration config, OkHttpClient httpClient) { diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/HttpSignatureinterceptor.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/HttpSignatureinterceptor.java index 6c3bae69..35c8d246 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/HttpSignatureinterceptor.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/HttpSignatureinterceptor.java @@ -1,17 +1,18 @@ package io.getstream.client.okhttp.repo; +import java.io.IOException; +import java.util.Collections; + +import org.tomitribe.auth.signatures.Signature; + import com.google.common.base.Optional; -import com.squareup.okhttp.Interceptor; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.Response; import io.getstream.client.config.AuthenticationHandlerConfiguration; import io.getstream.client.util.HttpSignatureHandler; -import org.tomitribe.auth.signatures.Signature; - -import java.io.IOException; -import java.util.Collections; +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; -public class HttpSignatureinterceptor extends HttpSignatureHandler implements Interceptor{ +public class HttpSignatureinterceptor extends HttpSignatureHandler implements Interceptor { /** * Create a {@link Signature} template object using the incoming credentials. @@ -32,7 +33,7 @@ public Response intercept(Chain chain) throws IOException { newRequest.addHeader(DATE_HEADER, today); Signature signature = getSigner().sign( request.method(), - request.urlString(), + request.url().toString(), Collections.singletonMap(DATE_HEADER, today) ); newRequest.addHeader(AUTHORIZATION_HEADER, signature.toString()); diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java index 488cf310..a0c040b6 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java @@ -1,11 +1,17 @@ package io.getstream.client.okhttp.repo; +import static io.getstream.client.util.JwtAuthenticationUtil.ALL; +import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; + +import java.io.IOException; +import java.net.URI; +import java.util.Collections; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.fasterxml.jackson.databind.ObjectMapper; -import com.squareup.okhttp.MediaType; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.RequestBody; -import com.squareup.okhttp.Response; import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; @@ -22,16 +28,11 @@ import io.getstream.client.okhttp.repo.utils.StreamRepoUtils; import io.getstream.client.okhttp.repo.utils.UriBuilder; import io.getstream.client.util.HttpSignatureHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URI; -import java.util.Collections; -import java.util.List; - -import static io.getstream.client.util.JwtAuthenticationUtil.ALL; -import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; public class StreamActivityRepository { @@ -65,7 +66,7 @@ public T addActivity(BaseFeed feed, T activity) throws requestBuilder.post(RequestBody.create(MediaType.parse(APPLICATION_JSON), objectMapper.writeValueAsString(activity))); Request request = addAuthentication(feed, requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -86,7 +87,7 @@ public StreamActivitiesResponse addActivities(BaseFe objectMapper.writeValueAsString(Collections.singletonMap("activities", activities)))); Request request = addAuthentication(feed, requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -105,7 +106,7 @@ public T addToMany(List targetIds, T activity) objectMapper.writeValueAsString(new AddMany<>(targetIds, activity)))); final Request request = requestBuilder.build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -119,7 +120,7 @@ public StreamResponse getActivities(BaseFeed feed, C .queryParam(StreamRepositoryImpl.API_KEY, apiKey), filter).build().toURL()).get(); Request request = addAuthentication(feed, requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -133,7 +134,7 @@ public StreamResponse> getAggrega .queryParam(StreamRepositoryImpl.API_KEY, apiKey), filter).build().toURL()).get(); Request request = addAuthentication(feed, requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -147,7 +148,7 @@ public StreamResponse> getNotif .queryParam(StreamRepositoryImpl.API_KEY, apiKey), filter).build().toURL()).get(); Request request = addAuthentication(feed, requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -164,7 +165,7 @@ public StreamResponse> getNotif .queryParam("mark_seen", Boolean.toString(markAsSeen)), filter).build().toURL()).get(); Request request = addAuthentication(feed, requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -186,7 +187,7 @@ public StreamResponse> getNotif Request.Builder requestBuilder = new Request.Builder().url(FeedFilterUtils.apply(baseUri, filter).build().toURL()).get(); Request request = addAuthentication(feed, requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -200,7 +201,7 @@ public void deleteActivityById(BaseFeed feed, String activityId) throws IOExcept .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build().toURL()); Request request = addAuthentication(feed, requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -213,7 +214,7 @@ public void deleteActivityByForeignId(BaseFeed feed, String activityId) throws I .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build().toURL()); Request request = addAuthentication(feed, requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -231,7 +232,7 @@ public StreamActivitiesResponse updateActivities(Bas generateToken(secretKey, ALL, "activities", ALL, null), requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java index bac8ad61..1820783c 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java @@ -1,11 +1,19 @@ package io.getstream.client.okhttp.repo; +import static io.getstream.client.okhttp.repo.utils.FeedFilterUtils.apply; +import static io.getstream.client.util.JwtAuthenticationUtil.ALL; +import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; + +import java.io.IOException; +import java.io.Serializable; +import java.net.URI; +import java.util.Collections; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.fasterxml.jackson.databind.ObjectMapper; -import com.squareup.okhttp.MediaType; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.RequestBody; -import com.squareup.okhttp.Response; import io.getstream.client.config.ClientConfiguration; import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.PersonalizedActivity; @@ -18,18 +26,11 @@ import io.getstream.client.okhttp.repo.utils.UriBuilder; import io.getstream.client.repo.StreamPersonalizedRepository; import io.getstream.client.util.EndpointUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.Serializable; -import java.net.URI; -import java.util.Collections; -import java.util.List; - -import static io.getstream.client.okhttp.repo.utils.FeedFilterUtils.apply; -import static io.getstream.client.util.JwtAuthenticationUtil.ALL; -import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; public class StreamPersonalizedRepositoryImpl implements StreamPersonalizedRepository { @@ -68,7 +69,7 @@ public List get(PersonalizedFeed feed, Class Request request = StreamRepoUtils.addJwtAuthentication( generateToken(secretKey, ALL, ALL, null, feed.getUserId()), requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -92,7 +93,7 @@ public MetaResponse addMeta(PersonalizedFeed feed, Serializable metaPayload) thr Request request = StreamRepoUtils.addJwtAuthentication( generateToken(secretKey, ALL, ALL, null, feed.getUserId()), requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -115,7 +116,7 @@ public List getInterest(PersonalizedFeed feed, Class Request request = StreamRepoUtils.addJwtAuthentication( generateToken(secretKey, ALL, ALL, null, feed.getUserId()), requestBuilder).build(); - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index f3e003e8..23dfb346 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -1,12 +1,14 @@ package io.getstream.client.okhttp.repo; +import java.io.IOException; +import java.net.URI; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import com.squareup.okhttp.MediaType; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.RequestBody; -import com.squareup.okhttp.Response; import io.getstream.client.config.ClientConfiguration; import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.AggregatedActivity; @@ -29,12 +31,11 @@ import io.getstream.client.util.EndpointUtil; import io.getstream.client.util.HttpSignatureHandler; import io.getstream.client.util.JwtAuthenticationUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URI; -import java.util.List; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; /** * Actual implementation of the Stream's REST API calls. @@ -126,7 +127,7 @@ public List getFollowing(BaseFeed feed, FeedFilter filter) throws St .queryParam(API_KEY, apiKey), filter).build().toURL()).get(); Request request = addAuthentication(feed, requestBuilder).build(); - LOG.debug("Invoking url: '{}'", request.urlString()); + LOG.debug("Invoking url: '{}'", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -142,7 +143,7 @@ public List getFollowers(BaseFeed feed, FeedFilter filter) throws St .queryParam(API_KEY, apiKey), filter).build().toURL()).get(); Request request = addAuthentication(feed, requestBuilder).build(); - LOG.debug("Invoking url: '{}'", request.urlString()); + LOG.debug("Invoking url: '{}'", request.url().toString()); Response response = httpClient.newCall(request).execute(); handleResponseCode(response); @@ -212,7 +213,7 @@ public void shutdown() throws IOException { } private void fireAndForget(final Request request) throws IOException, StreamClientException { - LOG.debug("Invoking url: '{}", request.urlString()); + LOG.debug("Invoking url: '{}", request.url().toString()); handleResponseCode(httpClient.newCall(request).execute()); } diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java index aaf065f4..7f7ed298 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java @@ -1,7 +1,8 @@ package io.getstream.client.okhttp.repo.handlers; +import java.io.IOException; + import com.fasterxml.jackson.databind.ObjectMapper; -import com.squareup.okhttp.Response; import io.getstream.client.exception.AuthenticationFailedException; import io.getstream.client.exception.InternalServerException; import io.getstream.client.exception.InvalidOrMissingInputException; @@ -9,8 +10,7 @@ import io.getstream.client.exception.ResourceNotFoundException; import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.beans.StreamErrorResponse; - -import java.io.IOException; +import okhttp3.Response; /** * It provides a mechanism to translate the http status code (different from 200) diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java index 1b89650e..523e5503 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java @@ -1,13 +1,13 @@ package io.getstream.client.okhttp.repo.utils; -import com.squareup.okhttp.Request; -import io.getstream.client.model.feeds.BaseFeed; - import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SignatureException; +import io.getstream.client.model.feeds.BaseFeed; +import okhttp3.Request; + /** * Support utils for StreamRepository. */ @@ -29,7 +29,7 @@ private StreamRepoUtils() { * @return Request with the Authorization header. */ public static Request.Builder addAuthentication(BaseFeed feed, String secretKey, Request.Builder httpRequest) { - httpRequest.addHeader("Authorization", createFeedSignature(feed, secretKey)); + httpRequest.addHeader(HEADER_AUTHORIZATION, createFeedSignature(feed, secretKey)); return httpRequest; } diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java index 90561f18..10360840 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java @@ -1,9 +1,31 @@ package io.getstream.client.okhttp.repo; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.containing; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.mock; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import org.hamcrest.Matcher; +import org.junit.Rule; +import org.junit.Test; + import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.tomakehurst.wiremock.junit.WireMockRule; -import com.squareup.okhttp.OkHttpClient; import io.getstream.client.config.ClientConfiguration; import io.getstream.client.config.StreamRegion; import io.getstream.client.exception.StreamClientException; @@ -11,19 +33,7 @@ import io.getstream.client.model.feeds.PersonalizedFeed; import io.getstream.client.okhttp.StreamClientImpl; import io.getstream.client.util.JwtAuthenticationUtil; -import org.hamcrest.Matcher; -import org.junit.Rule; -import org.junit.Test; - -import java.io.IOException; -import java.io.Serializable; -import java.util.Collections; -import java.util.List; - -import static com.github.tomakehurst.wiremock.client.WireMock.*; -import static org.hamcrest.CoreMatchers.hasItems; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.Mockito.mock; +import okhttp3.OkHttpClient; public class StreamPersonalizedRepositoryImplTest { diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandlerTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandlerTest.java index d3b25a59..dbdf1a0c 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandlerTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandlerTest.java @@ -1,22 +1,23 @@ package io.getstream.client.okhttp.repo.handlers; +import static org.mockito.Mockito.mock; + +import java.io.IOException; + +import org.junit.Test; + import com.fasterxml.jackson.databind.ObjectMapper; -import com.squareup.okhttp.MediaType; -import com.squareup.okhttp.Protocol; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.Response; -import com.squareup.okhttp.internal.http.RealResponseBody; import io.getstream.client.exception.AuthenticationFailedException; import io.getstream.client.exception.InternalServerException; import io.getstream.client.exception.InvalidOrMissingInputException; import io.getstream.client.exception.RateLimitExceededException; import io.getstream.client.exception.ResourceNotFoundException; import io.getstream.client.exception.StreamClientException; -import org.junit.Test; - -import java.io.IOException; - -import static org.mockito.Mockito.mock; +import okhttp3.MediaType; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.internal.http.RealResponseBody; public class StreamExceptionHandlerTest { diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/InfoUtilTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/InfoUtilTest.java index fd9acf53..a93790f2 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/InfoUtilTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/InfoUtilTest.java @@ -1,11 +1,13 @@ -package io.getstream.client.util; - -import org.junit.Test; +package io.getstream.client.okhttp.repo.utils; import static org.hamcrest.CoreMatchers.any; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import org.junit.Test; + +import io.getstream.client.util.InfoUtil; + public class InfoUtilTest { @Test diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtilsTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtilsTest.java index 20414efd..0921978e 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtilsTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtilsTest.java @@ -1,14 +1,17 @@ package io.getstream.client.okhttp.repo.utils; -import com.squareup.okhttp.Request; -import io.getstream.client.model.feeds.BaseFeed; -import org.junit.Before; -import org.junit.Test; - import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; + +import io.getstream.client.model.feeds.BaseFeed; +import okhttp3.Request; public class StreamRepoUtilsTest { @@ -23,7 +26,7 @@ public void init() { } @Test - public void shouldAddAuthentication() throws Exception { + public void shouldAddAuthentication() { Request.Builder request = mock(Request.Builder.class); String signature = StreamRepoUtils.createFeedSignature(feed, API_SECRET); @@ -32,17 +35,17 @@ public void shouldAddAuthentication() throws Exception { } @Test - public void shouldCreateFeedToken() throws Exception { + public void shouldCreateFeedToken() { assertThat(StreamRepoUtils.createFeedToken(feed, API_SECRET), is("0DayILmfWZ4i8h6WHFUV0diDXOg")); } @Test - public void shouldCreateFeedSignature() throws Exception { + public void shouldCreateFeedSignature(){ assertThat(StreamRepoUtils.createFeedSignature(feed, API_SECRET), is("id 0DayILmfWZ4i8h6WHFUV0diDXOg")); } @Test - public void shouldAddJwtAuthentication() throws Exception { + public void shouldAddJwtAuthentication() { Request.Builder request = mock(Request.Builder.class); StreamRepoUtils.addJwtAuthentication("token", request); From 7083cbcd3fbf799e02116293f1fba0a4ae1d85ea Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 11 Mar 2018 20:13:41 +0100 Subject: [PATCH 098/320] Upgrade to Java-JWT 3.3.0 --- pom.xml | 2 +- .../client/util/JwtAuthenticationUtil.java | 28 ++++++++----- .../util/JwtAuthenticationUtilTest.java | 39 ++++++++++++------- .../client/apache/IntegrationTest.java | 25 ++++++++---- .../client/okhttp/IntegrationTest.java | 27 ++++++++----- 5 files changed, 78 insertions(+), 43 deletions(-) diff --git a/pom.xml b/pom.xml index 27415d57..b5f8f41b 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 1.0 4.11 1.10.19 - 2.1.0 + 3.3.0 1.57 true diff --git a/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java b/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java index 6524d429..b6911d3c 100644 --- a/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java +++ b/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java @@ -1,10 +1,10 @@ package io.getstream.client.util; -import com.auth0.jwt.Algorithm; -import com.auth0.jwt.JWTSigner; +import java.io.UnsupportedEncodingException; -import java.util.LinkedHashMap; -import java.util.Map; +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTCreator; +import com.auth0.jwt.algorithms.Algorithm; /** * Utility class to generate a JWT token. @@ -26,15 +26,23 @@ public class JwtAuthenticationUtil { * @return Token string */ public static String generateToken(final String secretKey, final String action, final String resource, final String feedId, final String userId) { - Map claims = new LinkedHashMap(); - claims.put("action", action); - claims.put("resource", resource); + JWTCreator.Builder jwtBuilder = JWT.create(); + + jwtBuilder = jwtBuilder.withClaim("action", action); + jwtBuilder = jwtBuilder.withClaim("resource", resource); if (null != feedId) { - claims.put("feed_id", feedId); + jwtBuilder = jwtBuilder.withClaim("feed_id", feedId); } if (null != userId) { - claims.put("user_id", userId); + jwtBuilder = jwtBuilder.withClaim("user_id", userId); + } + + try { + Algorithm algorithm = Algorithm.HMAC256(secretKey); + + return jwtBuilder.sign(algorithm); + } catch (UnsupportedEncodingException exc) { + throw new IllegalStateException("Fatal error: JWT Algorithm unsupported."); } - return new JWTSigner(secretKey).sign(claims, new JWTSigner.Options().setAlgorithm(Algorithm.HS256)); } } diff --git a/stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java b/stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java index cec6921a..0c4b0341 100644 --- a/stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java +++ b/stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java @@ -1,7 +1,11 @@ package io.getstream.client.util; +import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; -import com.auth0.jwt.JWTVerifyException; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.interfaces.Claim; +import com.auth0.jwt.interfaces.DecodedJWT; + import org.junit.Test; import java.io.IOException; @@ -21,7 +25,7 @@ public class JwtAuthenticationUtilTest { @Test public void testGenerateToken() throws Exception { - Map map = verifyToken( + Map map = verifyToken( JwtAuthenticationUtil.generateToken( SECRET_KEY, "activities", @@ -30,12 +34,12 @@ public void testGenerateToken() throws Exception { null) ); assertTrue(map.size() > 0); - assertThat(map.get("action").toString(), is("activities")); + assertThat(map.get("action").asString(), is("activities")); } @Test public void testGenerateTokenWithFeedId() throws Exception { - Map map = verifyToken( + Map map = verifyToken( JwtAuthenticationUtil.generateToken( SECRET_KEY, "activities", @@ -44,13 +48,13 @@ public void testGenerateTokenWithFeedId() throws Exception { null) ); assertTrue(map.size() > 0); - assertThat(map.get("resource").toString(), is(ALL)); - assertThat(map.get("feed_id").toString(), is("feedId")); + assertThat(map.get("resource").asString(), is(ALL)); + assertThat(map.get("feed_id").asString(), is("feedId")); } @Test public void testGenerateTokenWithUserId() throws Exception { - Map map = verifyToken( + Map map = verifyToken( JwtAuthenticationUtil.generateToken( SECRET_KEY, "activities", @@ -59,13 +63,13 @@ public void testGenerateTokenWithUserId() throws Exception { "userId1") ); assertTrue(map.size() > 0); - assertThat(map.get("resource").toString(), is(ALL)); - assertThat(map.get("user_id").toString(), is("userId1")); + assertThat(map.get("resource").asString(), is(ALL)); + assertThat(map.get("user_id").asString(), is("userId1")); } @Test public void testGenerateTokenWithFeedAndUserId() throws Exception { - Map map = verifyToken( + Map map = verifyToken( JwtAuthenticationUtil.generateToken( SECRET_KEY, "activities", @@ -74,13 +78,18 @@ public void testGenerateTokenWithFeedAndUserId() throws Exception { "userId1") ); assertTrue(map.size() > 0); - assertThat(map.get("resource").toString(), is(ALL)); - assertThat(map.get("feed_id").toString(), is("feedId")); - assertThat(map.get("user_id").toString(), is("userId1")); + assertThat(map.get("resource").asString(), is(ALL)); + assertThat(map.get("feed_id").asString(), is("feedId")); + assertThat(map.get("user_id").asString(), is("userId1")); } - private Map verifyToken(final String token) throws SignatureException, NoSuchAlgorithmException, JWTVerifyException, InvalidKeyException, IOException { + private Map verifyToken(final String token) { byte[] secret = SECRET_KEY.getBytes(); - return new JWTVerifier(secret, "audience").verify(token); + Algorithm algorithm = Algorithm.HMAC256(secret); + + JWTVerifier verifier = JWT.require(algorithm).build(); + DecodedJWT jwt = verifier.verify(token); + + return jwt.getClaims(); } } \ No newline at end of file diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index 570b0fc6..5e2ace04 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -1,7 +1,10 @@ package io.getstream.client.apache; +import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; -import com.auth0.jwt.JWTVerifyException; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.interfaces.Claim; +import com.auth0.jwt.interfaces.DecodedJWT; import com.google.common.collect.ImmutableList; import io.getstream.client.StreamClient; import io.getstream.client.config.ClientConfiguration; @@ -63,15 +66,15 @@ public String getTestUserId(String userId) { } @Test - public void shouldGetReadOnlyToken() throws IOException, StreamClientException, NoSuchAlgorithmException, SignatureException, JWTVerifyException, InvalidKeyException { + public void shouldGetReadOnlyToken() throws IOException, StreamClientException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); Feed feed = streamClient.newFeed("user", "1"); - Map map = verifyToken(feed.getReadOnlyToken()); + Map map = verifyToken(feed.getReadOnlyToken()); assertTrue(map.size() > 0); - assertThat(map.get("action").toString(), is("read")); - assertThat(map.get("resource").toString(), is(ALL)); + assertThat(map.get("action").asString(), is("read")); + assertThat(map.get("resource").asString(), is(ALL)); } @Test @@ -205,7 +208,7 @@ public void shouldHaveOriginField() throws IOException, StreamClientException, I } @Test - public void shouldUnfollow() throws IOException, StreamClientException, InterruptedException { + public void shouldUnfollow() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); @@ -722,8 +725,14 @@ public void shouldHaveToken() throws IOException, StreamClientException { assertThat(token, notNullValue()); } - private Map verifyToken(final String token) throws SignatureException, NoSuchAlgorithmException, JWTVerifyException, InvalidKeyException, IOException { + private Map verifyToken(final String token) { byte[] secret = API_SECRET.getBytes(); - return new JWTVerifier(secret, "audience").verify(token); + + Algorithm algorithm = Algorithm.HMAC256(secret); + + JWTVerifier verifier = JWT.require(algorithm).build(); + DecodedJWT jwt = verifier.verify(token); + + return jwt.getClaims(); } } diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index 3e27365b..ba88dec8 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -1,7 +1,10 @@ package io.getstream.client.okhttp; +import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; -import com.auth0.jwt.JWTVerifyException; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.interfaces.Claim; +import com.auth0.jwt.interfaces.DecodedJWT; import com.google.common.collect.ImmutableList; import io.getstream.client.StreamClient; import io.getstream.client.config.ClientConfiguration; @@ -56,15 +59,15 @@ public String getTestUserId(String userId) { } @Test - public void shouldGetReadOnlyToken() throws IOException, StreamClientException, NoSuchAlgorithmException, SignatureException, JWTVerifyException, InvalidKeyException { + public void shouldGetReadOnlyToken() throws StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); Feed feed = streamClient.newFeed("user", "1"); - Map map = verifyToken(feed.getReadOnlyToken()); + Map map = verifyToken(feed.getReadOnlyToken()); assertTrue(map.size() > 0); - assertThat(map.get("action").toString(), is("read")); - assertThat(map.get("resource").toString(), is(ALL)); + assertThat(map.get("action").asString(), is("read")); + assertThat(map.get("resource").asString(), is(ALL)); } @Test @@ -227,7 +230,7 @@ public void shouldHaveOriginField() throws IOException, StreamClientException, I } @Test - public void shouldUnfollow() throws IOException, StreamClientException, InterruptedException { + public void shouldUnfollow() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); @@ -756,7 +759,7 @@ public void shouldGetActivitiesFromAggregatedFeed() throws IOException, StreamCl } @Test - public void shouldHaveToken() throws IOException, StreamClientException { + public void shouldHaveToken() throws StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); Feed feed = streamClient.newFeed("aggregated", "whatever"); @@ -764,8 +767,14 @@ public void shouldHaveToken() throws IOException, StreamClientException { assertThat(token, notNullValue()); } - private Map verifyToken(final String token) throws SignatureException, NoSuchAlgorithmException, JWTVerifyException, InvalidKeyException, IOException { + private Map verifyToken(final String token) { byte[] secret = API_SECRET.getBytes(); - return new JWTVerifier(secret, "audience").verify(token); + + Algorithm algorithm = Algorithm.HMAC256(secret); + + JWTVerifier verifier = JWT.require(algorithm).build(); + DecodedJWT jwt = verifier.verify(token); + + return jwt.getClaims(); } } From 1763e5b2aadcded10e425bc703d46c5c1d46e56a Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 10 Oct 2018 15:47:44 +0200 Subject: [PATCH 099/320] Added support for the batch unfollow_many --- .../client/model/beans/UnfollowMany.java | 111 ++++++++++++++++++ .../client/model/feeds/BaseFeed.java | 6 + .../io/getstream/client/model/feeds/Feed.java | 16 ++- .../client/repo/StreamRepository.java | 13 +- .../apache/repo/StreamRepositoryImpl.java | 11 ++ .../client/apache/IntegrationTest.java | 35 ++++++ .../okhttp/repo/StreamRepositoryImpl.java | 24 ++-- .../client/okhttp/IntegrationTest.java | 38 +++++- 8 files changed, 241 insertions(+), 13 deletions(-) create mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/UnfollowMany.java diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/UnfollowMany.java b/stream-core/src/main/java/io/getstream/client/model/beans/UnfollowMany.java new file mode 100644 index 00000000..e5a12550 --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/model/beans/UnfollowMany.java @@ -0,0 +1,111 @@ +package io.getstream.client.model.beans; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** + * Helper bean used to perform bulk unfollow. + */ +public class UnfollowMany { + + @JsonSerialize(contentAs = UnfollowMany.Entry.class) + private final List entries; + + private UnfollowMany(final List entries) { + this.entries = entries; + } + + @JsonValue + public List getEntries() { + return entries; + } + + /** + * Provide an easy way to build an immutable list of unfollow. + */ + public static class Builder { + private ImmutableList.Builder followEntries = new ImmutableList.Builder<>(); + + /** + * Add a new unfollow source/target pair. Keep history is set to false. + * @param source Source feed + * @param target Target feed + * @return This builder. + */ + public Builder add(final String source, final String target) { + this.followEntries.add(new Entry(source, target, false)); + return this; + } + + /** + * Add a new unfollow source/target pair. + * @param source Source feed + * @param target Target feed + * @param keepHistory Whether the history must be preserved. + * @return This builder. + */ + public Builder add(final String source, final String target, final boolean keepHistory) { + this.followEntries.add(new Entry(source, target, keepHistory)); + return this; + } + + public Builder addMany(final List entries) { + this.followEntries.addAll(entries); + return this; + } + + /** + * Build an immutable list of unfollow. + * + * @return A marked activity + */ + public UnfollowMany build() { + return new UnfollowMany(followEntries.build()); + } + } + + public static class Entry { + + private String source; + private String target; + private boolean keepHistory; + + @JsonCreator + public Entry(@JsonProperty("source") final String source, + @JsonProperty("target") final String target, + @JsonProperty("keep_history") final boolean keepHistory) { + this.source = source; + this.target = target; + this.keepHistory = keepHistory; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public boolean getKeepHistory() { + return keepHistory; + } + + public void setKeepHistory(boolean keepHistory) { + this.keepHistory = keepHistory; + } + } +} diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java index 0c066b9d..b6f14ae2 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java @@ -4,6 +4,7 @@ import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; +import io.getstream.client.model.beans.UnfollowMany; import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.repo.StreamRepository; import io.getstream.client.service.AggregatedActivityServiceImpl; @@ -69,6 +70,11 @@ public void followMany(FollowMany follows) throws IOException, StreamClientExcep streamRepository.followMany(this, follows, DEFAULT_ACTIVITY_COPY_LIMIT); } + @Override + public void unfollowMany(UnfollowMany unfollowMany) throws IOException, StreamClientException { + streamRepository.unfollowMany(this, unfollowMany); + } + @Override public void unfollow(String feedSlug, String userId) throws IOException, StreamClientException { String feedId = String.format("%s:%s", feedSlug, userId); diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java b/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java index 740a9425..fe429d92 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java @@ -4,6 +4,7 @@ import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; +import io.getstream.client.model.beans.UnfollowMany; import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.service.AggregatedActivityServiceImpl; import io.getstream.client.service.FlatActivityServiceImpl; @@ -60,7 +61,7 @@ public interface Feed { void follow(String feedSlug, String userId, int activityCopyLimit) throws IOException, StreamClientException; /** - * Follow many feed in one shot. + * Follow many feeds in one shot. * * @param follows A {@link FollowMany} object which contains a list of sources and targets * @param activityCopyLimit the maximum number of activities from a @@ -71,7 +72,7 @@ public interface Feed { void followMany(FollowMany follows, int activityCopyLimit) throws IOException, StreamClientException; /** - * Follow many feed in one shot. + * Follow many feeds in one shot. * Default activity copy limit is set to 300. Maximum 300 activities from a given source feed * will be copied to the target feed. * @@ -81,6 +82,17 @@ public interface Feed { */ void followMany(FollowMany follows) throws IOException, StreamClientException; + /** + * Unfollow many feeds in one shot. + * + * @param unfollowMany A {@link UnfollowMany} object which contains a list of sources and targets. + * Any arbitrary feed can be specified as {@link io.getstream.client.model.beans.UnfollowMany.Entry#setSource(String)}, + * regardless the one used to trigger this operation. + * @throws StreamClientException in case of functional or server-side exception + * @throws IOException in case of network/socket exceptions + */ + void unfollowMany(UnfollowMany unfollowMany) throws IOException, StreamClientException; + /** * Unfollow the given target feed. * diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java index 28a933a0..33c3f687 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java @@ -9,6 +9,7 @@ import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.UnfollowMany; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; @@ -59,7 +60,7 @@ public interface StreamRepository { void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) throws StreamClientException, IOException; /** - * Follow many feed in one shot. + * Follow many feeds in one shot. * * @param feed Feed that wants to follow a target feed. * @param followManyInput A {@link FollowMany} object which contains a list of sources and targets @@ -69,6 +70,16 @@ public interface StreamRepository { */ void followMany(BaseFeed feed, FollowMany followManyInput, int activityCopyLimit) throws StreamClientException, IOException; + /** + * Unfollow many feeds in one shot. + * + * @param feed Feed that wants to follow a target feed. + * @param unfollowManyInput A {@link UnfollowMany} object which contains a list of sources and targets. + * @throws StreamClientException in case of functional or server-side exception + * @throws IOException in case of network/socket exceptions + */ + void unfollowMany(BaseFeed feed, UnfollowMany unfollowManyInput) throws StreamClientException, IOException; + /** * Unfollow a feed. * diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index b8f6c851..ed03e069 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -17,6 +17,7 @@ import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.UnfollowMany; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.repo.StreamRepository; @@ -104,6 +105,16 @@ public void followMany(BaseFeed feed, FollowMany followManyInput, int activityCo fireAndForget(request); } + @Override + public void unfollowMany(BaseFeed feed, UnfollowMany unfollowManyInput) throws StreamClientException, IOException { + HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) + .path("unfollow_many/") + .build()); + request.addHeader(HttpSignatureInterceptor.X_API_KEY_HEADER, apiKey); + request.setEntity(new StringEntity(objectMapper.writeValueAsString(unfollowManyInput), APPLICATION_JSON)); + fireAndForget(request); + } + @Override public void unfollow(BaseFeed feed, String targetFeedId, boolean keepHistory) throws StreamClientException, IOException { HttpDelete request = new HttpDelete(UriBuilder.fromEndpoint(baseEndpoint) diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index 5e2ace04..2e1938ca 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -20,6 +20,7 @@ import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.UnfollowMany; import io.getstream.client.model.feeds.Feed; import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.service.AggregatedActivityServiceImpl; @@ -178,6 +179,40 @@ public void shouldFollowMany() throws IOException, StreamClientException { streamClient.shutdown(); } + @Test + public void shouldUnfollowMany() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, + API_SECRET); + + String followerId = this.getTestUserId("shouldunfollowMany"); + Feed feed = streamClient.newFeed("user", followerId); + + List following = feed.getFollowing(); + assertThat(following.size(), is(0)); + + FollowMany followMany = new FollowMany.Builder() + .add("user:" + followerId, "user:1") + .add("user:" + followerId, "user:2") + .add("user:" + followerId, "user:3") + .build(); + feed.followMany(followMany); + + List followingAfter = feed.getFollowing(); + assertThat(followingAfter.size(), is(3)); + + UnfollowMany unfollowMany = new UnfollowMany.Builder() + .add("user:" + followerId, "user:1") + .add("user:" + followerId, "user:2", true) + .add("user:" + followerId, "user:3", false) + .build(); + feed.unfollowMany(unfollowMany); + + List unfollowingAfter = feed.getFollowing(); + assertThat(unfollowingAfter.size(), is(0)); + + streamClient.shutdown(); + } + @Test public void shouldHaveOriginField() throws IOException, StreamClientException, InterruptedException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index 23dfb346..e5dbe7d0 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -1,12 +1,5 @@ package io.getstream.client.okhttp.repo; -import java.io.IOException; -import java.net.URI; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import io.getstream.client.config.ClientConfiguration; @@ -20,6 +13,7 @@ import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.UnfollowMany; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.okhttp.StreamClientImpl; @@ -36,6 +30,12 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.URI; +import java.util.List; /** * Actual implementation of the Stream's REST API calls. @@ -111,6 +111,16 @@ public void followMany(BaseFeed feed, FollowMany followManyInput, int activityCo fireAndForget(requestBuilder.build()); } + @Override + public void unfollowMany(BaseFeed feed, UnfollowMany unfollowManyInput) throws StreamClientException, IOException { + Request.Builder requestBuilder = new Request.Builder().url(UriBuilder.fromEndpoint(baseEndpoint) + .path("unfollow_many/") + .build().toURL()); + requestBuilder.addHeader(HttpSignatureHandler.X_API_KEY_HEADER, apiKey); + requestBuilder.post(RequestBody.create(MediaType.parse(APPLICATION_JSON), objectMapper.writeValueAsString(unfollowManyInput))); + fireAndForget(requestBuilder.build()); + } + @Override public void unfollow(BaseFeed feed, String targetFeedId, boolean keepHistory) throws StreamClientException, IOException { Request.Builder requestBuilder = new Request.Builder().url(UriBuilder.fromEndpoint(baseEndpoint) diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index ba88dec8..afbf5944 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -20,6 +20,7 @@ import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.UnfollowMany; import io.getstream.client.model.feeds.Feed; import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.service.AggregatedActivityServiceImpl; @@ -29,9 +30,6 @@ import org.junit.Test; import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.SignatureException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -172,6 +170,40 @@ public void shouldFollowMany() throws IOException, StreamClientException { streamClient.shutdown(); } + @Test + public void shouldUnfollowMany() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, + API_SECRET); + + String followerId = this.getTestUserId("shouldunfollowMany"); + Feed feed = streamClient.newFeed("user", followerId); + + List following = feed.getFollowing(); + assertThat(following.size(), is(0)); + + FollowMany followMany = new FollowMany.Builder() + .add("user:" + followerId, "user:1") + .add("user:" + followerId, "user:2") + .add("user:" + followerId, "user:3") + .build(); + feed.followMany(followMany); + + List followingAfter = feed.getFollowing(); + assertThat(followingAfter.size(), is(3)); + + UnfollowMany unfollowMany = new UnfollowMany.Builder() + .add("user:" + followerId, "user:1") + .add("user:" + followerId, "user:2", true) + .add("user:" + followerId, "user:3", false) + .build(); + feed.unfollowMany(unfollowMany); + + List unfollowingAfter = feed.getFollowing(); + assertThat(unfollowingAfter.size(), is(0)); + + streamClient.shutdown(); + } + @Test public void shouldFollowManyWithActivityCopyLimit() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, From 60c33d5d2093aaf9cab07fb07463be2bdd6fe649 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 10 Oct 2018 15:50:52 +0200 Subject: [PATCH 100/320] Fixed connection leaks on OkHttp client --- .../okhttp/repo/StreamActivityRepository.java | 114 ++++++++++-------- .../StreamPersonalizedRepositoryImpl.java | 60 ++++----- .../okhttp/repo/StreamRepositoryImpl.java | 4 +- 3 files changed, 96 insertions(+), 82 deletions(-) diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java index a0c040b6..78f1a007 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java @@ -1,16 +1,5 @@ package io.getstream.client.okhttp.repo; -import static io.getstream.client.util.JwtAuthenticationUtil.ALL; -import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; - -import java.io.IOException; -import java.net.URI; -import java.util.Collections; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.fasterxml.jackson.databind.ObjectMapper; import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.AggregatedActivity; @@ -33,6 +22,16 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.URI; +import java.util.Collections; +import java.util.List; + +import static io.getstream.client.util.JwtAuthenticationUtil.ALL; +import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; public class StreamActivityRepository { @@ -68,10 +67,11 @@ public T addActivity(BaseFeed feed, T activity) throws Request request = addAuthentication(feed, requestBuilder).build(); LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); - return objectMapper.readValue(response.body().byteStream(), - objectMapper.getTypeFactory().constructType(activity.getClass())); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructType(activity.getClass())); + } } public StreamActivitiesResponse addActivities(BaseFeed feed, Class type, List activities) throws StreamClientException, IOException { @@ -89,10 +89,11 @@ public StreamActivitiesResponse addActivities(BaseFe Request request = addAuthentication(feed, requestBuilder).build(); LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); - return objectMapper.readValue(response.body().byteStream(), - objectMapper.getTypeFactory().constructParametricType(StreamActivitiesResponse.class, type)); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamActivitiesResponse.class, type)); + } } public T addToMany(List targetIds, T activity) throws StreamClientException, IOException { @@ -108,10 +109,11 @@ public T addToMany(List targetIds, T activity) final Request request = requestBuilder.build(); LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); - return objectMapper.readValue(response.body().byteStream(), - objectMapper.getTypeFactory().constructType(activity.getClass())); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructType(activity.getClass())); + } } public StreamResponse getActivities(BaseFeed feed, Class type, FeedFilter filter) throws IOException, StreamClientException { @@ -122,10 +124,11 @@ public StreamResponse getActivities(BaseFeed feed, C Request request = addAuthentication(feed, requestBuilder).build(); LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); - return objectMapper.readValue(response.body().byteStream(), - objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, type)); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, type)); + } } public StreamResponse> getAggregatedActivities(BaseFeed feed, Class type, FeedFilter filter) throws IOException, StreamClientException { @@ -136,10 +139,11 @@ public StreamResponse> getAggrega Request request = addAuthentication(feed, requestBuilder).build(); LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); - return objectMapper.readValue(response.body().byteStream(), - objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, objectMapper.getTypeFactory().constructParametricType(AggregatedActivity.class, type))); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, objectMapper.getTypeFactory().constructParametricType(AggregatedActivity.class, type))); + } } public StreamResponse> getNotificationActivities(BaseFeed feed, Class type, FeedFilter filter) throws IOException, StreamClientException { @@ -150,11 +154,12 @@ public StreamResponse> getNotif Request request = addAuthentication(feed, requestBuilder).build(); LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); - return objectMapper.readValue(response.body().byteStream(), - objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, - objectMapper.getTypeFactory().constructParametricType(NotificationActivity.class, type))); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, + objectMapper.getTypeFactory().constructParametricType(NotificationActivity.class, type))); + } } public StreamResponse> getNotificationActivities(BaseFeed feed, Class type, FeedFilter filter, boolean markAsRead, boolean markAsSeen) throws IOException, StreamClientException { @@ -167,10 +172,11 @@ public StreamResponse> getNotif Request request = addAuthentication(feed, requestBuilder).build(); LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); - return objectMapper.readValue(response.body().byteStream(), - objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, objectMapper.getTypeFactory().constructParametricType(NotificationActivity.class, type))); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, objectMapper.getTypeFactory().constructParametricType(NotificationActivity.class, type))); + } } public StreamResponse> getNotificationActivities(BaseFeed feed, Class type, FeedFilter filter, MarkedActivity markAsRead, MarkedActivity markAsSeen) throws IOException, StreamClientException { @@ -189,10 +195,11 @@ public StreamResponse> getNotif Request request = addAuthentication(feed, requestBuilder).build(); LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); - return objectMapper.readValue(response.body().byteStream(), - objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, objectMapper.getTypeFactory().constructParametricType(NotificationActivity.class, type))); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, objectMapper.getTypeFactory().constructParametricType(NotificationActivity.class, type))); + } } public void deleteActivityById(BaseFeed feed, String activityId) throws IOException, StreamClientException { @@ -203,8 +210,9 @@ public void deleteActivityById(BaseFeed feed, String activityId) throws IOExcept Request request = addAuthentication(feed, requestBuilder).build(); LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + } } public void deleteActivityByForeignId(BaseFeed feed, String activityId) throws IOException, StreamClientException { @@ -216,8 +224,9 @@ public void deleteActivityByForeignId(BaseFeed feed, String activityId) throws I Request request = addAuthentication(feed, requestBuilder).build(); LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + } } public StreamActivitiesResponse updateActivities(BaseFeed feed, Class type, List activities) throws IOException, StreamClientException { @@ -234,10 +243,11 @@ public StreamActivitiesResponse updateActivities(Bas LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); - return objectMapper.readValue(response.body().byteStream(), - objectMapper.getTypeFactory().constructParametricType(StreamActivitiesResponse.class, type)); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamActivitiesResponse.class, type)); + } } private void handleResponseCode(Response response) throws StreamClientException, IOException { diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java index 1820783c..32d36f7a 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java @@ -1,18 +1,5 @@ package io.getstream.client.okhttp.repo; -import static io.getstream.client.okhttp.repo.utils.FeedFilterUtils.apply; -import static io.getstream.client.util.JwtAuthenticationUtil.ALL; -import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; - -import java.io.IOException; -import java.io.Serializable; -import java.net.URI; -import java.util.Collections; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.fasterxml.jackson.databind.ObjectMapper; import io.getstream.client.config.ClientConfiguration; import io.getstream.client.exception.StreamClientException; @@ -31,6 +18,18 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.Serializable; +import java.net.URI; +import java.util.Collections; +import java.util.List; + +import static io.getstream.client.okhttp.repo.utils.FeedFilterUtils.apply; +import static io.getstream.client.util.JwtAuthenticationUtil.ALL; +import static io.getstream.client.util.JwtAuthenticationUtil.generateToken; public class StreamPersonalizedRepositoryImpl implements StreamPersonalizedRepository { @@ -71,11 +70,12 @@ public List get(PersonalizedFeed feed, Class requestBuilder).build(); LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); - StreamResponse streamResponse = objectMapper.readValue(response.body().byteStream(), - objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, type)); - return streamResponse.getResults(); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + StreamResponse streamResponse = objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, type)); + return streamResponse.getResults(); + } } @Override @@ -95,14 +95,15 @@ public MetaResponse addMeta(PersonalizedFeed feed, Serializable metaPayload) thr LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); - StreamResponse responseValue = objectMapper.readValue(response.body().byteStream(), StreamResponse.class); - if (responseValue != null) { - duration = Double.parseDouble(responseValue.getDuration()); + StreamResponse responseValue = objectMapper.readValue(response.body().byteStream(), StreamResponse.class); + if (responseValue != null) { + duration = Double.parseDouble(responseValue.getDuration()); + } + return new MetaResponse(duration, response.code()); } - return new MetaResponse(duration, response.code()); } @Override @@ -118,11 +119,12 @@ public List getInterest(PersonalizedFeed feed, Class requestBuilder).build(); LOG.debug("Invoking url: '{}", request.url().toString()); - Response response = httpClient.newCall(request).execute(); - handleResponseCode(response); - StreamResponse streamResponse = objectMapper.readValue(response.body().byteStream(), - objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, type)); - return streamResponse.getResults(); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + StreamResponse streamResponse = objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(StreamResponse.class, type)); + return streamResponse.getResults(); + } } private void handleResponseCode(Response response) throws StreamClientException, IOException { diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index e5dbe7d0..a1d4f65f 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -224,7 +224,9 @@ public void shutdown() throws IOException { private void fireAndForget(final Request request) throws IOException, StreamClientException { LOG.debug("Invoking url: '{}", request.url().toString()); - handleResponseCode(httpClient.newCall(request).execute()); + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + } } private void handleResponseCode(Response response) throws StreamClientException, IOException { From b9537c32499c2100bb291a1d8f027eee2a154889 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 10 Oct 2018 16:05:07 +0200 Subject: [PATCH 101/320] [maven-release-plugin] prepare release stream-java-2.1.0 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index b5f8f41b..21d4bcac 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 2.0.2-SNAPSHOT + 2.1.0 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-2.1.0 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 163e2a95..5facf9b0 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.0.2-SNAPSHOT + 2.1.0 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 42e13e3f..37810913 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.0.2-SNAPSHOT + 2.1.0 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 9ff4b0f4..abc751b9 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.0.2-SNAPSHOT + 2.1.0 4.0.0 From 2d576092ffed001a7e5e389da9294f52d3f57ef9 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 10 Oct 2018 16:05:19 +0200 Subject: [PATCH 102/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 21d4bcac..a30652f3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 2.1.0 + 2.1.1-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-2.1.0 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 5facf9b0..795dd46e 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.0 + 2.1.1-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 37810913..8d6875a4 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.0 + 2.1.1-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index abc751b9..20c3680c 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.0 + 2.1.1-SNAPSHOT 4.0.0 From 4ffaff15c75183a56b62a0b14621414caeb6893e Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 10 Oct 2018 16:11:42 +0200 Subject: [PATCH 103/320] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c54b68ee..a5746912 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 2.0.1 + 2.1.0 ``` @@ -36,14 +36,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 2.0.1 + 2.1.0 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:2.0.1' +compile 'io.getstream.client:stream-repo-okhttp:2.1.0' ``` In case you want to download the artifact and put it manually into your project, From 19551f05cf2faa93c529cf63adbdc44eae4831e1 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Wed, 10 Oct 2018 16:12:01 +0200 Subject: [PATCH 104/320] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a5746912..d2d6b321 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:2.0.1' +compile 'io.getstream.client:stream-repo-apache:2.1.0' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml From 32435f52044344c02bcdcb0b58ce6a93a67b248f Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 16 Oct 2018 13:47:12 +0200 Subject: [PATCH 105/320] Added getUserSessionToken() --- .../client/model/feeds/BaseFeed.java | 5 +++ .../io/getstream/client/model/feeds/Feed.java | 6 +++ .../client/repo/StreamRepository.java | 2 + .../client/util/JwtAuthenticationUtil.java | 41 +++++++++++++++++-- .../apache/repo/StreamRepositoryImpl.java | 5 +++ .../client/apache/IntegrationTest.java | 9 ++++ .../okhttp/repo/StreamRepositoryImpl.java | 5 +++ .../client/okhttp/IntegrationTest.java | 9 ++++ 8 files changed, 78 insertions(+), 4 deletions(-) diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java index b6f14ae2..b49982ed 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java @@ -48,6 +48,11 @@ public String getReadOnlyToken() { return streamRepository.getReadOnlyToken(this); } + @Override + public String getUserSessionToken() { + return streamRepository.getUserSessionToken(this); + } + @Override public void follow(String feedSlug, String userId) throws IOException, StreamClientException { String feedId = String.format("%s:%s", feedSlug, userId); diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java b/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java index fe429d92..95ac1986 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java @@ -39,6 +39,12 @@ public interface Feed { */ String getReadOnlyToken(); + /** + * Generate User Session JWT Token. UserId is taken from {@link Feed#getId()}. + * @return Token + */ + String getUserSessionToken(); + /** * Follows the given target feed. * diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java index 33c3f687..2a7b62be 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java @@ -48,6 +48,8 @@ public interface StreamRepository { */ String getReadOnlyToken(BaseFeed feed); + String getUserSessionToken(BaseFeed feed); + /** * Follow a feed. * diff --git a/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java b/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java index b6911d3c..75e25954 100644 --- a/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java +++ b/stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java @@ -1,11 +1,11 @@ package io.getstream.client.util; -import java.io.UnsupportedEncodingException; - import com.auth0.jwt.JWT; import com.auth0.jwt.JWTCreator; import com.auth0.jwt.algorithms.Algorithm; +import java.io.UnsupportedEncodingException; + /** * Utility class to generate a JWT token. */ @@ -28,8 +28,41 @@ public class JwtAuthenticationUtil { public static String generateToken(final String secretKey, final String action, final String resource, final String feedId, final String userId) { JWTCreator.Builder jwtBuilder = JWT.create(); - jwtBuilder = jwtBuilder.withClaim("action", action); - jwtBuilder = jwtBuilder.withClaim("resource", resource); + if (null != action) { + jwtBuilder = jwtBuilder.withClaim("action", action); + } + + if (null != resource) { + jwtBuilder = jwtBuilder.withClaim("resource", resource); + } + + if (null != feedId) { + jwtBuilder = jwtBuilder.withClaim("feed_id", feedId); + } + + if (null != userId) { + jwtBuilder = jwtBuilder.withClaim("user_id", userId); + } + + try { + Algorithm algorithm = Algorithm.HMAC256(secretKey); + + return jwtBuilder.sign(algorithm); + } catch (UnsupportedEncodingException exc) { + throw new IllegalStateException("Fatal error: JWT Algorithm unsupported."); + } + } + + /** + * Generate JWT token. + * @param secretKey API Secret + * @param feedId FeedId (if null it will not be added to the payload) + * @param userId UserId (if null it will not be added to the payload) + * @return Token string + */ + public static String generateToken(final String secretKey, final String feedId, final String userId) { + JWTCreator.Builder jwtBuilder = JWT.create(); + if (null != feedId) { jwtBuilder = jwtBuilder.withClaim("feed_id", feedId); } diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index ed03e069..9169e534 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -83,6 +83,11 @@ public String getReadOnlyToken(BaseFeed feed) { return JwtAuthenticationUtil.generateToken(secretKey, "read", "*", feed.getFeedSlug().concat(feed.getUserId()), null); } + @Override + public String getUserSessionToken(BaseFeed feed) { + return JwtAuthenticationUtil.generateToken(secretKey, null, feed.getUserId()); + } + @Override public void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) throws StreamClientException, IOException { HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index 2e1938ca..b2d40f7b 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -78,6 +78,15 @@ public void shouldGetReadOnlyToken() throws IOException, StreamClientException, assertThat(map.get("resource").asString(), is(ALL)); } + @Test + public void shouldGetUserSessionToken() throws StreamClientException { + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); + Feed feed = streamClient.newFeed("feedslug", "aUserId"); + + Map map = verifyToken(feed.getUserSessionToken()); + assertThat(map.get("user_id").asString(), is("aUserId")); + } + @Test public void shouldGetFollowers() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index a1d4f65f..de901ceb 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -86,6 +86,11 @@ public String getToken(BaseFeed feed) { return StreamRepoUtils.createFeedToken(feed, secretKey); } + @Override + public String getUserSessionToken(BaseFeed feed) { + return JwtAuthenticationUtil.generateToken(secretKey, null, feed.getUserId()); + } + @Override public void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) throws StreamClientException, IOException { Request.Builder requestBuilder = new Request.Builder().url(UriBuilder.fromEndpoint(baseEndpoint) diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index afbf5944..9d6949b6 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -68,6 +68,15 @@ public void shouldGetReadOnlyToken() throws StreamClientException { assertThat(map.get("resource").asString(), is(ALL)); } + @Test + public void shouldGetUserSessionToken() throws StreamClientException { + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); + Feed feed = streamClient.newFeed("feedslug", "aUserId"); + + Map map = verifyToken(feed.getUserSessionToken()); + assertThat(map.get("user_id").asString(), is("aUserId")); + } + @Test public void shouldGetFollowers() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, From 58f6389a3d1a2ffd9611ff6ad40aa994e29dbecc Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 16 Oct 2018 13:54:52 +0200 Subject: [PATCH 106/320] [maven-release-plugin] prepare release stream-java-2.1.1 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index a30652f3..0d58bdb2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 2.1.1-SNAPSHOT + 2.1.1 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-2.1.1 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 795dd46e..0bf1ffd6 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.1-SNAPSHOT + 2.1.1 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 8d6875a4..243bb234 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.1-SNAPSHOT + 2.1.1 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 20c3680c..eeeb025b 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.1-SNAPSHOT + 2.1.1 4.0.0 From 634cca9d39130ebbb63c75d8b07b8178eab69596 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 16 Oct 2018 13:55:01 +0200 Subject: [PATCH 107/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 0d58bdb2..903df51b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 2.1.1 + 2.1.2-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-2.1.1 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 0bf1ffd6..3eb94740 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.1 + 2.1.2-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 243bb234..5ac747c2 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.1 + 2.1.2-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index eeeb025b..b3e8cba8 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.1 + 2.1.2-SNAPSHOT 4.0.0 From b30e41318028ad0cc115286f06aa253b31becc66 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 16 Oct 2018 14:39:38 +0200 Subject: [PATCH 108/320] Moved getUserSessionToken() to StreamClient to keep the design consistent with other Stream clients. --- .../io/getstream/client/StreamClient.java | 8 +++++ .../client/model/feeds/BaseFeed.java | 5 --- .../io/getstream/client/model/feeds/Feed.java | 6 ---- .../client/repo/StreamRepository.java | 2 -- .../client/apache/StreamClientImpl.java | 19 ++++++++++++ .../apache/repo/StreamRepositoryImpl.java | 5 --- .../client/apache/IntegrationTest.java | 4 +-- .../client/okhttp/StreamClientImpl.java | 31 +++++++++++++++---- .../okhttp/repo/StreamRepositoryImpl.java | 5 --- .../client/okhttp/IntegrationTest.java | 4 +-- 10 files changed, 54 insertions(+), 35 deletions(-) diff --git a/stream-core/src/main/java/io/getstream/client/StreamClient.java b/stream-core/src/main/java/io/getstream/client/StreamClient.java index 5265c611..a83dc829 100644 --- a/stream-core/src/main/java/io/getstream/client/StreamClient.java +++ b/stream-core/src/main/java/io/getstream/client/StreamClient.java @@ -31,6 +31,14 @@ public interface StreamClient { */ PersonalizedFeed newPersonalizedFeed(String feedSlug, String id) throws InvalidFeedNameException; + + /** + * Generate User Session JWT Token. + * @param userId User identifier + * @return JWT Token + */ + String getUserSessionToken(String userId); + /** * Send the shutdown signal to the client. * diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java index b49982ed..b6f14ae2 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java @@ -48,11 +48,6 @@ public String getReadOnlyToken() { return streamRepository.getReadOnlyToken(this); } - @Override - public String getUserSessionToken() { - return streamRepository.getUserSessionToken(this); - } - @Override public void follow(String feedSlug, String userId) throws IOException, StreamClientException { String feedId = String.format("%s:%s", feedSlug, userId); diff --git a/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java b/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java index 95ac1986..fe429d92 100644 --- a/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java +++ b/stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java @@ -39,12 +39,6 @@ public interface Feed { */ String getReadOnlyToken(); - /** - * Generate User Session JWT Token. UserId is taken from {@link Feed#getId()}. - * @return Token - */ - String getUserSessionToken(); - /** * Follows the given target feed. * diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java index 2a7b62be..33c3f687 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java @@ -48,8 +48,6 @@ public interface StreamRepository { */ String getReadOnlyToken(BaseFeed feed); - String getUserSessionToken(BaseFeed feed); - /** * Follow a feed. * diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java index 9c12d728..1b71485f 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java @@ -20,6 +20,7 @@ import io.getstream.client.repo.StreamPersonalizedRepository; import io.getstream.client.repo.StreamRepository; import io.getstream.client.util.InfoUtil; +import io.getstream.client.util.JwtAuthenticationUtil; import org.apache.http.client.config.RequestConfig; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy; @@ -39,6 +40,8 @@ public class StreamClientImpl implements StreamClient { private FeedFactory feedFactory; private final StreamRepository streamRepository; private final Optional streamPersonalizedRepository; + private final String apiKey; + private final String secretKey; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() .setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES) @@ -46,6 +49,9 @@ public class StreamClientImpl implements StreamClient { .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); public StreamClientImpl(final ClientConfiguration clientConfiguration, final String key, final String secretKey) { + this.apiKey = key; + this.secretKey = secretKey; + Preconditions.checkNotNull(clientConfiguration, "Client configuration cannot be null."); AuthenticationHandlerConfiguration authenticationHandlerConfiguration = new AuthenticationHandlerConfiguration(); authenticationHandlerConfiguration.setApiKey(checkNotNull(key, "API key cannot be null.")); @@ -70,6 +76,11 @@ public PersonalizedFeed newPersonalizedFeed(final String feedSlug, return this.feedFactory.createPersonalizedFeed(feedSlug, id); } + @Override + public String getUserSessionToken(String userId) { + return JwtAuthenticationUtil.generateToken(getSecretKey(), null, userId); + } + @Override public void shutdown() throws IOException { this.streamRepository.shutdown(); @@ -123,4 +134,12 @@ private CloseableHttpClient initClient(final ClientConfiguration config, public static ObjectMapper getObjectMapper() { return OBJECT_MAPPER; } + + public String getApiKey() { + return apiKey; + } + + public String getSecretKey() { + return secretKey; + } } \ No newline at end of file diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index 9169e534..ed03e069 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -83,11 +83,6 @@ public String getReadOnlyToken(BaseFeed feed) { return JwtAuthenticationUtil.generateToken(secretKey, "read", "*", feed.getFeedSlug().concat(feed.getUserId()), null); } - @Override - public String getUserSessionToken(BaseFeed feed) { - return JwtAuthenticationUtil.generateToken(secretKey, null, feed.getUserId()); - } - @Override public void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) throws StreamClientException, IOException { HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index b2d40f7b..d74fb508 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -81,9 +81,7 @@ public void shouldGetReadOnlyToken() throws IOException, StreamClientException, @Test public void shouldGetUserSessionToken() throws StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); - Feed feed = streamClient.newFeed("feedslug", "aUserId"); - - Map map = verifyToken(feed.getUserSessionToken()); + Map map = verifyToken(streamClient.getUserSessionToken("aUserId")); assertThat(map.get("user_id").asString(), is("aUserId")); } diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java index a6edbe30..39386308 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java @@ -1,11 +1,5 @@ package io.getstream.client.okhttp; -import static com.google.common.base.Preconditions.checkNotNull; - -import java.io.IOException; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; @@ -26,11 +20,18 @@ import io.getstream.client.repo.StreamPersonalizedRepository; import io.getstream.client.repo.StreamRepository; import io.getstream.client.util.InfoUtil; +import io.getstream.client.util.JwtAuthenticationUtil; import okhttp3.ConnectionPool; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Response; +import java.io.IOException; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +import static com.google.common.base.Preconditions.checkNotNull; + public class StreamClientImpl implements StreamClient { private static final String USER_AGENT_PREFIX = "stream-java-okhttp-%s"; @@ -38,6 +39,8 @@ public class StreamClientImpl implements StreamClient { private final Optional streamPersonalizedRepository; private FeedFactory feedFactory; private final StreamRepository streamRepository; + private final String apiKey; + private final String secretKey; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() .setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES) @@ -45,6 +48,9 @@ public class StreamClientImpl implements StreamClient { .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); public StreamClientImpl(final ClientConfiguration clientConfiguration, final String key, final String secretKey) { + this.apiKey = key; + this.secretKey = secretKey; + Preconditions.checkNotNull(clientConfiguration, "Client configuration cannot be null."); AuthenticationHandlerConfiguration authenticationHandlerConfiguration = new AuthenticationHandlerConfiguration(); authenticationHandlerConfiguration.setApiKey(checkNotNull(key, "API key cannot be null.")); @@ -69,6 +75,11 @@ public PersonalizedFeed newPersonalizedFeed(final String feedSlug, return this.feedFactory.createPersonalizedFeed(feedSlug, id); } + @Override + public String getUserSessionToken(String userId) { + return JwtAuthenticationUtil.generateToken(getSecretKey(), null, userId); + } + @Override public void shutdown() throws IOException { this.streamRepository.shutdown(); @@ -124,4 +135,12 @@ private String getUserAgent() { public static ObjectMapper getObjectMapper() { return OBJECT_MAPPER; } + + public String getApiKey() { + return apiKey; + } + + public String getSecretKey() { + return secretKey; + } } \ No newline at end of file diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index de901ceb..a1d4f65f 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -86,11 +86,6 @@ public String getToken(BaseFeed feed) { return StreamRepoUtils.createFeedToken(feed, secretKey); } - @Override - public String getUserSessionToken(BaseFeed feed) { - return JwtAuthenticationUtil.generateToken(secretKey, null, feed.getUserId()); - } - @Override public void follow(BaseFeed feed, String targetFeedId, int activityCopyLimit) throws StreamClientException, IOException { Request.Builder requestBuilder = new Request.Builder().url(UriBuilder.fromEndpoint(baseEndpoint) diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index 9d6949b6..3c151849 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -71,9 +71,7 @@ public void shouldGetReadOnlyToken() throws StreamClientException { @Test public void shouldGetUserSessionToken() throws StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, API_SECRET); - Feed feed = streamClient.newFeed("feedslug", "aUserId"); - - Map map = verifyToken(feed.getUserSessionToken()); + Map map = verifyToken(streamClient.getUserSessionToken("aUserId")); assertThat(map.get("user_id").asString(), is("aUserId")); } From 046608ac003aac343ca3cd84a170c628999bb750 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 16 Oct 2018 15:05:31 +0200 Subject: [PATCH 109/320] [maven-release-plugin] prepare release stream-java-2.1.2 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 903df51b..90700f89 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 2.1.2-SNAPSHOT + 2.1.2 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-2.1.2 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 3eb94740..dac3c877 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.2-SNAPSHOT + 2.1.2 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 5ac747c2..91c5ab95 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.2-SNAPSHOT + 2.1.2 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index b3e8cba8..4003afbd 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.2-SNAPSHOT + 2.1.2 4.0.0 From e654dca28e6410858ae7ec34ea6f709d4292dace Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 16 Oct 2018 15:05:41 +0200 Subject: [PATCH 110/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 90700f89..3049178d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 2.1.2 + 2.1.3-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-2.1.2 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index dac3c877..04ed6a52 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.2 + 2.1.3-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 91c5ab95..820227d8 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.2 + 2.1.3-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 4003afbd..135cf452 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.2 + 2.1.3-SNAPSHOT 4.0.0 From 6067878bf7d5cab73baabc44a39320a049ba75cb Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 16 Oct 2018 15:30:31 +0200 Subject: [PATCH 111/320] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d2d6b321..8bbedc09 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 2.1.0 + 2.1.2 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:2.1.0' +compile 'io.getstream.client:stream-repo-apache:2.1.2' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -36,14 +36,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 2.1.0 + 2.1.2 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:2.1.0' +compile 'io.getstream.client:stream-repo-okhttp:2.1.2' ``` In case you want to download the artifact and put it manually into your project, From 699bb23cfc74b01a142647e21c89544ed49b4e13 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 30 Oct 2018 12:37:10 +0100 Subject: [PATCH 112/320] Added support for "update_to_targets" operation. --- .../activities/UpdateTargetResponse.java | 80 +++++++++++ .../getstream/client/model/beans/Targets.java | 126 ++++++++++++++++++ .../client/model/beans/UpdateTo.java | 49 +++++++ .../client/repo/StreamRepository.java | 14 ++ .../service/AbstractActivityService.java | 15 +++ .../client/model/beans/TargetsTest.java | 39 ++++++ .../apache/repo/StreamActivityRepository.java | 32 +++++ .../apache/repo/StreamRepositoryImpl.java | 7 + .../repo/handlers/StreamExceptionHandler.java | 16 ++- .../client/apache/IntegrationTest.java | 73 +++++++++- .../okhttp/repo/StreamActivityRepository.java | 33 +++++ .../okhttp/repo/StreamRepositoryImpl.java | 7 + .../client/okhttp/IntegrationTest.java | 73 +++++++++- 13 files changed, 555 insertions(+), 9 deletions(-) create mode 100644 stream-core/src/main/java/io/getstream/client/model/activities/UpdateTargetResponse.java create mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/Targets.java create mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/UpdateTo.java create mode 100644 stream-core/src/test/java/io/getstream/client/model/beans/TargetsTest.java diff --git a/stream-core/src/main/java/io/getstream/client/model/activities/UpdateTargetResponse.java b/stream-core/src/main/java/io/getstream/client/model/activities/UpdateTargetResponse.java new file mode 100644 index 00000000..5074260c --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/model/activities/UpdateTargetResponse.java @@ -0,0 +1,80 @@ +package io.getstream.client.model.activities; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +/** + * update_to_targets's response wrapper class. + * @param Type of the activity in scope. + */ +public class UpdateTargetResponse { + + private T activity; + private String duration; + + @JsonProperty("added") + private List addedTargets; + + @JsonProperty("removed") + private List removedTargets; + + @JsonProperty("new") + private List newTargets; + + public void setDuration(String duration) { + this.duration = duration; + } + + /** + * Duration of the operation. + * @return Duration in human-readable format. + */ + public String getDuration() { + return duration; + } + + public T getActivity() { + return activity; + } + + public void setActivity(T activity) { + this.activity = activity; + } + + /** + * Get a list of added target(s). + * @return List of added target(s) + */ + public List getAddedTargets() { + return addedTargets; + } + + public void setAddedTargets(List addedTargets) { + this.addedTargets = addedTargets; + } + + /** + * Get a list of removed target(s). + * @return List of remove target(s) + */ + public List getRemovedTargets() { + return removedTargets; + } + + public void setRemovedTargets(List removedTargets) { + this.removedTargets = removedTargets; + } + + /** + * Get a list of newly created target(s). + * @return List of newly created target(s) + */ + public List getNewTargets() { + return newTargets; + } + + public void setNewTargets(List newTargets) { + this.newTargets = newTargets; + } +} diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/Targets.java b/stream-core/src/main/java/io/getstream/client/model/beans/Targets.java new file mode 100644 index 00000000..6b31cc91 --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/model/beans/Targets.java @@ -0,0 +1,126 @@ +package io.getstream.client.model.beans; + +import com.google.common.collect.ImmutableList; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class acts as container for a list of operations intended to alter the target(s) of a given activity. + * A {@link Targets.Builder} is required in order to build a {@link Targets} object. + * + */ +public class Targets { + + private ImmutableList newTargets; + private ImmutableList addedTargets; + private ImmutableList removedTargets; + + public Targets(List newTargets, List addedTargets, List removedTargets) { + if (!newTargets.isEmpty()) { + this.newTargets = ImmutableList.copyOf(newTargets); + } + + if (!addedTargets.isEmpty()) { + this.addedTargets = ImmutableList.copyOf(addedTargets); + } + + if (!removedTargets.isEmpty()) { + this.removedTargets = ImmutableList.copyOf(removedTargets); + } + } + + public List getNewTargets() { + return newTargets; + } + + public List getAddedTargets() { + return addedTargets; + } + + public List getRemovedTargets() { + return removedTargets; + } + + /** + * Builder class for the {@link Targets} object. + */ + public static class Builder { + + private List newTargets = new ArrayList<>(); + private List addedTargets = new ArrayList<>(); + private List removedTargets = new ArrayList<>(); + + /** + * Set a list of new target(s). + * @param newTargets New target(s) + * @return This builder + */ + public Builder setNewTargets(List newTargets) { + this.newTargets = newTargets; + return this; + } + + /** + * Set a list of target(s) to add. + * @param addedTargets Target(s) to add. + * @return This builder + */ + public Builder setAddedTargets(List addedTargets) { + this.addedTargets = addedTargets; + return this; + } + + /** + * Set a list of target(s) to be removed. + * @param removedTargets Target(s) to be removed. + * @return This builder + */ + public Builder setRemovedTargets(List removedTargets) { + this.removedTargets = removedTargets; + return this; + } + + /** + * Change the existing target by specifying a new one. + * @param target New target. + * @return This builder + */ + public Builder addNewTarget(String target) { + this.newTargets.add(target); + return this; + } + + /** + * Add a new target to be added. + * @param target Target to be added. + * @return This builder + */ + public Builder addTargetToAdd(String target) { + this.addedTargets.add(target); + return this; + } + + /** + * Add a target to be removed. + * @param target Target to be removed. + * @return This builder + */ + public Builder addTargetToRemove(String target) { + this.removedTargets.add(target); + return this; + } + + /** + * Build a {@link Targets} object. + * You can specify either new targets or added targets or removed targets or a combinations of added and removed targets. + * @return A valid {@link Targets} object. + */ + public Targets build() { + if (!newTargets.isEmpty() && (!addedTargets.isEmpty() || !removedTargets.isEmpty())) { + throw new IllegalArgumentException("You can specify either new targets or added targets or removed targets or a combinations of added and removed targets."); + } + return new Targets(newTargets, addedTargets, removedTargets); + } + } +} diff --git a/stream-core/src/main/java/io/getstream/client/model/beans/UpdateTo.java b/stream-core/src/main/java/io/getstream/client/model/beans/UpdateTo.java new file mode 100644 index 00000000..2809b00e --- /dev/null +++ b/stream-core/src/main/java/io/getstream/client/model/beans/UpdateTo.java @@ -0,0 +1,49 @@ +package io.getstream.client.model.beans; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.getstream.client.model.activities.BaseActivity; + +import java.util.List; + +/** + * This custom activity is required to perform the update_to_targets operation. + */ +public class UpdateTo extends BaseActivity { + + @JsonInclude(JsonInclude.Include.NON_NULL) + @JsonProperty("new_targets") + private List newTargets; + + @JsonInclude(JsonInclude.Include.NON_NULL) + @JsonProperty("added_targets") + private List addedTargets; + + @JsonInclude(JsonInclude.Include.NON_NULL) + @JsonProperty("removed_targets") + private List removedTargets; + + public List getNewTargets() { + return newTargets; + } + + public void setNewTargets(List newTargets) { + this.newTargets = newTargets; + } + + public List getAddedTargets() { + return addedTargets; + } + + public void setAddedTargets(List addedTargets) { + this.addedTargets = addedTargets; + } + + public List getRemovedTargets() { + return removedTargets; + } + + public void setRemovedTargets(List removedTargets) { + this.removedTargets = removedTargets; + } +} diff --git a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java index 33c3f687..964439ab 100644 --- a/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java +++ b/stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java @@ -4,11 +4,13 @@ import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.NotificationActivity; +import io.getstream.client.model.activities.UpdateTargetResponse; import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.Targets; import io.getstream.client.model.beans.UnfollowMany; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; @@ -163,6 +165,18 @@ public interface StreamRepository { */ StreamActivitiesResponse updateActivities(BaseFeed feed, Class type, List activities) throws IOException, StreamClientException; + /** + * Update the to target(s) of a given {@link T} activity. + * @param feed Feed which the activity belong to + * @param activity The activity in scope. + * @param targets A container for the operations that need to be performed on the to field. + * @param The type of the activity. + * @return Response containing the modified activity and a summary of the actions performed to the to field. + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + UpdateTargetResponse updateToTargets(BaseFeed feed, BaseActivity activity, Targets targets) throws StreamClientException, IOException; + /** * Add a new activity of type {@link T} to multiple feeds. * diff --git a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java index 1076509e..091c9530 100644 --- a/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java +++ b/stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java @@ -2,7 +2,9 @@ import io.getstream.client.exception.StreamClientException; import io.getstream.client.model.activities.BaseActivity; +import io.getstream.client.model.activities.UpdateTargetResponse; import io.getstream.client.model.beans.StreamActivitiesResponse; +import io.getstream.client.model.beans.Targets; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.repo.StreamRepository; @@ -67,6 +69,19 @@ public StreamActivitiesResponse updateActivities(List activities) throws I return streamRepository.updateActivities(this.feed, type, activities); } + /** + * Update the to target(s) of a given {@link T} activity. + * @param activity The activity in scope. + * @param targets A container for the operations that need to be performed on the to field. + * @param The type of the activity. + * @return Response containing the modified activity and a summary of the actions performed to the to field. + * @throws IOException in case of network/socket exceptions + * @throws StreamClientException in case of functional or server-side exception + */ + public UpdateTargetResponse updateToTargets(BaseActivity activity, Targets targets) throws IOException, StreamClientException { + return streamRepository.updateToTargets(feed, activity, targets); + } + /** * Add a new activity of type {@link T} to multiple feeds. * diff --git a/stream-core/src/test/java/io/getstream/client/model/beans/TargetsTest.java b/stream-core/src/test/java/io/getstream/client/model/beans/TargetsTest.java new file mode 100644 index 00000000..0ad7c9b5 --- /dev/null +++ b/stream-core/src/test/java/io/getstream/client/model/beans/TargetsTest.java @@ -0,0 +1,39 @@ +package io.getstream.client.model.beans; + +import org.junit.Test; + +import java.util.Collections; + +import static org.hamcrest.CoreMatchers.hasItem; +import static org.junit.Assert.assertThat; + +public class TargetsTest { + + @Test + public void shouldBuildTheTargetWithNewTargets() { + Targets targets = new Targets.Builder() + .setNewTargets(Collections.singletonList("user:newUser1")) + .build(); + + assertThat(targets.getNewTargets(), hasItem("user:newUser1")); + } + + @Test + public void shouldBuildTheTargetWithAddAndRemoveTargets() { + Targets targets = new Targets.Builder() + .setAddedTargets(Collections.singletonList("user:newUser1")) + .setRemovedTargets(Collections.singletonList("user:newUser2")) + .build(); + + assertThat(targets.getAddedTargets(), hasItem("user:newUser1")); + assertThat(targets.getRemovedTargets(), hasItem("user:newUser2")); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldFailBuildingTargets() { + Targets targets = new Targets.Builder() + .setNewTargets(Collections.singletonList("user:newUser1")) + .setRemovedTargets(Collections.singletonList("user:newUser2")) + .build(); + } +} \ No newline at end of file diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java index 3400e0ac..4243df1e 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java @@ -9,10 +9,13 @@ import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.NotificationActivity; +import io.getstream.client.model.activities.UpdateTargetResponse; import io.getstream.client.model.beans.AddMany; import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.Targets; +import io.getstream.client.model.beans.UpdateTo; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.util.HttpSignatureHandler; @@ -228,6 +231,35 @@ public StreamActivitiesResponse updateActivities(Bas } } + public UpdateTargetResponse updateToTargets(BaseFeed feed, BaseActivity activity, Targets targets) throws StreamClientException, IOException { + HttpPost request = new HttpPost(UriBuilder.fromEndpoint(baseEndpoint) + .path("feed_targets/") + .path(feed.getFeedSlug().concat("/")) + .path(feed.getUserId().concat("/")) + .path("activity_to_targets/") + .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build()); + LOG.debug("Invoking url: '{}'", request.getURI()); + + UpdateTo updateActivity = new UpdateTo(); + updateActivity.setForeignId(activity.getForeignId()); + updateActivity.setTime(activity.getTime()); + updateActivity.setNewTargets(targets.getNewTargets()); + updateActivity.setAddedTargets(targets.getAddedTargets()); + updateActivity.setRemovedTargets(targets.getRemovedTargets()); + + request.setEntity(new InputStreamEntity(new ByteArrayInputStream(objectMapper.writeValueAsBytes(updateActivity)), APPLICATION_JSON)); + + request = StreamRepoUtils.addJwtAuthentication(generateToken(secretKey, "write", "feed_targets", feed.getFeedSlug().concat(feed.getUserId()), null), request); + + LOG.debug("Type: " + activity.getClass()); + try (CloseableHttpResponse response = httpClient.execute(request, HttpClientContext.create())) { + handleResponseCode(response); + return objectMapper.readValue(response.getEntity().getContent(), + objectMapper.getTypeFactory().constructParametricType(UpdateTargetResponse.class, + objectMapper.constructType(activity.getClass()))); + } + } + private HttpRequestBase addAuthentication(BaseFeed feed, HttpRequestBase request) { return StreamRepoUtils.addAuthentication(feed, secretKey, request); } diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java index ed03e069..b953e38d 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java @@ -11,12 +11,14 @@ import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.NotificationActivity; +import io.getstream.client.model.activities.UpdateTargetResponse; import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; import io.getstream.client.model.beans.FollowRequest; import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.Targets; import io.getstream.client.model.beans.UnfollowMany; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; @@ -184,6 +186,11 @@ public StreamActivitiesResponse updateActivities(Bas return streamActivityRepository.updateActivities(feed, type, activities); } + @Override + public UpdateTargetResponse updateToTargets(BaseFeed feed, BaseActivity activity, Targets targets) throws StreamClientException, IOException { + return streamActivityRepository.updateToTargets(feed, activity, targets); + } + @Override public T addActivityToMany(List targetIds, T activity) throws StreamClientException, IOException { return streamActivityRepository.addToMany(targetIds, activity); diff --git a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java index b6fbd9a7..f3177aab 100644 --- a/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java +++ b/stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java @@ -1,5 +1,6 @@ package io.getstream.client.apache.repo.handlers; +import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.ObjectMapper; import io.getstream.client.exception.AuthenticationFailedException; import io.getstream.client.exception.InternalServerException; @@ -69,12 +70,17 @@ private void parseException(final CloseableHttpResponse response) throws IOExcep private StreamClientException buildException(StreamClientException exception, CloseableHttpResponse response) throws IOException { - StreamErrorResponse error = objectMapper.readValue(response.getEntity().getContent(), StreamErrorResponse.class); - if (null != error) { - exception.setCode(error.getCode()); + try { + StreamErrorResponse error = objectMapper.readValue(response.getEntity().getContent(), StreamErrorResponse.class); + if (null != error) { + exception.setCode(error.getCode()); + exception.setHttpStatusCode(response.getStatusLine().getStatusCode()); + exception.setDetail(error.getDetail()); + exception.setExceptionField(error.getException()); + } + } catch (JsonParseException e) { exception.setHttpStatusCode(response.getStatusLine().getStatusCode()); - exception.setDetail(error.getDetail()); - exception.setExceptionField(error.getException()); + exception.setDetail(response.getStatusLine().getReasonPhrase()); } return exception; } diff --git a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java index d74fb508..0f44151b 100644 --- a/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java +++ b/stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java @@ -15,11 +15,13 @@ import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.NotificationActivity; import io.getstream.client.model.activities.SimpleActivity; +import io.getstream.client.model.activities.UpdateTargetResponse; import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.Targets; import io.getstream.client.model.beans.UnfollowMany; import io.getstream.client.model.feeds.Feed; import io.getstream.client.model.filters.FeedFilter; @@ -44,8 +46,7 @@ import static io.getstream.client.util.JwtAuthenticationUtil.ALL; import static junit.framework.TestCase.assertTrue; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; public class IntegrationTest { @@ -368,6 +369,74 @@ public void shouldUpdateActivities() throws IOException, StreamClientException { streamClient.shutdown(); } + @Test + public void shouldUpdateToTargets() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, + API_SECRET); + + String user1 = this.getTestUserId("shouldChangeTo1"); + Feed feed = streamClient.newFeed("user", user1); + FlatActivityServiceImpl flatActivityService1 = feed.newFlatActivityService(SimpleActivity.class); + + SimpleActivity activityUser1 = new SimpleActivity(); + activityUser1.setForeignId("activityUser1"); + activityUser1.setActor("user1"); + activityUser1.setVerb("like"); + activityUser1.setObject("object1"); + activityUser1.setTime(new Date()); + + /* add activity 'activityUser1' */ + flatActivityService1.addActivity(activityUser1); + + + String user2 = this.getTestUserId("shouldChangeTo2"); + Feed feed2 = streamClient.newFeed("user", user2); + FlatActivityServiceImpl flatActivityService2 = feed2.newFlatActivityService(SimpleActivity.class); + + SimpleActivity activityUser2 = new SimpleActivity(); + activityUser2.setForeignId("activityUser2"); + activityUser2.setActor("user2"); + activityUser2.setVerb("like"); + activityUser2.setObject("object1"); + activityUser2.setTime(new Date()); + + /* add activity 'activityUser2' */ + flatActivityService2.addActivity(activityUser2); + + + String user3 = this.getTestUserId("shouldChangeTo2"); + Feed feed3 = streamClient.newFeed("user", user3); + FlatActivityServiceImpl flatActivityService3 = feed2.newFlatActivityService(SimpleActivity.class); + + SimpleActivity activityUser3 = new SimpleActivity(); + activityUser3.setForeignId("activityUser3"); + activityUser3.setActor("user3"); + activityUser3.setVerb("like"); + activityUser3.setObject("object1"); + activityUser3.setTime(new Date()); + activityUser3.setForeignId("user:".concat(user1)); + activityUser3.setTo(Collections.singletonList("user:".concat(user1))); // 'to' field points to 'user1' feed + + /* add activity 'activityUser3' with 'to' field pointing to feed user1 */ + flatActivityService3.addActivity(activityUser3); + + /* change the 'to' field of activity 'activityUser3' from user1 to user2 */ + /* addNewTarget(new_activity) replaces the 'to' field. It's equivalent to run addTargetToAdd(new_activity) and + * addTargetToRemove(old_activity). See the below assertions. */ + Targets toTargets = new Targets.Builder() + .addNewTarget("user:".concat(user2)) + .build(); + + /* perform the change */ + UpdateTargetResponse response = flatActivityService3.updateToTargets(activityUser3, toTargets); + + assertThat(response.getRemovedTargets(), hasItem("user:".concat(user1))); + assertThat(response.getAddedTargets(), hasItem("user:".concat(user2))); + assertThat(response.getActivity().getTo(), hasItem("user:".concat(user2))); + + streamClient.shutdown(); + } + @Test public void shouldAddActivityToMany() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java index 78f1a007..ef9a156f 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java @@ -5,10 +5,13 @@ import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.NotificationActivity; +import io.getstream.client.model.activities.UpdateTargetResponse; import io.getstream.client.model.beans.AddMany; import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.Targets; +import io.getstream.client.model.beans.UpdateTo; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; import io.getstream.client.okhttp.repo.handlers.StreamExceptionHandler; @@ -250,6 +253,36 @@ public StreamActivitiesResponse updateActivities(Bas } } + public UpdateTargetResponse updateToTargets(BaseFeed feed, BaseActivity activity, Targets targets) throws StreamClientException, IOException { + Request.Builder requestBuilder = new Request.Builder().delete().url(UriBuilder.fromEndpoint(baseEndpoint) + .path("feed_targets/") + .path(feed.getFeedSlug().concat("/")) + .path(feed.getUserId().concat("/")) + .path("activity_to_targets/") + .queryParam(StreamRepositoryImpl.API_KEY, apiKey).build().toURL()); + + UpdateTo updateActivity = new UpdateTo(); + updateActivity.setForeignId(activity.getForeignId()); + updateActivity.setTime(activity.getTime()); + updateActivity.setNewTargets(targets.getNewTargets()); + updateActivity.setAddedTargets(targets.getAddedTargets()); + updateActivity.setRemovedTargets(targets.getRemovedTargets()); + + requestBuilder.post(RequestBody.create(MediaType.parse(APPLICATION_JSON), objectMapper.writeValueAsBytes(updateActivity))); + + Request request = StreamRepoUtils.addJwtAuthentication(generateToken(secretKey, "write", "feed_targets", + feed.getFeedSlug().concat(feed.getUserId()), null), requestBuilder).build(); + + LOG.debug("Invoking url: '{}", request.url().toString()); + + try (Response response = httpClient.newCall(request).execute()) { + handleResponseCode(response); + return objectMapper.readValue(response.body().byteStream(), + objectMapper.getTypeFactory().constructParametricType(UpdateTargetResponse.class, + objectMapper.constructType(activity.getClass()))); + } + } + private void handleResponseCode(Response response) throws StreamClientException, IOException { exceptionHandler.handleResponseCode(response); } diff --git a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java index a1d4f65f..2dfc36de 100644 --- a/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java +++ b/stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java @@ -7,12 +7,14 @@ import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.BaseActivity; import io.getstream.client.model.activities.NotificationActivity; +import io.getstream.client.model.activities.UpdateTargetResponse; import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; import io.getstream.client.model.beans.FollowRequest; import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.Targets; import io.getstream.client.model.beans.UnfollowMany; import io.getstream.client.model.feeds.BaseFeed; import io.getstream.client.model.filters.FeedFilter; @@ -192,6 +194,11 @@ public StreamActivitiesResponse updateActivities(Bas return streamActivityRepository.updateActivities(feed, type, activities); } + @Override + public UpdateTargetResponse updateToTargets(BaseFeed feed, BaseActivity activity, Targets targets) throws StreamClientException, IOException { + return streamActivityRepository.updateToTargets(feed, activity, targets); + } + @Override public T addActivityToMany(List targetIds, T activity) throws StreamClientException, IOException { return streamActivityRepository.addToMany(targetIds, activity); diff --git a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java index 3c151849..0cde798b 100644 --- a/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java +++ b/stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java @@ -15,11 +15,13 @@ import io.getstream.client.model.activities.AggregatedActivity; import io.getstream.client.model.activities.NotificationActivity; import io.getstream.client.model.activities.SimpleActivity; +import io.getstream.client.model.activities.UpdateTargetResponse; import io.getstream.client.model.beans.FeedFollow; import io.getstream.client.model.beans.FollowMany; import io.getstream.client.model.beans.MarkedActivity; import io.getstream.client.model.beans.StreamActivitiesResponse; import io.getstream.client.model.beans.StreamResponse; +import io.getstream.client.model.beans.Targets; import io.getstream.client.model.beans.UnfollowMany; import io.getstream.client.model.feeds.Feed; import io.getstream.client.model.filters.FeedFilter; @@ -40,8 +42,7 @@ import static io.getstream.client.util.JwtAuthenticationUtil.ALL; import static junit.framework.TestCase.assertTrue; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; @@ -402,6 +403,74 @@ public void shouldUpdateActivity() throws IOException, StreamClientException { streamClient.shutdown(); } + @Test + public void shouldUpdateToTargets() throws IOException, StreamClientException { + StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, + API_SECRET); + + String user1 = this.getTestUserId("shouldChangeTo1"); + Feed feed = streamClient.newFeed("user", user1); + FlatActivityServiceImpl flatActivityService1 = feed.newFlatActivityService(SimpleActivity.class); + + SimpleActivity activityUser1 = new SimpleActivity(); + activityUser1.setForeignId("activityUser1"); + activityUser1.setActor("user1"); + activityUser1.setVerb("like"); + activityUser1.setObject("object1"); + activityUser1.setTime(new Date()); + + /* add activity 'activityUser1' */ + flatActivityService1.addActivity(activityUser1); + + + String user2 = this.getTestUserId("shouldChangeTo2"); + Feed feed2 = streamClient.newFeed("user", user2); + FlatActivityServiceImpl flatActivityService2 = feed2.newFlatActivityService(SimpleActivity.class); + + SimpleActivity activityUser2 = new SimpleActivity(); + activityUser2.setForeignId("activityUser2"); + activityUser2.setActor("user2"); + activityUser2.setVerb("like"); + activityUser2.setObject("object1"); + activityUser2.setTime(new Date()); + + /* add activity 'activityUser2' */ + flatActivityService2.addActivity(activityUser2); + + + String user3 = this.getTestUserId("shouldChangeTo2"); + Feed feed3 = streamClient.newFeed("user", user3); + FlatActivityServiceImpl flatActivityService3 = feed2.newFlatActivityService(SimpleActivity.class); + + SimpleActivity activityUser3 = new SimpleActivity(); + activityUser3.setForeignId("activityUser3"); + activityUser3.setActor("user3"); + activityUser3.setVerb("like"); + activityUser3.setObject("object1"); + activityUser3.setTime(new Date()); + activityUser3.setForeignId("user:".concat(user1)); + activityUser3.setTo(Collections.singletonList("user:".concat(user1))); // 'to' field points to 'user1' feed + + /* add activity 'activityUser3' with 'to' field pointing to feed user1 */ + flatActivityService3.addActivity(activityUser3); + + /* change the 'to' field of activity 'activityUser3' from user1 to user2 */ + /* addNewTarget(new_activity) replaces the 'to' field. It's equivalent to run addTargetToAdd(new_activity) and + * addTargetToRemove(old_activity). See the below assertions. */ + Targets toTargets = new Targets.Builder() + .addNewTarget("user:".concat(user2)) + .build(); + + /* perform the change */ + UpdateTargetResponse response = flatActivityService3.updateToTargets(activityUser3, toTargets); + + assertThat(response.getRemovedTargets(), hasItem("user:".concat(user1))); + assertThat(response.getAddedTargets(), hasItem("user:".concat(user2))); + assertThat(response.getActivity().getTo(), hasItem("user:".concat(user2))); + + streamClient.shutdown(); + } + @Test public void shouldAddActivityToMany() throws IOException, StreamClientException { StreamClient streamClient = new StreamClientImpl(CLIENT_CONFIGURATION, API_KEY, From 5841bc5bd51501c62751ffea0b991c69f99c4d51 Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 30 Oct 2018 13:52:21 +0100 Subject: [PATCH 113/320] Set project.reporting.outputEncoding to "UTF-8" --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 3049178d..7f26ffc5 100644 --- a/pom.xml +++ b/pom.xml @@ -50,6 +50,7 @@ UTF-8 + UTF-8 1.6.6 1.1.2 18.0 From b808822f4b6581702cd9ca7402dbaf94701738db Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 30 Oct 2018 14:00:58 +0100 Subject: [PATCH 114/320] [maven-release-plugin] prepare release stream-java-2.1.3 --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 7f26ffc5..64ef3042 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 2.1.3-SNAPSHOT + 2.1.3 stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - HEAD + stream-java-2.1.3 diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 04ed6a52..9dbab19b 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.3-SNAPSHOT + 2.1.3 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 820227d8..3010628c 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.3-SNAPSHOT + 2.1.3 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index 135cf452..a44165b6 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.3-SNAPSHOT + 2.1.3 4.0.0 From c4aaec87b2276a35b9813ba6dfb2173cc80b185f Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 30 Oct 2018 14:01:09 +0100 Subject: [PATCH 115/320] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- stream-core/pom.xml | 2 +- stream-repo-apache/pom.xml | 2 +- stream-repo-okhttp/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 64ef3042..dbf15999 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.getstream.client stream-java pom - 2.1.3 + 2.1.4-SNAPSHOT stream-java stream-java is a Java client for http://getstream.io. @@ -39,7 +39,7 @@ scm:git:git@github.com:GetStream/stream-java.git scm:git:git@github.com:GetStream/stream-java.git git@github.com:GetStream/stream-java.git - stream-java-2.1.3 + HEAD diff --git a/stream-core/pom.xml b/stream-core/pom.xml index 9dbab19b..3b9d0894 100644 --- a/stream-core/pom.xml +++ b/stream-core/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.3 + 2.1.4-SNAPSHOT 4.0.0 diff --git a/stream-repo-apache/pom.xml b/stream-repo-apache/pom.xml index 3010628c..9a588b97 100644 --- a/stream-repo-apache/pom.xml +++ b/stream-repo-apache/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.3 + 2.1.4-SNAPSHOT 4.0.0 diff --git a/stream-repo-okhttp/pom.xml b/stream-repo-okhttp/pom.xml index a44165b6..365b1362 100644 --- a/stream-repo-okhttp/pom.xml +++ b/stream-repo-okhttp/pom.xml @@ -3,7 +3,7 @@ stream-java io.getstream.client - 2.1.3 + 2.1.4-SNAPSHOT 4.0.0 From 309c67cd4a435fe1da760f4ab9d58625bdfe09cc Mon Sep 17 00:00:00 2001 From: Alessandro Pieri Date: Tue, 30 Oct 2018 14:07:35 +0100 Subject: [PATCH 116/320] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8bbedc09..90694696 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ If you decide to go for the *Apache HttpClient* implementation, add the followin io.getstream.client stream-repo-apache - 2.1.2 + 2.1.3 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-apache:2.1.2' +compile 'io.getstream.client:stream-repo-apache:2.1.3' ``` Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml @@ -36,14 +36,14 @@ Instead, if you opted for the *OkHttp* implementation please add it to your pom. io.getstream.client stream-repo-okhttp - 2.1.2 + 2.1.3 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:2.1.2' +compile 'io.getstream.client:stream-repo-okhttp:2.1.3' ``` In case you want to download the artifact and put it manually into your project, From 45de65e540e95f75ccf24aa834c597df52f3e376 Mon Sep 17 00:00:00 2001 From: Max Klyga <1467036+Nekuromento@users.noreply.github.com> Date: Fri, 14 Dec 2018 18:09:08 +0100 Subject: [PATCH 117/320] New client (#50) --- .gitignore | 29 +- .java-version | 1 + .travis/publish.sh | 26 - .travis/settings.xml | 9 - LICENSE => LICENCE | 25 +- README.md | 149 +-- build.gradle | 127 +++ data/test.jpg | Bin 0 -> 1362 bytes data/test.txt | 1 + example/Example.java | 628 +++++++++++++ pom.xml | 331 ------- settings.gradle | 10 + .../io/getstream/client/AggregatedFeed.java | 217 +++++ .../io/getstream/client/AnalyticsClient.java | 56 ++ .../java/io/getstream/client/BatchClient.java | 80 ++ src/main/java/io/getstream/client/Client.java | 296 ++++++ .../getstream/client/CollectionsClient.java | 139 +++ src/main/java/io/getstream/client/Feed.java | 278 ++++++ .../getstream/client/FileStorageClient.java | 37 + .../java/io/getstream/client/FlatFeed.java | 225 +++++ .../getstream/client/ImageStorageClient.java | 49 + .../io/getstream/client/NotificationFeed.java | 257 +++++ .../client/PersonalizationClient.java | 73 ++ .../io/getstream/client/ReactionsClient.java | 118 +++ src/main/java/io/getstream/client/User.java | 98 ++ .../getstream/cloud/CloudAggregatedFeed.java | 217 +++++ .../getstream/cloud/CloudAnalyticsClient.java | 32 + .../java/io/getstream/cloud/CloudClient.java | 263 ++++++ .../cloud/CloudCollectionsClient.java | 81 ++ .../java/io/getstream/cloud/CloudFeed.java | 246 +++++ .../cloud/CloudFileStorageClient.java | 31 + .../io/getstream/cloud/CloudFlatFeed.java | 225 +++++ .../cloud/CloudImageStorageClient.java | 41 + .../cloud/CloudNotificationFeed.java | 257 +++++ .../getstream/cloud/CloudReactionsClient.java | 109 +++ .../java/io/getstream/cloud/CloudUser.java | 98 ++ .../java/io/getstream/core/KeepHistory.java | 16 + .../java/io/getstream/core/LookupKind.java | 18 + src/main/java/io/getstream/core/Region.java | 20 + src/main/java/io/getstream/core/Stream.java | 369 ++++++++ .../io/getstream/core/StreamAnalytics.java | 93 ++ .../java/io/getstream/core/StreamBatch.java | 183 ++++ .../io/getstream/core/StreamCollections.java | 226 +++++ .../java/io/getstream/core/StreamFiles.java | 90 ++ .../java/io/getstream/core/StreamImages.java | 108 +++ .../getstream/core/StreamPersonalization.java | 108 +++ .../io/getstream/core/StreamReactions.java | 182 ++++ .../core/exceptions/StreamAPIException.java | 60 ++ .../core/exceptions/StreamException.java | 23 + .../io/getstream/core/http/HTTPClient.java | 12 + .../core/http/OKHTTPClientAdapter.java | 114 +++ .../java/io/getstream/core/http/Request.java | 157 ++++ .../io/getstream/core/http/RequestBody.java | 93 ++ .../java/io/getstream/core/http/Response.java | 49 + .../java/io/getstream/core/http/Token.java | 35 + .../io/getstream/core/models/Activity.java | 265 ++++++ .../getstream/core/models/CollectionData.java | 105 +++ .../io/getstream/core/models/Content.java | 86 ++ .../java/io/getstream/core/models/Data.java | 90 ++ .../io/getstream/core/models/Engagement.java | 210 +++++ .../core/models/EnrichedActivity.java | 333 +++++++ .../io/getstream/core/models/Feature.java | 48 + .../java/io/getstream/core/models/FeedID.java | 62 ++ .../getstream/core/models/FollowRelation.java | 55 ++ .../core/models/ForeignIDTimePair.java | 46 + .../java/io/getstream/core/models/Group.java | 93 ++ .../io/getstream/core/models/Impression.java | 193 ++++ .../core/models/NotificationGroup.java | 76 ++ .../java/io/getstream/core/models/OGData.java | 268 ++++++ .../io/getstream/core/models/ProfileData.java | 95 ++ .../io/getstream/core/models/Reaction.java | 263 ++++++ .../io/getstream/core/models/UserData.java | 45 + .../serialization/DataDeserializer.java | 41 + .../core/options/ActivityMarker.java | 63 ++ .../java/io/getstream/core/options/Crop.java | 70 ++ .../core/options/CustomQueryParameter.java | 33 + .../core/options/EnrichmentFlags.java | 85 ++ .../io/getstream/core/options/Filter.java | 74 ++ .../getstream/core/options/KeepHistory.java | 20 + .../io/getstream/core/options/Pagination.java | 57 ++ .../io/getstream/core/options/Ranking.java | 25 + .../getstream/core/options/RequestOption.java | 7 + .../io/getstream/core/options/Resize.java | 63 ++ .../java/io/getstream/core/utils/Auth.java | 137 +++ .../getstream/core/utils/DefaultOptions.java | 16 + .../io/getstream/core/utils/Enrichment.java | 11 + .../java/io/getstream/core/utils/Info.java | 23 + .../java/io/getstream/core/utils/Request.java | 48 + .../java/io/getstream/core/utils/Routes.java | 116 +++ .../getstream/core/utils/Serialization.java | 136 +++ src/main/resources/stream-java2.info | 3 + .../getstream/client/AggregatedFeedTest.java | 91 ++ .../getstream/client/AnalyticsClientTest.java | 88 ++ .../io/getstream/client/BatchClientTest.java | 102 ++ .../java/io/getstream/client/ClientTest.java | 133 +++ .../client/CollectionsClientTest.java | 246 +++++ .../java/io/getstream/client/FeedTest.java | 199 ++++ .../client/FileStorageClientTest.java | 52 + .../io/getstream/client/FlatFeedTest.java | 109 +++ .../client/ImageStorageClientTest.java | 96 ++ .../client/NotificationFeedTest.java | 43 + src/test/java/io/getstream/client/OGTest.java | 24 + .../client/PersonalizationClientTest.java | 63 ++ .../getstream/client/ReactionsClientTest.java | 104 ++ .../java/io/getstream/client/UserTest.java | 129 +++ .../client/entities/FootballMatch.java | 43 + .../io/getstream/client/entities/Match.java | 37 + .../client/entities/VolleyballMatch.java | 43 + .../core/http/OKHTTPClientAdapterTest.java | 66 ++ .../core/utils/ActivityGenerator.java | 83 ++ .../io/getstream/core/utils/InfoTest.java | 12 + .../utils/SerializationPropertiesTest.java | 26 + .../core/utils/SerializationTest.java | 229 +++++ stream-core/pom.xml | 73 -- .../io/getstream/client/StreamClient.java | 48 - .../AuthenticationHandlerConfiguration.java | 34 - .../client/config/ClientConfiguration.java | 174 ---- .../getstream/client/config/StreamRegion.java | 37 - .../AuthenticationFailedException.java | 27 - .../exception/InternalServerException.java | 26 - .../exception/InvalidFeedNameException.java | 27 - .../InvalidOrMissingInputException.java | 27 - .../exception/RateLimitExceededException.java | 27 - .../exception/ResourceNotFoundException.java | 27 - .../exception/StreamClientException.java | 75 -- .../client/exception/UriBuilderException.java | 26 - .../ActivitySignedRecipientDeserializer.java | 48 - .../model/activities/AggregatedActivity.java | 4 - .../client/model/activities/BaseActivity.java | 150 --- .../activities/NotificationActivity.java | 29 - .../activities/PersonalizedActivity.java | 33 - .../model/activities/SimpleActivity.java | 8 - .../activities/UpdateTargetResponse.java | 80 -- .../model/activities/WrappedActivity.java | 87 -- .../getstream/client/model/beans/AddMany.java | 38 - .../client/model/beans/FeedFollow.java | 59 -- .../client/model/beans/FollowMany.java | 82 -- .../client/model/beans/FollowRequest.java | 36 - .../client/model/beans/MarkedActivity.java | 61 -- .../client/model/beans/MetaResponse.java | 40 - .../model/beans/StreamActivitiesResponse.java | 22 - .../model/beans/StreamErrorResponse.java | 51 - .../client/model/beans/StreamResponse.java | 56 -- .../getstream/client/model/beans/Targets.java | 126 --- .../client/model/beans/UnfollowMany.java | 111 --- .../client/model/beans/UpdateTo.java | 49 - .../client/model/feeds/BaseFeed.java | 161 ---- .../client/model/feeds/BaseFeedFactory.java | 51 - .../io/getstream/client/model/feeds/Feed.java | 210 ----- .../client/model/feeds/FeedFactory.java | 39 - .../client/model/feeds/PersonalizedFeed.java | 64 -- .../model/feeds/PersonalizedFeedImpl.java | 50 - .../client/model/filters/FeedFilter.java | 135 --- .../repo/StreamPersonalizedRepository.java | 55 -- .../client/repo/StreamRepoFactory.java | 22 - .../client/repo/StreamRepository.java | 263 ------ .../service/AbstractActivityService.java | 97 -- .../service/AggregatedActivityService.java | 36 - .../AggregatedActivityServiceImpl.java | 34 - .../client/service/FlatActivityService.java | 35 - .../service/FlatActivityServiceImpl.java | 33 - .../service/NotificationActivityService.java | 53 -- .../NotificationActivityServiceImpl.java | 40 - .../client/service/UserActivityService.java | 35 - .../service/UserActivityServiceImpl.java | 35 - .../client/util/DateDeserializer.java | 45 - .../getstream/client/util/EndpointUtil.java | 58 -- .../client/util/HttpSignatureHandler.java | 51 - .../io/getstream/client/util/InfoUtil.java | 34 - .../client/util/JwtAuthenticationUtil.java | 81 -- .../util/PersonalizedDateDeserializer.java | 45 - .../client/config/StreamRegionTest.java | 14 - .../client/model/beans/TargetsTest.java | 39 - .../client/model/filters/FeedFilterTest.java | 64 -- .../AggregatedActivityServiceImplTest.java | 59 -- .../service/FlatActivityServiceImplTest.java | 58 -- .../NotificationActivityServiceImplTest.java | 71 -- .../service/UserActivityServiceImplTest.java | 58 -- .../client/util/DateDeserializerTest.java | 47 - .../client/util/EndpointUtilTest.java | 57 -- .../getstream/client/util/InfoUtilTest.java | 16 - .../util/JwtAuthenticationUtilTest.java | 95 -- .../src/test/resources/stream-java.info | 1 - stream-repo-apache/pom.xml | 94 -- .../client/apache/StreamClientImpl.java | 145 --- .../apache/repo/HttpSignatureInterceptor.java | 44 - .../apache/repo/StreamActivityRepository.java | 270 ------ .../StreamPersonalizedRepositoryImpl.java | 133 --- .../apache/repo/StreamRepositoryImpl.java | 253 ----- .../repo/handlers/StreamExceptionHandler.java | 87 -- .../apache/repo/utils/FeedFilterUtils.java | 52 - .../apache/repo/utils/SignatureUtils.java | 76 -- .../apache/repo/utils/StreamRepoUtils.java | 89 -- .../client/apache/repo/utils/UriBuilder.java | 119 --- .../src/main/resources/stream-java.info | 3 - .../client/apache/IntegrationTest.java | 849 ----------------- .../apache/PersonalizedIntegrationTest.java | 151 --- .../client/apache/StreamClientImplTest.java | 50 - .../client/apache/example/follow/Follow.java | 63 -- .../apache/example/helloworld/HelloWorld.java | 65 -- .../apache/example/mixtype/MixedType.java | 135 --- ...tivitySignedRecipientDeserializerTest.java | 37 - .../StreamPersonalizedRepositoryImplTest.java | 159 ---- .../apache/repo/StreamRepositoryImplTest.java | 86 -- .../handlers/StreamExceptionHandlerTest.java | 92 -- .../repo/utils/StreamRepoUtilsTest.java | 63 -- .../client/apache/utils/UriBuilderTest.java | 34 - stream-repo-okhttp/pom.xml | 95 -- .../client/okhttp/StreamClientImpl.java | 146 --- .../okhttp/repo/HttpSignatureinterceptor.java | 44 - .../okhttp/repo/StreamActivityRepository.java | 293 ------ .../StreamPersonalizedRepositoryImpl.java | 133 --- .../okhttp/repo/StreamRepositoryImpl.java | 256 ----- .../repo/handlers/StreamExceptionHandler.java | 81 -- .../client/okhttp/repo/utils/Base64.java | 742 --------------- .../okhttp/repo/utils/FeedFilterUtils.java | 52 - .../okhttp/repo/utils/SignatureUtils.java | 74 -- .../okhttp/repo/utils/StreamRepoUtils.java | 74 -- .../client/okhttp/repo/utils/UriBuilder.java | 149 --- .../src/main/resources/stream-java.info | 3 - .../client/okhttp/IntegrationTest.java | 888 ------------------ .../okhttp/PersonalizedIntegrationTest.java | 139 --- .../client/okhttp/StreamClientImplTest.java | 38 - .../StreamPersonalizedRepositoryImplTest.java | 160 ---- .../handlers/StreamExceptionHandlerTest.java | 120 --- .../okhttp/repo/utils/InfoUtilTest.java | 17 - .../repo/utils/StreamRepoUtilsTest.java | 55 -- .../okhttp/repo/utils/UriBuilderTest.java | 33 - 228 files changed, 11651 insertions(+), 11423 deletions(-) create mode 100644 .java-version delete mode 100755 .travis/publish.sh delete mode 100644 .travis/settings.xml rename LICENSE => LICENCE (59%) create mode 100644 build.gradle create mode 100644 data/test.jpg create mode 100644 data/test.txt create mode 100644 example/Example.java delete mode 100644 pom.xml create mode 100644 settings.gradle create mode 100644 src/main/java/io/getstream/client/AggregatedFeed.java create mode 100644 src/main/java/io/getstream/client/AnalyticsClient.java create mode 100644 src/main/java/io/getstream/client/BatchClient.java create mode 100644 src/main/java/io/getstream/client/Client.java create mode 100644 src/main/java/io/getstream/client/CollectionsClient.java create mode 100644 src/main/java/io/getstream/client/Feed.java create mode 100644 src/main/java/io/getstream/client/FileStorageClient.java create mode 100644 src/main/java/io/getstream/client/FlatFeed.java create mode 100644 src/main/java/io/getstream/client/ImageStorageClient.java create mode 100644 src/main/java/io/getstream/client/NotificationFeed.java create mode 100644 src/main/java/io/getstream/client/PersonalizationClient.java create mode 100644 src/main/java/io/getstream/client/ReactionsClient.java create mode 100644 src/main/java/io/getstream/client/User.java create mode 100644 src/main/java/io/getstream/cloud/CloudAggregatedFeed.java create mode 100644 src/main/java/io/getstream/cloud/CloudAnalyticsClient.java create mode 100644 src/main/java/io/getstream/cloud/CloudClient.java create mode 100644 src/main/java/io/getstream/cloud/CloudCollectionsClient.java create mode 100644 src/main/java/io/getstream/cloud/CloudFeed.java create mode 100644 src/main/java/io/getstream/cloud/CloudFileStorageClient.java create mode 100644 src/main/java/io/getstream/cloud/CloudFlatFeed.java create mode 100644 src/main/java/io/getstream/cloud/CloudImageStorageClient.java create mode 100644 src/main/java/io/getstream/cloud/CloudNotificationFeed.java create mode 100644 src/main/java/io/getstream/cloud/CloudReactionsClient.java create mode 100644 src/main/java/io/getstream/cloud/CloudUser.java create mode 100644 src/main/java/io/getstream/core/KeepHistory.java create mode 100644 src/main/java/io/getstream/core/LookupKind.java create mode 100644 src/main/java/io/getstream/core/Region.java create mode 100644 src/main/java/io/getstream/core/Stream.java create mode 100644 src/main/java/io/getstream/core/StreamAnalytics.java create mode 100644 src/main/java/io/getstream/core/StreamBatch.java create mode 100644 src/main/java/io/getstream/core/StreamCollections.java create mode 100644 src/main/java/io/getstream/core/StreamFiles.java create mode 100644 src/main/java/io/getstream/core/StreamImages.java create mode 100644 src/main/java/io/getstream/core/StreamPersonalization.java create mode 100644 src/main/java/io/getstream/core/StreamReactions.java create mode 100644 src/main/java/io/getstream/core/exceptions/StreamAPIException.java create mode 100644 src/main/java/io/getstream/core/exceptions/StreamException.java create mode 100644 src/main/java/io/getstream/core/http/HTTPClient.java create mode 100644 src/main/java/io/getstream/core/http/OKHTTPClientAdapter.java create mode 100644 src/main/java/io/getstream/core/http/Request.java create mode 100644 src/main/java/io/getstream/core/http/RequestBody.java create mode 100644 src/main/java/io/getstream/core/http/Response.java create mode 100644 src/main/java/io/getstream/core/http/Token.java create mode 100644 src/main/java/io/getstream/core/models/Activity.java create mode 100644 src/main/java/io/getstream/core/models/CollectionData.java create mode 100644 src/main/java/io/getstream/core/models/Content.java create mode 100644 src/main/java/io/getstream/core/models/Data.java create mode 100644 src/main/java/io/getstream/core/models/Engagement.java create mode 100644 src/main/java/io/getstream/core/models/EnrichedActivity.java create mode 100644 src/main/java/io/getstream/core/models/Feature.java create mode 100644 src/main/java/io/getstream/core/models/FeedID.java create mode 100644 src/main/java/io/getstream/core/models/FollowRelation.java create mode 100644 src/main/java/io/getstream/core/models/ForeignIDTimePair.java create mode 100644 src/main/java/io/getstream/core/models/Group.java create mode 100644 src/main/java/io/getstream/core/models/Impression.java create mode 100644 src/main/java/io/getstream/core/models/NotificationGroup.java create mode 100644 src/main/java/io/getstream/core/models/OGData.java create mode 100644 src/main/java/io/getstream/core/models/ProfileData.java create mode 100644 src/main/java/io/getstream/core/models/Reaction.java create mode 100644 src/main/java/io/getstream/core/models/UserData.java create mode 100644 src/main/java/io/getstream/core/models/serialization/DataDeserializer.java create mode 100644 src/main/java/io/getstream/core/options/ActivityMarker.java create mode 100644 src/main/java/io/getstream/core/options/Crop.java create mode 100644 src/main/java/io/getstream/core/options/CustomQueryParameter.java create mode 100644 src/main/java/io/getstream/core/options/EnrichmentFlags.java create mode 100644 src/main/java/io/getstream/core/options/Filter.java create mode 100644 src/main/java/io/getstream/core/options/KeepHistory.java create mode 100644 src/main/java/io/getstream/core/options/Pagination.java create mode 100644 src/main/java/io/getstream/core/options/Ranking.java create mode 100644 src/main/java/io/getstream/core/options/RequestOption.java create mode 100644 src/main/java/io/getstream/core/options/Resize.java create mode 100644 src/main/java/io/getstream/core/utils/Auth.java create mode 100644 src/main/java/io/getstream/core/utils/DefaultOptions.java create mode 100644 src/main/java/io/getstream/core/utils/Enrichment.java create mode 100644 src/main/java/io/getstream/core/utils/Info.java create mode 100644 src/main/java/io/getstream/core/utils/Request.java create mode 100644 src/main/java/io/getstream/core/utils/Routes.java create mode 100644 src/main/java/io/getstream/core/utils/Serialization.java create mode 100644 src/main/resources/stream-java2.info create mode 100644 src/test/java/io/getstream/client/AggregatedFeedTest.java create mode 100644 src/test/java/io/getstream/client/AnalyticsClientTest.java create mode 100644 src/test/java/io/getstream/client/BatchClientTest.java create mode 100644 src/test/java/io/getstream/client/ClientTest.java create mode 100644 src/test/java/io/getstream/client/CollectionsClientTest.java create mode 100644 src/test/java/io/getstream/client/FeedTest.java create mode 100644 src/test/java/io/getstream/client/FileStorageClientTest.java create mode 100644 src/test/java/io/getstream/client/FlatFeedTest.java create mode 100644 src/test/java/io/getstream/client/ImageStorageClientTest.java create mode 100644 src/test/java/io/getstream/client/NotificationFeedTest.java create mode 100644 src/test/java/io/getstream/client/OGTest.java create mode 100644 src/test/java/io/getstream/client/PersonalizationClientTest.java create mode 100644 src/test/java/io/getstream/client/ReactionsClientTest.java create mode 100644 src/test/java/io/getstream/client/UserTest.java create mode 100644 src/test/java/io/getstream/client/entities/FootballMatch.java create mode 100644 src/test/java/io/getstream/client/entities/Match.java create mode 100644 src/test/java/io/getstream/client/entities/VolleyballMatch.java create mode 100644 src/test/java/io/getstream/core/http/OKHTTPClientAdapterTest.java create mode 100644 src/test/java/io/getstream/core/utils/ActivityGenerator.java create mode 100644 src/test/java/io/getstream/core/utils/InfoTest.java create mode 100644 src/test/java/io/getstream/core/utils/SerializationPropertiesTest.java create mode 100644 src/test/java/io/getstream/core/utils/SerializationTest.java delete mode 100644 stream-core/pom.xml delete mode 100644 stream-core/src/main/java/io/getstream/client/StreamClient.java delete mode 100644 stream-core/src/main/java/io/getstream/client/config/AuthenticationHandlerConfiguration.java delete mode 100644 stream-core/src/main/java/io/getstream/client/config/ClientConfiguration.java delete mode 100644 stream-core/src/main/java/io/getstream/client/config/StreamRegion.java delete mode 100644 stream-core/src/main/java/io/getstream/client/exception/AuthenticationFailedException.java delete mode 100644 stream-core/src/main/java/io/getstream/client/exception/InternalServerException.java delete mode 100644 stream-core/src/main/java/io/getstream/client/exception/InvalidFeedNameException.java delete mode 100644 stream-core/src/main/java/io/getstream/client/exception/InvalidOrMissingInputException.java delete mode 100644 stream-core/src/main/java/io/getstream/client/exception/RateLimitExceededException.java delete mode 100644 stream-core/src/main/java/io/getstream/client/exception/ResourceNotFoundException.java delete mode 100644 stream-core/src/main/java/io/getstream/client/exception/StreamClientException.java delete mode 100644 stream-core/src/main/java/io/getstream/client/exception/UriBuilderException.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/activities/ActivitySignedRecipientDeserializer.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/activities/AggregatedActivity.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/activities/BaseActivity.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/activities/NotificationActivity.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/activities/PersonalizedActivity.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/activities/SimpleActivity.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/activities/UpdateTargetResponse.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/activities/WrappedActivity.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/AddMany.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/FeedFollow.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/FollowMany.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/FollowRequest.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/MarkedActivity.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/MetaResponse.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/StreamActivitiesResponse.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/StreamErrorResponse.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/StreamResponse.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/Targets.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/UnfollowMany.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/beans/UpdateTo.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeed.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/feeds/BaseFeedFactory.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/feeds/Feed.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/feeds/FeedFactory.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeed.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/feeds/PersonalizedFeedImpl.java delete mode 100644 stream-core/src/main/java/io/getstream/client/model/filters/FeedFilter.java delete mode 100644 stream-core/src/main/java/io/getstream/client/repo/StreamPersonalizedRepository.java delete mode 100644 stream-core/src/main/java/io/getstream/client/repo/StreamRepoFactory.java delete mode 100644 stream-core/src/main/java/io/getstream/client/repo/StreamRepository.java delete mode 100644 stream-core/src/main/java/io/getstream/client/service/AbstractActivityService.java delete mode 100644 stream-core/src/main/java/io/getstream/client/service/AggregatedActivityService.java delete mode 100644 stream-core/src/main/java/io/getstream/client/service/AggregatedActivityServiceImpl.java delete mode 100644 stream-core/src/main/java/io/getstream/client/service/FlatActivityService.java delete mode 100644 stream-core/src/main/java/io/getstream/client/service/FlatActivityServiceImpl.java delete mode 100644 stream-core/src/main/java/io/getstream/client/service/NotificationActivityService.java delete mode 100644 stream-core/src/main/java/io/getstream/client/service/NotificationActivityServiceImpl.java delete mode 100644 stream-core/src/main/java/io/getstream/client/service/UserActivityService.java delete mode 100644 stream-core/src/main/java/io/getstream/client/service/UserActivityServiceImpl.java delete mode 100644 stream-core/src/main/java/io/getstream/client/util/DateDeserializer.java delete mode 100644 stream-core/src/main/java/io/getstream/client/util/EndpointUtil.java delete mode 100644 stream-core/src/main/java/io/getstream/client/util/HttpSignatureHandler.java delete mode 100644 stream-core/src/main/java/io/getstream/client/util/InfoUtil.java delete mode 100644 stream-core/src/main/java/io/getstream/client/util/JwtAuthenticationUtil.java delete mode 100644 stream-core/src/main/java/io/getstream/client/util/PersonalizedDateDeserializer.java delete mode 100644 stream-core/src/test/java/io/getstream/client/config/StreamRegionTest.java delete mode 100644 stream-core/src/test/java/io/getstream/client/model/beans/TargetsTest.java delete mode 100644 stream-core/src/test/java/io/getstream/client/model/filters/FeedFilterTest.java delete mode 100644 stream-core/src/test/java/io/getstream/client/service/AggregatedActivityServiceImplTest.java delete mode 100644 stream-core/src/test/java/io/getstream/client/service/FlatActivityServiceImplTest.java delete mode 100644 stream-core/src/test/java/io/getstream/client/service/NotificationActivityServiceImplTest.java delete mode 100644 stream-core/src/test/java/io/getstream/client/service/UserActivityServiceImplTest.java delete mode 100644 stream-core/src/test/java/io/getstream/client/util/DateDeserializerTest.java delete mode 100644 stream-core/src/test/java/io/getstream/client/util/EndpointUtilTest.java delete mode 100644 stream-core/src/test/java/io/getstream/client/util/InfoUtilTest.java delete mode 100644 stream-core/src/test/java/io/getstream/client/util/JwtAuthenticationUtilTest.java delete mode 100644 stream-core/src/test/resources/stream-java.info delete mode 100644 stream-repo-apache/pom.xml delete mode 100644 stream-repo-apache/src/main/java/io/getstream/client/apache/StreamClientImpl.java delete mode 100644 stream-repo-apache/src/main/java/io/getstream/client/apache/repo/HttpSignatureInterceptor.java delete mode 100644 stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamActivityRepository.java delete mode 100644 stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImpl.java delete mode 100644 stream-repo-apache/src/main/java/io/getstream/client/apache/repo/StreamRepositoryImpl.java delete mode 100644 stream-repo-apache/src/main/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandler.java delete mode 100644 stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/FeedFilterUtils.java delete mode 100644 stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/SignatureUtils.java delete mode 100644 stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/StreamRepoUtils.java delete mode 100644 stream-repo-apache/src/main/java/io/getstream/client/apache/repo/utils/UriBuilder.java delete mode 100644 stream-repo-apache/src/main/resources/stream-java.info delete mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/IntegrationTest.java delete mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/PersonalizedIntegrationTest.java delete mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/StreamClientImplTest.java delete mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/example/follow/Follow.java delete mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/example/helloworld/HelloWorld.java delete mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/example/mixtype/MixedType.java delete mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/model/activities/ActivitySignedRecipientDeserializerTest.java delete mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamPersonalizedRepositoryImplTest.java delete mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/repo/StreamRepositoryImplTest.java delete mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/repo/handlers/StreamExceptionHandlerTest.java delete mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/repo/utils/StreamRepoUtilsTest.java delete mode 100644 stream-repo-apache/src/test/java/io/getstream/client/apache/utils/UriBuilderTest.java delete mode 100644 stream-repo-okhttp/pom.xml delete mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/StreamClientImpl.java delete mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/HttpSignatureinterceptor.java delete mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamActivityRepository.java delete mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImpl.java delete mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/StreamRepositoryImpl.java delete mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandler.java delete mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/Base64.java delete mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/FeedFilterUtils.java delete mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/SignatureUtils.java delete mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtils.java delete mode 100644 stream-repo-okhttp/src/main/java/io/getstream/client/okhttp/repo/utils/UriBuilder.java delete mode 100644 stream-repo-okhttp/src/main/resources/stream-java.info delete mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/IntegrationTest.java delete mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/PersonalizedIntegrationTest.java delete mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/StreamClientImplTest.java delete mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/StreamPersonalizedRepositoryImplTest.java delete mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/handlers/StreamExceptionHandlerTest.java delete mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/InfoUtilTest.java delete mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/StreamRepoUtilsTest.java delete mode 100644 stream-repo-okhttp/src/test/java/io/getstream/client/okhttp/repo/utils/UriBuilderTest.java diff --git a/.gitignore b/.gitignore index cd968238..92715af9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,14 @@ *.class -.idea -*.iml - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # *.jar *.war *.ear - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -# Maven +.gradle/ +.idea/ +.syntastic_javac_config +build/ +gradle.properties +gradle/ +gradlew +gradlew.bat +out/ target/ -pom.xml.tag -pom.xml.releaseBackup -pom.xml.versionsBackup -pom.xml.next -release.properties -dependency-reduced-pom.xml -buildNumber.properties -.mvn/timing.properties diff --git a/.java-version b/.java-version new file mode 100644 index 00000000..ba6a626d --- /dev/null +++ b/.java-version @@ -0,0 +1 @@ +oracle64-10.0.2 diff --git a/.travis/publish.sh b/.travis/publish.sh deleted file mode 100755 index 6f5021e6..00000000 --- a/.travis/publish.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -# -# Deploy a jar, source jar, and javadoc jar to Sonatype's snapshot repo. -# -# Adapted from https://coderwall.com/p/9b_lfq and -# http://benlimmer.com/2013/12/26/automatically-publish-javadoc-to-gh-pages-with-travis-ci/ - -SLUG="GetStream/stream-java" -JDK="oraclejdk8" -BRANCH="master" - -set -e - -if [ "$TRAVIS_REPO_SLUG" != "$SLUG" ]; then - echo "Skipping snapshot deployment: wrong repository. Expected '$SLUG' but was '$TRAVIS_REPO_SLUG'." -elif [ "$TRAVIS_JDK_VERSION" != "$JDK" ]; then - echo "Skipping snapshot deployment: wrong JDK. Expected '$JDK' but was '$TRAVIS_JDK_VERSION'." -elif [ "$TRAVIS_PULL_REQUEST" != "false" ]; then - echo "Skipping snapshot deployment: was pull request." -elif [ "$TRAVIS_BRANCH" != "$BRANCH" ]; then - echo "Skipping snapshot deployment: wrong branch. Expected '$BRANCH' but was '$TRAVIS_BRANCH'." -else - echo "Deploying snapshot..." - mvn clean deploy --settings=".travis/settings.xml" -Dmaven.test.skip=true - echo "Snapshot deployed!" -fi \ No newline at end of file diff --git a/.travis/settings.xml b/.travis/settings.xml deleted file mode 100644 index de371552..00000000 --- a/.travis/settings.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - ossrh - ${env.CI_DEPLOY_USERNAME} - ${env.CI_DEPLOY_PASSWORD} - - - \ No newline at end of file diff --git a/LICENSE b/LICENCE similarity index 59% rename from LICENSE rename to LICENCE index 8a25cc4d..c59b050e 100644 --- a/LICENSE +++ b/LICENCE @@ -1,4 +1,4 @@ -Copyright (c) 2016-2017 Stream.io Inc, and individual contributors. +Copyright (c) 2016-2018 Stream.io Inc, and individual contributors. All rights reserved. @@ -24,25 +24,4 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -This software incorporates additional Open Source components. You can find the source code of these -open source projects along with license information below. - - Base64.java: - - https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/Base64.java - - Copyright (C) 2010 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/README.md b/README.md index 90694696..e49391e5 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,25 @@ stream-java =========== -[![Build Status](https://travis-ci.org/GetStream/stream-java.svg?branch=master)](https://travis-ci.org/GetStream/stream-java) - [stream-java](https://github.com/GetStream/stream-java) is a Java client for [Stream](https://getstream.io/). You can sign up for a Stream account at https://getstream.io/get_started. -The Stream's Java client come in two different flavours, you should decide which one to drag into your project. -Those two implementations differ according to the underlying library used to handle HTTP connections: - -- *stream-repo-apache* uses Apache HttpClient and we recommend it for backend applications. Apache HttpClient is a mature, reliable and rock-solid HTTP library. -- *stream-repo-okhttp* uses Square's OkHttp which is lightweight, powerful and mobile-oriented HTTP library. We recommend it for mobile application. - ### Installation -If you decide to go for the *Apache HttpClient* implementation, add the following dependency to your pom.xml: - -```xml - - io.getstream.client - stream-repo-apache - 2.1.3 - -``` - -or in your build.gradle: - -```gradle -compile 'io.getstream.client:stream-repo-apache:2.1.3' -``` - -Instead, if you opted for the *OkHttp* implementation please add it to your pom.xml +Add the following dependency to your pom.xml: ```xml io.getstream.client - stream-repo-okhttp - 2.1.3 + stream-java + 3.0.0 ``` or in your build.gradle: ```gradle -compile 'io.getstream.client:stream-repo-okhttp:2.1.3' +compile 'io.getstream.client:stream-java:3.0.0' ``` In case you want to download the artifact and put it manually into your project, @@ -55,127 +31,32 @@ Snapshots of the development version are available in [Sonatype](https://oss.son This API Client project requires Java SE 8. -See the [Travis configuration](.travis.yml) for details of how it is built, tested and packaged. - ### Full documentation Documentation for this Java client are available at the [Stream website](https://getstream.io/docs/?language=java). -### Usage - -```java -/** - * Instantiate a new client to connect to us east API endpoint - * Find your API keys here https://getstream.io/dashboard/ - **/ - -StreamClient streamClient = new StreamClientImpl(new ClientConfiguration(), "", ""); -``` - -#### Create a new Feed - -```java -/* Instantiate a feed object */ -Feed feed = streamClient.newFeed("user", "1"); -``` - -#### Working with Activities - -```java -/* Create an activity service */ -FlatActivityServiceImpl flatActivityService = feed.newFlatActivityService(SimpleActivity.class); - -/* Get activities from 5 to 10 (using offset pagination) */ -FeedFilter filter = new FeedFilter.Builder().withLimit(5).withOffset(5).build(); -List activities = flatActivityService.getActivities(filter).getResults(); - -/* Filter on an id less than the given UUID */ -aid = "e561de8f-00f1-11e4-b400-0cc47a024be0"; -FeedFilter filter = new FeedFilter.Builder().withIdLowerThan(aid).withLimit(5).build(); -List activities = flatActivityService.getActivities(filter).getResults(); +For examples have a look [here](https://github.com/GetStream/stream-java/tree/master/example/Example.java). -/* Create a new activity */ -SimpleActivity activity = new SimpleActivity(); -activity.setActor("user:1"); -activity.setObject("tweet:1"); -activity.setVerb("tweet"); -activity.setForeignId("tweet:1"); -SimpleActivity response = flatActivityService.addActivity(activity); - -/* Remove an activity by its id */ -feed.deleteActivity("e561de8f-00f1-11e4-b400-0cc47a024be0"); - -/* Remove activities by their foreign_id */ -feed.deleteActivityByForeignId("tweet:1"); -``` - -In case you want to add a single activity to multiple feeds, you can use the batch feature _addToMany_: - -```java -/* Batch adding activities to many feeds */ -flatActivityService.addActivityToMany(ImmutableList.of("user:1", "user:2").asList(), myActivity); -``` - -The API client allows you to send activities with custom field as well, you can find a -complete example [here](https://github.com/GetStream/stream-java/blob/master/stream-repo-apache/src/test/java/io/getstream/client/example/mixtype/MixedType.java) - -#### Follow and Unfollow - -```java -/* Follow another feed */ -feed.follow(flat", "42"); - -/* Stop following another feed */ -feed.unfollow(flat", "42"); - -/* Retrieve first 10 followers of a feed */ -FeedFilter filter = new FeedFilter.Builder().withLimit(10).build(); -List followingPaged = feed.getFollowing(filter); - -/* Retrieve the first 10 followed feeds */ -FeedFilter filter = new FeedFilter.Builder().withLimit(10).build(); -List followingPaged = feed.getFollowing(filter); -``` - -In case you want to send to Stream a long list of following relationships you can use the batch feature _followMany_: - -```java -/* Batch following many feeds */ -FollowMany followMany = new FollowMany.Builder() - .add("user:1", "user:2") - .add("user:1", "user:3") - .add("user:1", "user:4") - .add("user:2", "user:3") - .build(); -feed.followMany(followMany); - -``` - -#### Client token - -In order to generate a token for client side usage (e.g. JS client), you can use the following code: - -```java -/* Generating tokens for client side usage */ -String token = feed.getToken(); -``` +Docs are available on [GetStream.io](http://getstream.io/docs/). -#### Further references +Javadocs are available [here](https://getstream.github.io/stream-java/). -For more examples have a look [here](https://github.com/GetStream/stream-java/tree/master/stream-repo-apache/src/test/java/io/getstream/client/apache/example). +### Building & Testing -Docs are available on [GetStream.io](http://getstream.io/docs/). +Run `gradle wrapper --gradle-version 5.0` to generate gradle wrapper files -Javadocs are available [here](https://getstream.github.io/stream-java/). +Run `gradle test` to execute integration tests ### Credits & Contributors -This project was originally contributed by [Alessandro Pieri](sirio7g), prior to him joining Stream as an employee. +Project is maintained by [Max Klyga](nekuromento). + +This project was originally contributed by [Alessandro Pieri](sirio7g). We continue to welcome pull requests from community members. ### Copyright and License Information -Copyright (c) 2016-2017 Stream.io Inc, and individual contributors. All rights reserved. +Copyright (c) 2016-2018 Stream.io Inc, and individual contributors. All rights reserved. -See the file "LICENSE" for information on the history of this software, terms & conditions for usage, and a DISCLAIMER OF ALL WARRANTIES. +See the file "LICENSE" for information on the history of this software, terms & conditions for usage, and a DISCLAIMER OF ALL WARRANTIES. \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..d3573920 --- /dev/null +++ b/build.gradle @@ -0,0 +1,127 @@ +plugins { + id 'java-library' + id 'eclipse' + id 'idea' + id 'maven-publish' + id 'signing' + id "com.scuilion.syntastic" version "0.3.8" + id "com.prot.versioninfo" version "0.5" +} + +group 'io.getstream.client' +version = '3.0.0' + +dependencies { + testCompile 'org.junit.jupiter:junit-jupiter-api:5.3.1' + testCompile 'org.junit.jupiter:junit-jupiter-params:5.3.1' + testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.3.1' + testRuntime 'org.junit.vintage:junit-vintage-engine:5.3.1' + testCompile 'com.pholser:junit-quickcheck-core:0.8.1' + testCompile 'com.pholser:junit-quickcheck-generators:0.8.1' + + implementation 'com.google.guava:guava:26.0-jre' + + implementation 'com.squareup.okhttp3:okhttp:3.11.0' + + compile 'com.fasterxml.jackson.core:jackson-core:2.9.6' + compile 'com.fasterxml.jackson.core:jackson-annotations:2.9.6' + compile 'com.fasterxml.jackson.core:jackson-databind:2.9.6' + + compile 'com.auth0:java-jwt:3.4.0' +} + +compileJava { + sourceCompatibility = 1.8 + targetCompatibility = 1.8 +} + +test { + useJUnitPlatform { + includeEngines 'junit-jupiter', 'junit-vintage' + } + testLogging { + exceptionFormat = 'full' + events 'standard_out', 'standard_error', "passed", "skipped", "failed" + } +} + +repositories { + jcenter() +} + +processResources { + filesMatching('stream-java2.info') { + expand(project.properties) + } +} + +task sourcesJar(type: Jar) { + from sourceSets.main.allJava + classifier = 'sources' +} + +task javadocJar(type: Jar) { + from javadoc + classifier = 'javadoc' +} + +publishing { + publications { + mavenJava(MavenPublication) { + artifactId = 'stream-java' + from components.java + artifact sourcesJar + artifact javadocJar + + pom { + name = 'client' + description = 'Stream API official client' + url = 'https://github.com/GetStream/stream-java' + + scm { + url = 'scm:git@github.com:GetStream/stream-java.git' + connection = 'scm:git@github.com:GetStream/stream-java.git' + developerConnection = 'scm:git@github.com:GetStream/stream-java.git' + } + + licenses { + license { + name = 'The 3-Clause BSD License' + url = 'https://opensource.org/licenses/BSD-3-Clause' + distribution = 'repo' + } + } + + developers { + developer { + id = 'sirio7g' + name = 'Alessandro Pieri' + } + developer { + id = 'nekuromento' + name = 'Max Klyga' + } + } + } + } + } + repositories { + maven { + url 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' + credentials { + username = sonatypeUsername + password = sonatypePassword + } + } + } +} + +signing { + sign publishing.publications.mavenJava +} + +javadoc { + if (JavaVersion.current().isJava9Compatible()) { + options.addBooleanOption('html5', true) + } +} diff --git a/data/test.jpg b/data/test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fd87cca4645e9112b99f5bf669afeab6cf9b4403 GIT binary patch literal 1362 zcmex=>ukC3pCfH06P05XITq?4J21E^7eo0A(TN+S4wfI*Oh zL4<{YnNf*>Nsy6Qkn#T!25AOH1}0`kMg|06W@BOJ;A90#>IpD10PSUB=3r!n$}=)C zv#_!WvI_}|DsqU3sTev2CMtCL-z-nApf}6japo{}uxe&=4j;WArE(>fgfd zINQ*`GX2a*`$I_;^O9z%C13x{xs^ZbTvz0!O~zYluRgn3_Tp!)y}Zz0^G|u_mzurk zdeI*_v*WK;Z2XNVali7n`!@NtTS}LQ?esHywp=WG>*U6wm5+LUi|6{pY_~Zt`pu{K z{JpGaI#J8LG!EUFl^$;L_i_9Bo0kfnt>KoQ_Qg$imG+|*d-JufxaY>y>cuR2^U=`e zSFmB}cX`HHy7xPFUXIB&byM5%b#X{maqpSq(~?&F(zg5hXm9APnTt)%f1LB>{Mp~z z*Ig9eF(aT(c~}e$_wS8(-GlEp!!rEi5d*HTl=?<>&tOCO`Cb?pL3qU-fZq zWqNtPXvMwX=hGX%y?;Ef);hk}=Vh$r?*8Cc_ZIFc`1W^hG@sV_&D+)=c^tQ>FKhO7 zqjg6SW`?($8L<`JW+rR{7VSf2KS2e#ewJ&Hh%naqC}atvy{U7hM5HN#(k z@}7FG*Z)SBd&TWv?<19+zSr(ta%Z)4&gH45cTb+*>GLtJ_V@O*yqI~(UDnSk9=|pD zY%A69@trwyd)aImi&a`3pTGL}snx~0qUA z{Kfr#`B(d1~GL4_@71RI=A!?4F-m?5Z{Kn~UaU?#x^9XjPisM?+(N3-h`U zcWW*0S8cm`!Swb{sj}Nw^dG(~EA|F7wGccu4A zS8sH!JZju|C*4@`$lodTx!S9)?l!$W$1lBb<(tXBXTGkVUHSaje+KJ!_ntqhOq2gr zy?b|cjo$tB>urjCkJX@z@ax2rlHzxZp*ScG-*|os{n#S7VWLYMLE$-S#SPPnElGJ+ response = jack.getActivities(new Pagination().limit(10)).join(); + for (Activity activity : response) { + // ... + } + + // Remove an Activity by referencing it's foreign_id + chris.removeActivityByForeignID("picture:10"); + + /* -------------------------------------------------------- */ + + // Instantiate a feed object + FlatFeed userFeed = client.flatFeed("user", "1"); + + // Add an activity to the feed, where actor, object and target are references to objects (`Eric`, `Hawaii`, `Places to Visit`) + Activity activity = Activity.builder() + .actor("User:1") + .verb("pin") + .object("Place:42") + .target("Board:1") + .build(); + userFeed.addActivity(activity); + + // Create a bit more complex activity + activity = Activity.builder() + .actor("User:1") + .verb("run") + .object("Exercise:42") + .foreignID("run:1") + .extra(new ImmutableMap.Builder() + .put("course", new ImmutableMap.Builder() + .put("name", "Golden Gate park") + .put("distance", 10) + .build()) + .put("participants", new String[]{ + "Thierry", + "Tommaso", + }) + .put("started_at", LocalDateTime.now()) + .put("location", new ImmutableMap.Builder() + .put("type", "point") + .put("coordinates", new double[]{37.769722, -122.476944}) + .build()) + .build()) + .build(); + userFeed.addActivity(activity); + + // Remove an activity by its id + userFeed.removeActivityByID("e561de8f-00f1-11e4-b400-0cc47a024be0"); + + // Remove activities with foreign_id 'run:1' + userFeed.removeActivityByForeignID("run:1"); + + activity = Activity.builder() + .actor("1") + .verb("like") + .object("3") + .time(new Date()) + .foreignID("like:3") + .extraField("popularity", 100) + .build(); + + // first time the activity is added + userFeed.addActivity(activity); + + // update the popularity value for the activity + activity = Activity.builder() + .fromActivity(activity) + .extraField("popularity", 10) + .build(); + + client.batch().updateActivities(activity); + + /* -------------------------------------------------------- */ + + // partial update by activity ID + + // prepare the set operations + Map set = new ImmutableMap.Builder() + .put("product.price", 19.99) + .put("shares", new ImmutableMap.Builder() + .put("facebook", "...") + .put("twitter", "...") + .build()) + .build(); + // prepare the unset operations + String[] unset = new String[] { "daily_likes", "popularity" }; + + String id = "54a60c1e-4ee3-494b-a1e3-50c06acb5ed4"; + client.updateActivityByID(id, set, unset); + + String foreignID = "product:123"; + Date timestamp = new Date(); + client.updateActivityByForeignID(foreignID, timestamp, set, unset); + + FeedID[] add = new FeedID[0]; + FeedID[] remove = new FeedID[0]; + userFeed.updateActivityToTargets(activity, add, remove); + + FeedID[] newTargets = new FeedID[0]; + userFeed.replaceActivityToTargets(activity, newTargets); + + /* -------------------------------------------------------- */ + + Date now = new Date(); + Activity firstActivity = userFeed.addActivity(Activity.builder() + .actor("1") + .verb("like") + .object("3") + .time(now) + .foreignID("like:3") + .build()).join(); + Activity secondActivity = userFeed.addActivity(Activity.builder() + .actor("1") + .verb("like") + .object("3") + .time(now) + .extraField("extra", "extra_value") + .foreignID("like:3") + .build()).join(); + // foreign ID and time are the same for both activities + // hence only one activity is created and first and second IDs are equal + // firstActivity.ID == secondActivity.ID + + /* -------------------------------------------------------- */ + + // Get 5 activities with id less than the given UUID (Faster - Recommended!) + response = userFeed.getActivities(new Filter().idLessThan("e561de8f-00f1-11e4-b400-0cc47a024be0").limit(5)).join(); + // Get activities from 5 to 10 (Pagination-based - Slower) + response = userFeed.getActivities(new Pagination().offset(0).limit(5)).join(); + // Get activities sorted by rank (Ranked Feeds Enabled): + response = userFeed.getActivities(new Pagination().limit(5), "popularity").join(); + + /* -------------------------------------------------------- */ + + // timeline:timeline_feed_1 follows user:user_42 + FlatFeed user = client.flatFeed("user", "user_42"); + FlatFeed timeline = client.flatFeed("timeline", "timeline_feed_1"); + timeline.follow(user); + + // follow feed without copying the activities: + timeline.follow(user, 0); + + /* -------------------------------------------------------- */ + + // user := client.FlatFeed("user", "42") + + // Stop following feed user:user_42 + timeline.unfollow(user); + + // Stop following feed user:user_42 but keep history of activities + timeline.unfollow(user, KeepHistory.YES); + + // list followers + List followers = userFeed.getFollowers(new Pagination().offset(0).limit(10)).join(); + for (FollowRelation follow : followers) { + System.out.format("%s -> %s", follow.getSource(), follow.getTarget()); + // ... + } + + // Retrieve last 10 feeds followed by user_feed_1 + List followed = userFeed.getFollowed(new Pagination().offset(0).limit(10)).join(); + + // Retrieve 10 feeds followed by user_feed_1 starting from the 11th + followed = userFeed.getFollowed(new Pagination().offset(10).limit(10)).join(); + + // Check if user_feed_1 follows specific feeds + followed = userFeed.getFollowed(new Pagination().offset(0).limit(2), new FeedID("user:42"), new FeedID("user", "43")).join(); + + /* -------------------------------------------------------- */ + + NotificationFeed notifications = client.notificationFeed("notifications", "1"); + // Mark all activities in the feed as seen + List> activityGroups = notifications.getActivities(new ActivityMarker().allSeen()).join(); + for (NotificationGroup group : activityGroups) { + // ... + } + // Mark some activities as read via specific Activity Group Ids + activityGroups = notifications.getActivities(new ActivityMarker().read("groupID1", "groupID2" /* ... */)).join(); + + /* -------------------------------------------------------- */ + + // Add an activity to the feed, where actor, object and target are references to objects - adding your ranking method as a parameter (in this case, "popularity"): + activity = Activity.builder() + .actor("User:1") + .verb("pin") + .object("place:42") + .target("board:1") + .extraField("popularity", 5) + .build(); + userFeed.addActivity(activity); + + // Get activities sorted by the ranking method labelled 'activity_popularity' (Ranked Feeds Enabled) + response = userFeed.getActivities(new Pagination().limit(5), "activity_popularity").join(); + + /* -------------------------------------------------------- */ + + // Add the activity to Eric's feed and to Jessica's notification feed + activity = Activity.builder() + .actor("User:Eric") + .verb("tweet") + .object("tweet:id") + .to(Lists.newArrayList(new FeedID("notification:Jessica"))) + .extraField("message", "@Jessica check out getstream.io it's so dang awesome.") + .build(); + userFeed.addActivity(activity); + + // The TO field ensures the activity is send to the player, match and team feed + activity = Activity.builder() + .actor("Player:Suarez") + .verb("foul") + .object("Player:Ramos") + .to(Lists.newArrayList(new FeedID("team:barcelona"), new FeedID("match:1"))) + .extraField("match", ImmutableMap.of("El Classico", 10)) + .build(); + // playerFeed.addActivity(activity); + userFeed.addActivity(activity); + + /* -------------------------------------------------------- */ + + // Batch following many feeds + // Let timeline:1 will follow user:1, user:2 and user:3 + FollowRelation[] follows = new FollowRelation[]{ + new FollowRelation("timeline:1", "user:1"), + new FollowRelation("timeline:3", "user:2"), + new FollowRelation("timeline:1", "user:3") + }; + client.batch().followMany(follows); + // copy only the last 10 activities from every feed + client.batch().followMany(10, follows); + + /* -------------------------------------------------------- */ + + Activity[] activities = new Activity[]{ + Activity.builder() + .actor("User:1") + .verb("tweet") + .object("Tweet:1") + .build(), + Activity.builder() + .actor("User:2") + .verb("watch") + .object("Movie:1") + .build() + }; + userFeed.addActivities(activities); + + /* -------------------------------------------------------- */ + + // adds 1 activity to many feeds in one request + activity = Activity.builder() + .actor("User:2") + .verb("pin") + .object("Place:42") + .target("Board:1") + .build(); + FeedID[] feeds = new FeedID[]{ + new FeedID("timeline", "1"), + new FeedID("timeline", "2"), + new FeedID("timeline", "3"), + new FeedID("timeline", "4") + }; + client.batch().addToMany(activity, feeds); + + /* -------------------------------------------------------- */ + + // retrieve two activities by ID + client.batch().getActivitiesByID("01b3c1dd-e7ab-4649-b5b3-b4371d8f7045", "ed2837a6-0a3b-4679-adc1-778a1704852"); + + // retrieve an activity by foreign ID and time + client.batch().getActivitiesByForeignID(new ForeignIDTimePair("foreignID1", new Date()), new ForeignIDTimePair("foreignID2", new Date())); + + /* -------------------------------------------------------- */ + + // connect to the us-east region + client = Client.builder(apiKey, secret) + .region(Region.US_EAST) + .build(); + + /* -------------------------------------------------------- */ + Reaction like = new Reaction.Builder() + .kind("like") + .activityID(activity.getID()) + .build(); + + // add a like reaction to the activity with id activityId + like = client.reactions().add("john-doe", like).join(); + + Reaction comment = new Reaction.Builder() + .kind("comment") + .activityID(activity.getID()) + .extraField("text", "awesome post!") + .build(); + + // adds a comment reaction to the activity with id activityId + comment = client.reactions().add("john-doe", comment).join(); + + /* -------------------------------------------------------- */ + + // first let's read current user's timeline feed and pick one activity + response = client.flatFeed("timeline", "mike").getActivities().join(); + activity = response.get(0); + + // then let's add a like reaction to that activity + client.reactions().add("john-doe", Reaction.builder() + .kind("like") + .activityID(activity.getID()) + .build()); + + /* -------------------------------------------------------- */ + + comment = new Reaction.Builder() + .kind("comment") + .activityID(activity.getID()) + .extraField("text", "awesome post!") + .build(); + + // adds a comment reaction to the activity and notify Thierry's notification feed + client.reactions().add("john-doe", comment, new FeedID("notification:thierry")); + + /* -------------------------------------------------------- */ + + // read bob's timeline and include most recent reactions to all activities and their total count + client.flatFeed("timeline", "bob") + .getEnrichedActivities(new EnrichmentFlags() + .withRecentReactions() + .withReactionCounts()); + + // read bob's timeline and include most recent reactions to all activities and her own reactions + client.flatFeed("timeline", "bob") + .getEnrichedActivities(new EnrichmentFlags() + .withOwnReactions() + .withRecentReactions() + .withReactionCounts()); + + /* -------------------------------------------------------- */ + + // retrieve all kind of reactions for an activity + List reactions = client.reactions().filter(LookupKind.ACTIVITY, "ed2837a6-0a3b-4679-adc1-778a1704852d").join(); + + // retrieve first 10 likes for an activity + reactions = client.reactions() + .filter(LookupKind.ACTIVITY, + "ed2837a6-0a3b-4679-adc1-778a1704852d", + new Filter().limit(10), + "like").join(); + + // retrieve the next 10 likes using the id_lt param + reactions = client.reactions() + .filter(LookupKind.ACTIVITY, + "ed2837a6-0a3b-4679-adc1-778a1704852d", + new Filter().idLessThan("e561de8f-00f1-11e4-b400-0cc47a024be0"), + "like").join(); + + /* -------------------------------------------------------- */ + + // adds a like to the previously created comment + Reaction reaction = client.reactions().addChild("john-doe", comment.getId(), Reaction.builder().kind("like").build()).join(); + + /* -------------------------------------------------------- */ + + client.reactions().update(Reaction.builder() + .id(reaction.getId()) + .extraField("text", "love it!") + .build()); + + /* -------------------------------------------------------- */ + + client.reactions().delete(reaction.getId()); + + /* -------------------------------------------------------- */ + + client.collections().add("food", new CollectionData("cheese-burger") + .set("name", "Cheese Burger") + .set("rating", "4 stars")); + + // if you don't have an id on your side, just use null as the ID and Stream will generate a unique ID + client.collections().add("food", new CollectionData() + .set("name", "Cheese Burger") + .set("rating", "4 stars")); + + /* -------------------------------------------------------- */ + + CollectionData collection = client.collections().get("food", "cheese-burger").join(); + + /* -------------------------------------------------------- */ + + client.collections().delete("food", "cheese-burger"); + + /* -------------------------------------------------------- */ + + client.collections().update("food", new CollectionData("cheese-burger") + .set("name", "Cheese Burger") + .set("rating", "1 star")); + + /* -------------------------------------------------------- */ + + client.collections().upsert("visitor", + new CollectionData("123") + .set("name", "John") + .set("favorite_color", "blue"), + new CollectionData("124") + .set("name", "Jane") + .set("favorite_color", "purple") + .set("interests", Lists.newArrayList("fashion", "jazz"))); + + /* -------------------------------------------------------- */ + + // select the entries with ID 123 and 124 from items collection + List objects = client.collections().select("items", "123", "124").join(); + + /* -------------------------------------------------------- */ + + // delete the entries with ID 123 and 124 from visitor collection + client.collections().deleteMany("visitor", "123", "124"); + + /* -------------------------------------------------------- */ + + // first we add our object to the food collection + CollectionData cheeseBurger = client.collections().add("food", new CollectionData("123") + .set("name", "Cheese Burger") + .set("ingredients", Lists.newArrayList("cheese", "burger", "bread", "lettuce", "tomato"))).join(); + + // the object returned by .add can be embedded directly inside of an activity + userFeed.addActivity(Activity.builder() + .actor(createUserReference("john-doe")) + .verb("grill") + .object(createCollectionReference(cheeseBurger.getCollection(), cheeseBurger.getID())) + .build()); + + // if we now read the feed, the activity we just added will include the entire full object + userFeed.getEnrichedActivities(); + + // we can then update the object and Stream will propagate the change to all activities + client.collections().update(cheeseBurger.getCollection(), cheeseBurger + .set("name", "Amazing Cheese Burger") + .set("ingredients", Lists.newArrayList("cheese", "burger", "bread", "lettuce", "tomato"))).join(); + + /* -------------------------------------------------------- */ + + // First create a collection entry with upsert api + client.collections().upsert("food", new CollectionData().set("name", "Cheese Burger")); + + // Then create a user + client.user("john-doe").create(new Data() + .set("name", "John Doe") + .set("occupation", "Software Engineer") + .set("gender", "male")); + + // Since we know their IDs we can create references to both without reading from APIs + String cheeseBurgerRef = createCollectionReference("food", "cheese-burger"); + String johnDoeRef = createUserReference("john-doe"); + + client.flatFeed("user", "john").addActivity(Activity.builder() + .actor(johnDoeRef) + .verb("eat") + .object(cheeseBurgerRef) + .build()); + + /* -------------------------------------------------------- */ + + // create a new user, if the user already exist an error is returned + client.user("john-doe").create(new Data() + .set("name", "John Doe") + .set("occupation", "Software Engineer") + .set("gender", "male")); + + // get or create a new user, if the user already exist the user is returned + client.user("john-doe").getOrCreate(new Data() + .set("name", "John Doe") + .set("occupation", "Software Engineer") + .set("gender", "male")); + + /* -------------------------------------------------------- */ + + client.user("123").get(); + + /* -------------------------------------------------------- */ + + client.user("123").delete(); + + /* -------------------------------------------------------- */ + + client.user("123").update(new Data() + .set("name", "Jane Doe") + .set("occupation", "Software Engineer") + .set("gender", "female")); + + /* -------------------------------------------------------- */ + + // Read the personalization feed for a given user + client.personalization().get("personalized_feed", new ImmutableMap.Builder() + .put("user_id", 123) + .put("feed_slug", "timeline") + .build()); + + // Our data science team will typically tell you which endpoint to use + client.personalization().get("discovery_feed", new ImmutableMap.Builder() + .put("user_id", 123) + .put("source_feed_slug", "timeline") + .put("target_feed_slug", "user") + .build()); + + /* -------------------------------------------------------- */ + + client.analytics().trackEngagement(Engagement.builder() + .feedID("user:thierry") + .content(new Content("message:34349698") + .set("verb", "share") + .set("actor", ImmutableMap.of("1", "user1"))) + .boost(2) + .location("profile_page") + .position(3) + .build()); + + /* -------------------------------------------------------- */ + + client.analytics().trackImpression(Impression.builder() + .contentList(new Content("tweet:34349698") + .set("verb", "share") + .set("actor", ImmutableMap.of("1", "user1")), + new Content("tweet:34349699"), + new Content("tweet:34349700")) + .feedID("flat:tommaso") + .location("android-app") + .build()); + + /* -------------------------------------------------------- */ + + // the URL to direct to + URL targetURL = new URL("http://mysite.com/detail"); + + // track the impressions and a click + List impressions = Lists.newArrayList(Impression.builder() + .contentList(new Content("tweet:1"), + new Content("tweet:2"), + new Content("tweet:3")) + .userData(new UserData("tommaso", null)) + .location("email") + .feedID("user:global") + .build()); + List engagements = Lists.newArrayList(Engagement.builder() + .content(new Content("tweet:2")) + .label("click") + .position(1) + .userData(new UserData("tommaso", null)) + .location("email") + .feedID("user:global") + .build()); + + // when the user opens the tracking URL in their browser gets redirected to the target URL + // the events are added to our analytics platform + URL trackingURL = client.analytics().createRedirectURL(targetURL, impressions, engagements); + + /* -------------------------------------------------------- */ + + File image = new File("..."); + URL imageURL = client.images().upload(image).join(); + + File file = new File("..."); + URL fileURL = client.files().upload(file).join(); + + /* -------------------------------------------------------- */ + + // deleting an image using the url returned by the APIs + client.images().delete(imageURL); + + // deleting a file using the url returned by the APIs + client.files().delete(fileURL); + + /* -------------------------------------------------------- */ + + // create a 50x50 thumbnail and crop from center + client.images().process(imageURL, new Resize(50, 50, Resize.Type.CROP)); + + // create a 50x50 thumbnail using clipping (keeps aspect ratio) + client.images().process(imageURL, new Resize(50, 50, Resize.Type.CLIP)); + + /* -------------------------------------------------------- */ + + OGData urlPreview = client.openGraph(new URL("http://www.imdb.com/title/tt0117500/")).join(); + } +} diff --git a/pom.xml b/pom.xml deleted file mode 100644 index dbf15999..00000000 --- a/pom.xml +++ /dev/null @@ -1,331 +0,0 @@ - - - 4.0.0 - - io.getstream.client - stream-java - pom - 2.1.4-SNAPSHOT - - stream-java - stream-java is a Java client for http://getstream.io. - https://github.com/GetStream/stream-java - - - - The 3-Clause BSD License - https://opensource.org/licenses/BSD-3-Clause - - - Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - - sirio7g - Alessandro Pieri - https://github.com/sirio7g - - - tbarbugli - Tommaso Barbugli - https://github.com/tbarbugli - - - - - scm:git:git@github.com:GetStream/stream-java.git - scm:git:git@github.com:GetStream/stream-java.git - git@github.com:GetStream/stream-java.git - HEAD - - - - stream-core - stream-repo-apache - stream-repo-okhttp - - - - UTF-8 - UTF-8 - 1.6.6 - 1.1.2 - 18.0 - 2.4.3 - 1.0 - 4.11 - 1.10.19 - 3.3.0 - 1.57 - - true - false - - - - - - org.slf4j - slf4j-api - ${slf4j-api.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - ch.qos.logback - logback-core - ${logback.version} - - - com.google.guava - guava - ${guava.version} - - - com.fasterxml.jackson.core - jackson-core - ${jackson.version} - - - com.fasterxml.jackson.core - jackson-annotations - ${jackson.version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - - org.tomitribe - tomitribe-http-signatures - ${tomitribe-http-signatures.version} - - - com.auth0 - java-jwt - ${java-jwt.version} - - - - - junit - junit - ${junit.version} - test - - - org.mockito - mockito-core - ${mockito.version} - test - - - com.github.tomakehurst - wiremock - ${wiremock.version} - test - - - standalone - - - org.mortbay.jetty - jetty - - - com.google.guava - guava - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-annotations - - - com.fasterxml.jackson.core - jackson-databind - - - org.apache.httpcomponents - httpclient - - - org.skyscreamer - jsonassert - - - xmlunit - xmlunit - - - com.jayway.jsonpath - json-path - - - net.sf.jopt-simple - jopt-simple - - - - - - - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - - - - - org.apache.maven.plugins - maven-release-plugin - 2.5 - - false - release - deploy - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - aggregate - - aggregate - - site - - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.3 - true - - ossrh - https://oss.sonatype.org/ - true - - - - maven-compiler-plugin - 2.3.2 - - 1.7 - 1.7 - - - - maven-release-plugin - 2.5 - - - org.apache.maven.plugins - maven-surefire-plugin - 2.19.1 - - ${skipTests} - - **/*IntegrationTest.java - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.19.1 - - ${skipTests} - ${skipITs} - - **/IntegrationTest.java - - - - - integration-test - - integration-test - verify - - - - - - - - - - release - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9.1 - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.5 - - - sign-artifacts - verify - - sign - - - - - - - - - diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..4f791be5 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user guide at https://docs.gradle.org/4.10.2/userguide/multi_project_builds.html + */ + +rootProject.name = 'stream-java' diff --git a/src/main/java/io/getstream/client/AggregatedFeed.java b/src/main/java/io/getstream/client/AggregatedFeed.java new file mode 100644 index 00000000..0d653617 --- /dev/null +++ b/src/main/java/io/getstream/client/AggregatedFeed.java @@ -0,0 +1,217 @@ +package io.getstream.client; + +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.models.Activity; +import io.getstream.core.models.EnrichedActivity; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.Group; +import io.getstream.core.options.ActivityMarker; +import io.getstream.core.options.EnrichmentFlags; +import io.getstream.core.options.Filter; +import io.getstream.core.options.Pagination; +import io.getstream.core.utils.DefaultOptions; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static io.getstream.core.utils.Serialization.deserializeContainer; + +public class AggregatedFeed extends Feed { + AggregatedFeed(Client client, FeedID id) { + super(client, id); + } + + public CompletableFuture>> getActivities() throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + public CompletableFuture>> getActivities(Pagination pagination) throws StreamException { + return getActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + public CompletableFuture>> getActivities(Filter filter) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER); + } + + public CompletableFuture>> getActivities(ActivityMarker marker) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker); + } + + public CompletableFuture>> getActivities(Filter filter, ActivityMarker marker) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, filter, marker); + } + + public CompletableFuture>> getActivities(Pagination pagination, ActivityMarker marker) throws StreamException { + return getActivities(pagination, DefaultOptions.DEFAULT_FILTER, marker); + } + + CompletableFuture>> getActivities(Pagination pagination, Filter filter, ActivityMarker marker) throws StreamException { + return getClient() + .getActivities(getID(), pagination, filter, marker) + .thenApply(response -> { + try { + return deserializeContainer(response, Group.class, Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture>> getCustomActivities(Class type) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + public CompletableFuture>> getCustomActivities(Class type, Pagination pagination) throws StreamException { + return getCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + public CompletableFuture>> getCustomActivities(Class type, Filter filter) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER); + } + + public CompletableFuture>> getCustomActivities(Class type, ActivityMarker marker) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker); + } + + public CompletableFuture>> getCustomActivities(Class type, Filter filter, ActivityMarker marker) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, marker); + } + + public CompletableFuture>> getCustomActivities(Class type, Pagination pagination, ActivityMarker marker) throws StreamException { + return getCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, marker); + } + + CompletableFuture>> getCustomActivities(Class type, Pagination pagination, Filter filter, ActivityMarker marker) throws StreamException { + return getClient() + .getActivities(getID(), pagination, filter, marker) + .thenApply(response -> { + try { + return deserializeContainer(response, Group.class, type); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture>> getEnrichedActivities() throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedActivities(EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + public CompletableFuture>> getEnrichedActivities(Pagination pagination) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedActivities(Pagination pagination, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + public CompletableFuture>> getEnrichedActivities(Filter filter) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedActivities(Filter filter, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, flags); + } + + public CompletableFuture>> getEnrichedActivities(ActivityMarker marker) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedActivities(ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + public CompletableFuture>> getEnrichedActivities(Filter filter, ActivityMarker marker) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedActivities(Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, marker, flags); + } + + public CompletableFuture>> getEnrichedActivities(Pagination pagination, ActivityMarker marker) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedActivities(Pagination pagination, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + CompletableFuture>> getEnrichedActivities(Pagination pagination, Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getClient() + .getEnrichedActivities(getID(), pagination, filter, marker, flags) + .thenApply(response -> { + try { + return deserializeContainer(response, Group.class, EnrichedActivity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, flags); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, ActivityMarker marker) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter, ActivityMarker marker) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, marker, flags); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, ActivityMarker marker) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getClient() + .getEnrichedActivities(getID(), pagination, filter, marker, flags) + .thenApply(response -> { + try { + return deserializeContainer(response, Group.class, type); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } +} diff --git a/src/main/java/io/getstream/client/AnalyticsClient.java b/src/main/java/io/getstream/client/AnalyticsClient.java new file mode 100644 index 00000000..742d47d7 --- /dev/null +++ b/src/main/java/io/getstream/client/AnalyticsClient.java @@ -0,0 +1,56 @@ +package io.getstream.client; + +import com.google.common.collect.Iterables; +import io.getstream.core.StreamAnalytics; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.models.Engagement; +import io.getstream.core.models.Impression; +import io.getstream.core.utils.Auth.TokenAction; + +import java.net.URL; +import java.util.concurrent.CompletableFuture; + +import static io.getstream.core.utils.Auth.buildAnalyticsRedirectToken; +import static io.getstream.core.utils.Auth.buildAnalyticsToken; + +public final class AnalyticsClient { + private final String secret; + private final StreamAnalytics analytics; + + AnalyticsClient(String secret, StreamAnalytics analytics) { + this.secret = secret; + this.analytics = analytics; + } + + public CompletableFuture trackEngagement(Iterable events) throws StreamException { + return trackEngagement(Iterables.toArray(events, Engagement.class)); + } + + public CompletableFuture trackEngagement(Engagement... events) throws StreamException { + final Token token = buildAnalyticsToken(secret, TokenAction.WRITE); + return analytics.trackEngagement(token, events); + } + + public CompletableFuture trackImpression(Impression event) throws StreamException { + final Token token = buildAnalyticsToken(secret, TokenAction.WRITE); + return analytics.trackImpression(token, event); + } + + public URL createRedirectURL(URL url, Engagement... engagements) throws StreamException { + return createRedirectURL(url, new Impression[0], engagements); + } + + public URL createRedirectURL(URL url, Impression... impressions) throws StreamException { + return createRedirectURL(url, impressions, new Engagement[0]); + } + + public URL createRedirectURL(URL url, Iterable impressions, Iterable engagements) throws StreamException { + return createRedirectURL(url, Iterables.toArray(impressions, Impression.class), Iterables.toArray(engagements, Engagement.class)); + } + + public URL createRedirectURL(URL url, Impression[] impressions, Engagement[] engagements) throws StreamException { + final Token token = buildAnalyticsRedirectToken(secret); + return analytics.createRedirectURL(token, url, impressions, engagements); + } +} diff --git a/src/main/java/io/getstream/client/BatchClient.java b/src/main/java/io/getstream/client/BatchClient.java new file mode 100644 index 00000000..7cb05333 --- /dev/null +++ b/src/main/java/io/getstream/client/BatchClient.java @@ -0,0 +1,80 @@ +package io.getstream.client; + +import com.google.common.collect.Iterables; +import io.getstream.core.StreamBatch; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.models.Activity; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.FollowRelation; +import io.getstream.core.models.ForeignIDTimePair; +import io.getstream.core.utils.DefaultOptions; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static io.getstream.core.utils.Auth.*; + +public final class BatchClient { + private final String secret; + private final StreamBatch batch; + + BatchClient(String secret, StreamBatch batch) { + this.secret = secret; + this.batch = batch; + } + + public CompletableFuture addToMany(Activity activity, FeedID... feeds) throws StreamException { + final Token token = buildFeedToken(secret, TokenAction.WRITE); + return batch.addToMany(token, activity, feeds); + } + + public CompletableFuture followMany(int activityCopyLimit, FollowRelation... follows) throws StreamException { + final Token token = buildFollowToken(secret, TokenAction.WRITE); + return batch.followMany(token, activityCopyLimit, follows); + } + + public CompletableFuture followMany(int activityCopyLimit, Iterable follows) throws StreamException { + return followMany(activityCopyLimit, Iterables.toArray(follows, FollowRelation.class)); + } + + public CompletableFuture followMany(FollowRelation... follows) throws StreamException { + return followMany(DefaultOptions.DEFAULT_ACTIVITY_COPY_LIMIT, follows); + } + + public CompletableFuture followMany(Iterable follows) throws StreamException { + return followMany(Iterables.toArray(follows, FollowRelation.class)); + } + + public CompletableFuture unfollowMany(FollowRelation... follows) throws StreamException { + final Token token = buildFollowToken(secret, TokenAction.DELETE); + return batch.unfollowMany(token, follows); + } + + public CompletableFuture> getActivitiesByID(Iterable activityIDs) throws StreamException { + return getActivitiesByID(Iterables.toArray(activityIDs, String.class)); + } + + public CompletableFuture> getActivitiesByID(String... activityIDs) throws StreamException { + final Token token = buildActivityToken(secret, TokenAction.READ); + return batch.getActivitiesByID(token, activityIDs); + } + + public CompletableFuture> getActivitiesByForeignID(Iterable activityIDTimePairs) throws StreamException { + return getActivitiesByForeignID(Iterables.toArray(activityIDTimePairs, ForeignIDTimePair.class)); + } + + public CompletableFuture> getActivitiesByForeignID(ForeignIDTimePair... activityIDTimePairs) throws StreamException { + final Token token = buildActivityToken(secret, TokenAction.READ); + return batch.getActivitiesByForeignID(token, activityIDTimePairs); + } + + public CompletableFuture updateActivities(Iterable activities) throws StreamException { + return updateActivities(Iterables.toArray(activities, Activity.class)); + } + + public CompletableFuture updateActivities(Activity... activities) throws StreamException { + final Token token = buildActivityToken(secret, TokenAction.WRITE); + return batch.updateActivities(token, activities); + } +} diff --git a/src/main/java/io/getstream/client/Client.java b/src/main/java/io/getstream/client/Client.java new file mode 100644 index 00000000..77d41a1e --- /dev/null +++ b/src/main/java/io/getstream/client/Client.java @@ -0,0 +1,296 @@ +package io.getstream.client; + +import com.google.common.collect.Iterables; +import io.getstream.core.Region; +import io.getstream.core.Stream; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.HTTPClient; +import io.getstream.core.http.OKHTTPClientAdapter; +import io.getstream.core.http.Response; +import io.getstream.core.http.Token; +import io.getstream.core.models.*; +import io.getstream.core.options.RequestOption; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Date; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Auth.*; + +public final class Client { + private final String secret; + private final Stream stream; + + private Client(String key, String secret, URL baseURL, HTTPClient httpClient) { + this.secret = secret; + this.stream = new Stream(key, baseURL, httpClient); + } + + public static Builder builder(String apiKey, String secret) { + return new Builder(apiKey, secret); + } + + public CompletableFuture updateActivityByID(String id, Map set, Iterable unset) throws StreamException { + return updateActivityByID(id, set, Iterables.toArray(unset, String.class)); + } + + public CompletableFuture updateActivityByID(String id, Map set, String[] unset) throws StreamException { + final Token token = buildFeedToken(secret, TokenAction.WRITE); + return stream.updateActivityByID(token, id, set, unset); + } + + public CompletableFuture updateActivityByForeignID(ForeignIDTimePair foreignIDTimePair, Map set, Iterable unset) throws StreamException { + checkNotNull(foreignIDTimePair, "No activity to update"); + return updateActivityByForeignID(foreignIDTimePair.getForeignID(), foreignIDTimePair.getTime(), set, unset); + } + + public CompletableFuture updateActivityByForeignID(ForeignIDTimePair foreignIDTimePair, Map set, String[] unset) throws StreamException { + checkNotNull(foreignIDTimePair, "No activity to update"); + return updateActivityByForeignID(foreignIDTimePair.getForeignID(), foreignIDTimePair.getTime(), set, unset); + } + + public CompletableFuture updateActivityByForeignID(String foreignID, Date timestamp, Map set, Iterable unset) throws StreamException { + return updateActivityByForeignID(foreignID, timestamp, set, Iterables.toArray(unset, String.class)); + } + + public CompletableFuture updateActivityByForeignID(String foreignID, Date timestamp, Map set, String[] unset) throws StreamException { + final Token token = buildActivityToken(secret, TokenAction.WRITE); + return stream.updateActivityByForeignID(token, foreignID, timestamp, set, unset); + } + + public CompletableFuture openGraph(URL url) throws StreamException { + final Token token = buildOpenGraphToken(secret); + return stream.openGraph(token, url); + } + + public static final class Builder { + private static final String DEFAULT_HOST = "stream-io-api.com"; + + private final String apiKey; + private final String secret; + private HTTPClient httpClient; + + private String scheme = "https"; + private String region = Region.US_EAST.toString(); + private String host = DEFAULT_HOST; + private int port = 443; + + public Builder(String apiKey, String secret) { + checkNotNull(apiKey, "API key can't be null"); + checkNotNull(secret, "Secret can't be null"); + checkArgument(!apiKey.isEmpty(), "API key can't be empty"); + checkArgument(!secret.isEmpty(), "Secret can't be empty"); + this.apiKey = apiKey; + this.secret = secret; + } + + public Builder httpClient(HTTPClient httpClient) { + checkNotNull(httpClient, "HTTP client can't be null"); + this.httpClient = httpClient; + return this; + } + + public Builder scheme(String scheme) { + checkNotNull(scheme, "Scheme can't be null"); + checkArgument(!scheme.isEmpty(), "Scheme can't be empty"); + this.scheme = scheme; + return this; + } + + public Builder host(String host) { + checkNotNull(host, "Host can't be null"); + checkArgument(!host.isEmpty(), "Host can't be empty"); + this.host = host; + return this; + } + + public Builder port(int port) { + checkArgument(port > 0, "Port has to be a non-zero positive number"); + this.port = port; + return this; + } + + public Builder region(Region region) { + checkNotNull(region, "Region can't be null"); + this.region = region.toString(); + return this; + } + + public Builder region(String region) { + checkNotNull(region, "Region can't be null"); + checkArgument(!region.isEmpty(), "Region can't be empty"); + this.region = region; + return this; + } + + private String buildHost() { + final StringBuilder sb = new StringBuilder(); + if (host.equals(DEFAULT_HOST)) { + sb.append(region).append("."); + } + sb.append(host); + return sb.toString(); + } + + public Client build() throws MalformedURLException { + if (httpClient == null) { + httpClient = new OKHTTPClientAdapter(); + } + return new Client(apiKey, secret, new URL(scheme, buildHost(), port, ""), httpClient); + } + } + + public T getHTTPClientImplementation() { + return stream.getHTTPClientImplementation(); + } + + public Token frontendToken(String userID) { + return buildFrontendToken(secret, userID); + } + + public FlatFeed flatFeed(FeedID id) { + return new FlatFeed(this, id); + } + + public FlatFeed flatFeed(String slug, String userID) { + return flatFeed(new FeedID(slug, userID)); + } + + public AggregatedFeed aggregatedFeed(FeedID id) { + return new AggregatedFeed(this, id); + } + + public AggregatedFeed aggregatedFeed(String slug, String userID) { + return aggregatedFeed(new FeedID(slug, userID)); + } + + public NotificationFeed notificationFeed(FeedID id) { + return new NotificationFeed(this, id); + } + + public NotificationFeed notificationFeed(String slug, String userID) { + return notificationFeed(new FeedID(slug, userID)); + } + + public User user(String userID) { + return new User(this, userID); + } + + public BatchClient batch() { + return new BatchClient(secret, stream.batch()); + } + + public CollectionsClient collections() { + return new CollectionsClient(secret, stream.collections()); + } + + public PersonalizationClient personalization() { + return new PersonalizationClient(secret, stream.personalization()); + } + + public AnalyticsClient analytics() { + return new AnalyticsClient(secret, stream.analytics()); + } + + public ReactionsClient reactions() { + return new ReactionsClient(secret, stream.reactions()); + } + + public FileStorageClient files() { + return new FileStorageClient(secret, stream.files()); + } + + public ImageStorageClient images() { + return new ImageStorageClient(secret, stream.images()); + } + + CompletableFuture getActivities(FeedID feed, RequestOption... options) throws StreamException { + final Token token = buildFeedToken(secret, feed, TokenAction.READ); + return stream.getActivities(token, feed, options); + } + + CompletableFuture getEnrichedActivities(FeedID feed, RequestOption... options) throws StreamException { + final Token token = buildFeedToken(secret, feed, TokenAction.READ); + return stream.getEnrichedActivities(token, feed, options); + } + + CompletableFuture addActivity(FeedID feed, Activity activity) throws StreamException { + final Token token = buildFeedToken(secret, feed, TokenAction.WRITE); + return stream.addActivity(token, feed, activity); + } + + CompletableFuture addActivities(FeedID feed, Activity... activities) throws StreamException { + final Token token = buildFeedToken(secret, feed, TokenAction.WRITE); + return stream.addActivities(token, feed, activities); + } + + CompletableFuture removeActivityByID(FeedID feed, String id) throws StreamException { + final Token token = buildFeedToken(secret, feed, TokenAction.DELETE); + return stream.removeActivityByID(token, feed, id); + } + + CompletableFuture removeActivityByForeignID(FeedID feed, String foreignID) throws StreamException { + final Token token = buildFeedToken(secret, feed, TokenAction.DELETE); + return stream.removeActivityByForeignID(token, feed, foreignID); + } + + CompletableFuture follow(FeedID source, FeedID target, int activityCopyLimit) throws StreamException { + final Token token = buildFollowToken(secret, source, TokenAction.WRITE); + final Token targetToken = buildFeedToken(secret, target, TokenAction.READ); + return stream.follow(token, targetToken, source, target, activityCopyLimit); + } + + CompletableFuture getFollowers(FeedID feed, RequestOption... options) throws StreamException { + final Token token = buildFollowToken(secret, feed, TokenAction.READ); + return stream.getFollowers(token, feed, options); + } + + CompletableFuture getFollowed(FeedID feed, RequestOption... options) throws StreamException { + final Token token = buildFollowToken(secret, feed, TokenAction.READ); + return stream.getFollowed(token, feed, options); + } + + CompletableFuture unfollow(FeedID source, FeedID target, RequestOption... options) throws StreamException { + final Token token = buildFollowToken(secret, source, TokenAction.DELETE); + return stream.unfollow(token, source, target, options); + } + + CompletableFuture updateActivityToTargets(FeedID feed, Activity activity, FeedID[] add, FeedID[] remove, FeedID[] newTargets) throws StreamException { + final Token token = buildToTargetUpdateToken(secret, feed, TokenAction.WRITE); + return stream.updateActivityToTargets(token, feed, activity, add, remove, newTargets); + } + + CompletableFuture getUser(String id) throws StreamException { + final Token token = buildUsersToken(secret, TokenAction.READ); + return stream.getUser(token, id, false); + } + + CompletableFuture deleteUser(String id) throws StreamException { + final Token token = buildUsersToken(secret, TokenAction.DELETE); + return stream.deleteUser(token, id); + } + + CompletableFuture getOrCreateUser(String id, Data data) throws StreamException { + final Token token = buildUsersToken(secret, TokenAction.WRITE); + return stream.createUser(token, id, data, true); + } + + CompletableFuture createUser(String id, Data data) throws StreamException { + final Token token = buildUsersToken(secret, TokenAction.WRITE); + return stream.createUser(token, id, data, false); + } + + CompletableFuture updateUser(String id, Data data) throws StreamException { + final Token token = buildUsersToken(secret, TokenAction.WRITE); + return stream.updateUser(token, id, data); + } + + CompletableFuture userProfile(String id) throws StreamException { + final Token token = buildUsersToken(secret, TokenAction.READ); + return stream.getUser(token, id, true); + } +} diff --git a/src/main/java/io/getstream/client/CollectionsClient.java b/src/main/java/io/getstream/client/CollectionsClient.java new file mode 100644 index 00000000..aac154e9 --- /dev/null +++ b/src/main/java/io/getstream/client/CollectionsClient.java @@ -0,0 +1,139 @@ +package io.getstream.client; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Streams; +import io.getstream.core.StreamCollections; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.models.CollectionData; +import io.getstream.core.utils.Auth.TokenAction; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +import static io.getstream.core.utils.Auth.buildCollectionsToken; +import static io.getstream.core.utils.Serialization.convert; + +public final class CollectionsClient { + private final String secret; + private final StreamCollections collections; + + CollectionsClient(String secret, StreamCollections collections) { + this.secret = secret; + this.collections = collections; + } + + public CompletableFuture addCustom(String collection, T item) throws StreamException { + return addCustom(null, collection, item); + } + + public CompletableFuture addCustom(String userID, String collection, T item) throws StreamException { + return add(userID, collection, convert(item, CollectionData.class)) + .thenApply(data -> convert(data, (Class) item.getClass())); + } + + public CompletableFuture add(String collection, CollectionData item) throws StreamException { + return add(null, collection, item); + } + + public CompletableFuture add(String userID, String collection, CollectionData item) throws StreamException { + final Token token = buildCollectionsToken(secret, TokenAction.WRITE); + return collections.add(token, userID, collection, item); + } + + public CompletableFuture updateCustom(String collection, T item) throws StreamException { + return updateCustom(null, collection, item); + } + + public CompletableFuture updateCustom(String userID, String collection, T item) throws StreamException { + return update(userID, collection, convert(item, CollectionData.class)) + .thenApply(data -> convert(data, (Class) item.getClass())); + } + + public CompletableFuture update(String collection, CollectionData item) throws StreamException { + return update(null, collection, item); + } + + public CompletableFuture update(String userID, String collection, CollectionData item) throws StreamException { + final Token token = buildCollectionsToken(secret, TokenAction.WRITE); + return collections.update(token, userID, collection, item); + } + + public CompletableFuture upsertCustom(String collection, Iterable items) throws StreamException { + final CollectionData[] custom = Streams.stream(items) + .map(item -> CollectionData.buildFrom(item)) + .toArray(CollectionData[]::new); + return upsert(collection, custom); + } + + public CompletableFuture upsertCustom(String collection, T... items) throws StreamException { + final CollectionData[] custom = Arrays.stream(items) + .map(item -> CollectionData.buildFrom(item)) + .toArray(CollectionData[]::new); + return upsert(collection, custom); + } + + public CompletableFuture upsert(String collection, Iterable items) throws StreamException { + return upsert(collection, Iterables.toArray(items, CollectionData.class)); + } + + public CompletableFuture upsert(String collection, CollectionData... items) throws StreamException { + final Token token = buildCollectionsToken(secret, TokenAction.WRITE); + return collections.upsert(token, collection, items); + } + + public CompletableFuture> customItems(Class type, String collection) throws StreamException { + return items(collection) + .thenApply(result -> result.stream() + .map(item -> convert(item, type)) + .collect(Collectors.toList())); + } + + public CompletableFuture> items(String collection) throws StreamException { + final Token token = buildCollectionsToken(secret, TokenAction.READ); + return collections.items(token, collection); + } + + public CompletableFuture getCustom(Class type, String collection, String id) throws StreamException { + return get(collection, id).thenApply(data -> convert(data, type)); + } + + public CompletableFuture get(String collection, String id) throws StreamException { + final Token token = buildCollectionsToken(secret, TokenAction.READ); + return collections.get(token, collection, id); + } + + public CompletableFuture> selectCustom(Class type, String collection, Iterable ids) throws StreamException { + return selectCustom(type, collection, Iterables.toArray(ids, String.class)); + } + + public CompletableFuture> selectCustom(Class type, String collection, String... ids) throws StreamException { + return select(collection, ids) + .thenApply(data -> data.stream().map(item -> convert(item, type)).collect(Collectors.toList())); + } + + public CompletableFuture> select(String collection, Iterable ids) throws StreamException { + return select(collection, Iterables.toArray(ids, String.class)); + } + + public CompletableFuture> select(String collection, String... ids) throws StreamException { + final Token token = buildCollectionsToken(secret, TokenAction.READ); + return collections.select(token, collection, ids); + } + + public CompletableFuture delete(String collection, String id) throws StreamException { + final Token token = buildCollectionsToken(secret, TokenAction.DELETE); + return collections.delete(token, collection, id); + } + + public CompletableFuture deleteMany(String collection, Iterable ids) throws StreamException { + return deleteMany(collection, Iterables.toArray(ids, String.class)); + } + + public CompletableFuture deleteMany(String collection, String... ids) throws StreamException { + final Token token = buildCollectionsToken(secret, TokenAction.DELETE); + return collections.deleteMany(token, collection, ids); + } +} diff --git a/src/main/java/io/getstream/client/Feed.java b/src/main/java/io/getstream/client/Feed.java new file mode 100644 index 00000000..3ab25599 --- /dev/null +++ b/src/main/java/io/getstream/client/Feed.java @@ -0,0 +1,278 @@ +package io.getstream.client; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Streams; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.models.Activity; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.FollowRelation; +import io.getstream.core.options.CustomQueryParameter; +import io.getstream.core.options.Pagination; +import io.getstream.core.options.RequestOption; +import io.getstream.core.utils.DefaultOptions; + +import java.io.IOException; +import java.lang.reflect.ParameterizedType; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Serialization.*; + +public class Feed { + private final Client client; + private final FeedID id; + + Feed(Client client, FeedID id) { + checkNotNull(client, "Can't create feed w/o a client"); + checkNotNull(id, "Can't create feed w/o an ID"); + + this.client = client; + this.id = id; + } + + protected final Client getClient() { + return client; + } + + public final FeedID getID() { + return id; + } + + public final String getSlug() { + return id.getSlug(); + } + + public final String getUserID() { + return id.getUserID(); + } + + public final CompletableFuture addActivity(Activity activity) throws StreamException { + return getClient() + .addActivity(id, activity) + .thenApply(response -> { + try { + return deserialize(response, Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture addCustomActivity(T activity) throws StreamException { + return getClient() + .addActivity(id, Activity.builder().fromCustomActivity(activity).build()) + .thenApply(response -> { + try { + return deserialize(response, (Class) activity.getClass()); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture> addActivities(Iterable activities) throws StreamException { + return addActivities(Iterables.toArray(activities, Activity.class)); + } + + public final CompletableFuture> addCustomActivities(Iterable activities) throws StreamException { + final Activity[] custom = Streams.stream(activities) + .map(activity -> Activity.builder().fromCustomActivity(activity).build()) + .toArray(Activity[]::new); + return getClient() + .addActivities(id, custom) + .thenApply(response -> { + try { + Class element = (Class) ((ParameterizedType) getClass().getGenericSuperclass()) .getActualTypeArguments()[0]; + return deserializeContainer(response, "activities", element); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture> addActivities(Activity... activities) throws StreamException { + return getClient() + .addActivities(id, activities) + .thenApply(response -> { + try { + return deserializeContainer(response, "activities", Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture> addCustomActivities(T... activities) throws StreamException { + final Activity[] custom = Arrays.stream(activities) + .map(activity -> Activity.builder().fromCustomActivity(activity).build()) + .toArray(Activity[]::new); + return getClient() + .addActivities(id, custom) + .thenApply(response -> { + try { + Class element = (Class) activities.getClass().getComponentType(); + return deserializeContainer(response, "activities", element); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture removeActivityByID(String id) throws StreamException { + return client + .removeActivityByID(this.id, id) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture removeActivityByForeignID(String foreignID) throws StreamException { + return client + .removeActivityByForeignID(id, foreignID) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture follow(FlatFeed feed) throws StreamException { + return follow(feed, DefaultOptions.DEFAULT_ACTIVITY_COPY_LIMIT); + } + + public final CompletableFuture follow(FlatFeed feed, int activityCopyLimit) throws StreamException { + checkArgument(activityCopyLimit <= DefaultOptions.MAX_ACTIVITY_COPY_LIMIT, String.format("Activity copy limit should be less then %d", DefaultOptions.MAX_ACTIVITY_COPY_LIMIT)); + + return client + .follow(id, feed.getID(), activityCopyLimit) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture> getFollowers(Iterable feedIDs) throws StreamException { + return getFollowers(DefaultOptions.DEFAULT_PAGINATION, Iterables.toArray(feedIDs, FeedID.class)); + } + + public final CompletableFuture> getFollowers(FeedID... feedIDs) throws StreamException { + return getFollowers(DefaultOptions.DEFAULT_PAGINATION, feedIDs); + } + + public final CompletableFuture> getFollowers(Pagination pagination, Iterable feedIDs) throws StreamException { + return getFollowers(pagination, Iterables.toArray(feedIDs, FeedID.class)); + } + + public final CompletableFuture> getFollowers(Pagination pagination, FeedID... feeds) throws StreamException { + checkNotNull(feeds, "No feed ids to filter on"); + + final String[] feedIDs = Arrays.stream(feeds) + .map(id -> id.toString()) + .toArray(String[]::new); + final RequestOption[] options = feedIDs.length == 0 + ? new RequestOption[] { pagination } + : new RequestOption[] { pagination, new CustomQueryParameter("filter", String.join(",", feedIDs)) }; + return client + .getFollowers(id, options) + .thenApply(response -> { + try { + return deserializeContainer(response, FollowRelation.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture> getFollowed(Iterable feedIDs) throws StreamException { + return getFollowed(DefaultOptions.DEFAULT_PAGINATION, Iterables.toArray(feedIDs, FeedID.class)); + } + + public final CompletableFuture> getFollowed(FeedID... feedIDs) throws StreamException { + return getFollowed(DefaultOptions.DEFAULT_PAGINATION, feedIDs); + } + + public final CompletableFuture> getFollowed(Pagination pagination, Iterable feedIDs) throws StreamException { + return getFollowed(pagination, Iterables.toArray(feedIDs, FeedID.class)); + } + + public final CompletableFuture> getFollowed(Pagination pagination, FeedID... feeds) throws StreamException { + checkNotNull(feeds, "No feed ids to filter on"); + + final String[] feedIDs = Arrays.stream(feeds) + .map(id -> id.toString()) + .toArray(String[]::new); + final RequestOption[] options = feedIDs.length == 0 + ? new RequestOption[] { pagination } + : new RequestOption[] { pagination, new CustomQueryParameter("filter", String.join(",", feedIDs)) }; + return client + .getFollowed(id, options) + .thenApply(response -> { + try { + return deserializeContainer(response, FollowRelation.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture unfollow(FlatFeed feed) throws StreamException { + return unfollow(feed, io.getstream.core.KeepHistory.NO); + } + + public final CompletableFuture unfollow(FlatFeed feed, io.getstream.core.KeepHistory keepHistory) throws StreamException { + return client + .unfollow(id, feed.getID(), new io.getstream.core.options.KeepHistory(keepHistory)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture updateActivityToTargets(Activity activity, Iterable add, Iterable remove) throws StreamException { + return updateActivityToTargets(activity, Iterables.toArray(add, FeedID.class), Iterables.toArray(remove, FeedID.class)); + } + + public final CompletableFuture updateActivityToTargets(Activity activity, FeedID[] add, FeedID[] remove) throws StreamException { + return client + .updateActivityToTargets(id, activity, add, remove, new FeedID[0]) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture replaceActivityToTargets(Activity activity, Iterable newTargets) throws StreamException { + return replaceActivityToTargets(activity, Iterables.toArray(newTargets, FeedID.class)); + } + + public final CompletableFuture replaceActivityToTargets(Activity activity, FeedID... newTargets) throws StreamException { + return client + .updateActivityToTargets(id, activity, new FeedID[0], new FeedID[0], newTargets) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } +} diff --git a/src/main/java/io/getstream/client/FileStorageClient.java b/src/main/java/io/getstream/client/FileStorageClient.java new file mode 100644 index 00000000..b7696b22 --- /dev/null +++ b/src/main/java/io/getstream/client/FileStorageClient.java @@ -0,0 +1,37 @@ +package io.getstream.client; + +import io.getstream.core.StreamFiles; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.utils.Auth.TokenAction; + +import java.io.File; +import java.net.URL; +import java.util.concurrent.CompletableFuture; + +import static io.getstream.core.utils.Auth.buildFilesToken; + +public final class FileStorageClient { + private final String secret; + private final StreamFiles files; + + FileStorageClient(String secret, StreamFiles files) { + this.secret = secret; + this.files = files; + } + + public CompletableFuture upload(String fileName, byte[] content) throws StreamException { + final Token token = buildFilesToken(secret, TokenAction.WRITE); + return files.upload(token, fileName, content); + } + + public CompletableFuture upload(File content) throws StreamException { + final Token token = buildFilesToken(secret, TokenAction.WRITE); + return files.upload(token, content); + } + + public CompletableFuture delete(URL url) throws StreamException { + final Token token = buildFilesToken(secret, TokenAction.DELETE); + return files.delete(token, url); + } +} diff --git a/src/main/java/io/getstream/client/FlatFeed.java b/src/main/java/io/getstream/client/FlatFeed.java new file mode 100644 index 00000000..7ed5ac70 --- /dev/null +++ b/src/main/java/io/getstream/client/FlatFeed.java @@ -0,0 +1,225 @@ +package io.getstream.client; + +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.models.Activity; +import io.getstream.core.models.EnrichedActivity; +import io.getstream.core.models.FeedID; +import io.getstream.core.options.*; +import io.getstream.core.utils.DefaultOptions; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static io.getstream.core.utils.Serialization.deserializeContainer; + +public final class FlatFeed extends Feed { + FlatFeed(Client client, FeedID id) { + super(client, id); + } + + public CompletableFuture> getActivities() throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, null); + } + + public CompletableFuture> getActivities(String ranking) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, ranking); + } + + public CompletableFuture> getActivities(Filter filter) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, filter, null); + } + + public CompletableFuture> getActivities(Pagination pagination) throws StreamException { + return getActivities(pagination, DefaultOptions.DEFAULT_FILTER, null); + } + + public CompletableFuture> getActivities(Filter filter, String ranking) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, filter, ranking); + } + + public CompletableFuture> getActivities(Pagination pagination, String ranking) throws StreamException { + return getActivities(pagination, DefaultOptions.DEFAULT_FILTER, ranking); + } + + CompletableFuture> getActivities(Pagination pagination, Filter filter, String ranking) throws StreamException { + final RequestOption[] options = ranking == null + ? new RequestOption[] { pagination, filter, DefaultOptions.DEFAULT_MARKER } + : new RequestOption[] { pagination, filter, DefaultOptions.DEFAULT_MARKER, new Ranking(ranking) }; + return getClient() + .getActivities(getID(), options) + .thenApply(response -> { + try { + return deserializeContainer(response, Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture> getCustomActivities(Class type) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, null); + } + + public CompletableFuture> getCustomActivities(Class type, String ranking) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, ranking); + } + + public CompletableFuture> getCustomActivities(Class type, Filter filter) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, null); + } + + public CompletableFuture> getCustomActivities(Class type, Pagination pagination) throws StreamException { + return getCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, null); + } + + public CompletableFuture> getCustomActivities(Class type, Pagination pagination, String ranking) throws StreamException { + return getCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, ranking); + } + + public CompletableFuture> getCustomActivities(Class type, Filter filter, String ranking) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, ranking); + } + + CompletableFuture> getCustomActivities(Class type, Pagination pagination, Filter filter, String ranking) throws StreamException { + final RequestOption[] options = ranking == null + ? new RequestOption[] { pagination, filter, DefaultOptions.DEFAULT_MARKER } + : new RequestOption[] { pagination, filter, DefaultOptions.DEFAULT_MARKER, new Ranking(ranking) }; + return getClient() + .getActivities(getID(), options) + .thenApply(response -> { + try { + return deserializeContainer(response, type); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture> getEnrichedActivities() throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, null); + } + + public CompletableFuture> getEnrichedActivities(EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, flags, null); + } + + public CompletableFuture> getEnrichedActivities(String ranking) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, ranking); + } + + public CompletableFuture> getEnrichedActivities(EnrichmentFlags flags, String ranking) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, flags, ranking); + } + + public CompletableFuture> getEnrichedActivities(Filter filter) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, null); + } + + public CompletableFuture> getEnrichedActivities(Filter filter, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, flags, null); + } + + public CompletableFuture> getEnrichedActivities(Pagination pagination) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, null); + } + + public CompletableFuture> getEnrichedActivities(Pagination pagination, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, flags, null); + } + + public CompletableFuture> getEnrichedActivities(Filter filter, String ranking) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, ranking); + } + + public CompletableFuture> getEnrichedActivities(Filter filter, EnrichmentFlags flags, String ranking) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, flags, ranking); + } + + public CompletableFuture> getEnrichedActivities(Pagination pagination, String ranking) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, ranking); + } + + public CompletableFuture> getEnrichedActivities(Pagination pagination, EnrichmentFlags flags, String ranking) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, flags, ranking); + } + + CompletableFuture> getEnrichedActivities(Pagination pagination, Filter filter, EnrichmentFlags flags, String ranking) throws StreamException { + final RequestOption[] options = ranking == null + ? new RequestOption[] { pagination, filter, flags, DefaultOptions.DEFAULT_MARKER } + : new RequestOption[] { pagination, filter, flags, DefaultOptions.DEFAULT_MARKER, new Ranking(ranking) }; + return getClient() + .getEnrichedActivities(getID(), options) + .thenApply(response -> { + try { + return deserializeContainer(response, EnrichedActivity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, null); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, flags, null); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, String ranking) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, ranking); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, EnrichmentFlags flags, String ranking) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, flags, ranking); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Filter filter) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, null); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Filter filter, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, flags, null); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Pagination pagination) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, null); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Pagination pagination, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, flags, null); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Pagination pagination, String ranking) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, ranking); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Pagination pagination, EnrichmentFlags flags, String ranking) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, flags, ranking); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Filter filter, String ranking) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, ranking); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Filter filter, EnrichmentFlags flags, String ranking) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, flags, ranking); + } + + CompletableFuture> getEnrichedCustomActivities(Class type, Pagination pagination, Filter filter, EnrichmentFlags flags, String ranking) throws StreamException { + final RequestOption[] options = ranking == null + ? new RequestOption[] { pagination, filter, flags, DefaultOptions.DEFAULT_MARKER } + : new RequestOption[] { pagination, filter, flags, DefaultOptions.DEFAULT_MARKER, new Ranking(ranking) }; + return getClient() + .getActivities(getID(), options) + .thenApply(response -> { + try { + return deserializeContainer(response, type); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } +} diff --git a/src/main/java/io/getstream/client/ImageStorageClient.java b/src/main/java/io/getstream/client/ImageStorageClient.java new file mode 100644 index 00000000..0f358c24 --- /dev/null +++ b/src/main/java/io/getstream/client/ImageStorageClient.java @@ -0,0 +1,49 @@ +package io.getstream.client; + +import io.getstream.core.StreamImages; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.options.Crop; +import io.getstream.core.options.Resize; +import io.getstream.core.utils.Auth.TokenAction; + +import java.io.File; +import java.net.URL; +import java.util.concurrent.CompletableFuture; + +import static io.getstream.core.utils.Auth.buildFilesToken; + +public final class ImageStorageClient { + private final String secret; + private final StreamImages images; + + ImageStorageClient(String secret, StreamImages images) { + this.secret = secret; + this.images = images; + } + + public CompletableFuture upload(String fileName, byte[] content) throws StreamException { + final Token token = buildFilesToken(secret, TokenAction.WRITE); + return images.upload(token, fileName, content); + } + + public CompletableFuture upload(File content) throws StreamException { + final Token token = buildFilesToken(secret, TokenAction.WRITE); + return images.upload(token, content); + } + + public CompletableFuture delete(URL url) throws StreamException { + final Token token = buildFilesToken(secret, TokenAction.DELETE); + return images.delete(token, url); + } + + public CompletableFuture process(URL url, Crop crop) throws StreamException { + final Token token = buildFilesToken(secret, TokenAction.READ); + return images.process(token, url, crop); + } + + public CompletableFuture process(URL url, Resize resize) throws StreamException { + final Token token = buildFilesToken(secret, TokenAction.READ); + return images.process(token, url, resize); + } +} diff --git a/src/main/java/io/getstream/client/NotificationFeed.java b/src/main/java/io/getstream/client/NotificationFeed.java new file mode 100644 index 00000000..91703f4f --- /dev/null +++ b/src/main/java/io/getstream/client/NotificationFeed.java @@ -0,0 +1,257 @@ +package io.getstream.client; + +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.models.Activity; +import io.getstream.core.models.EnrichedActivity; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.NotificationGroup; +import io.getstream.core.options.ActivityMarker; +import io.getstream.core.options.EnrichmentFlags; +import io.getstream.core.options.Filter; +import io.getstream.core.options.Pagination; +import io.getstream.core.utils.DefaultOptions; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static io.getstream.core.utils.Serialization.deserializeContainer; + +public final class NotificationFeed extends AggregatedFeed { + NotificationFeed(Client client, FeedID id) { + super(client, id); + } + + @Override + public CompletableFuture>> getActivities() throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + @Override + public CompletableFuture>> getActivities(Pagination pagination) throws StreamException { + return getActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + @Override + public CompletableFuture>> getActivities(Filter filter) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER); + } + + @Override + public CompletableFuture>> getActivities(ActivityMarker marker) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker); + } + + @Override + public CompletableFuture>> getActivities(Filter filter, ActivityMarker marker) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, filter, marker); + } + + @Override + public CompletableFuture>> getActivities(Pagination pagination, ActivityMarker marker) throws StreamException { + return getActivities(pagination, DefaultOptions.DEFAULT_FILTER, marker); + } + + @Override + CompletableFuture>> getActivities(Pagination pagination, Filter filter, ActivityMarker marker) throws StreamException { + return getClient() + .getActivities(getID(), pagination, filter, marker) + .thenApply(response -> { + try { + return deserializeContainer(response, NotificationGroup.class, Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture>> getCustomActivities(Class type) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + @Override + public CompletableFuture>> getCustomActivities(Class type, Pagination pagination) throws StreamException { + return getCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + @Override + public CompletableFuture>> getCustomActivities(Class type, Filter filter) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER); + } + + @Override + public CompletableFuture>> getCustomActivities(Class type, ActivityMarker marker) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker); + } + + @Override + public CompletableFuture>> getCustomActivities(Class type, Filter filter, ActivityMarker marker) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, marker); + } + + @Override + public CompletableFuture>> getCustomActivities(Class type, Pagination pagination, ActivityMarker marker) throws StreamException { + return getCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, marker); + } + + @Override + CompletableFuture>> getCustomActivities(Class type, Pagination pagination, Filter filter, ActivityMarker marker) throws StreamException { + return getClient() + .getActivities(getID(), pagination, filter, marker) + .thenApply(response -> { + try { + return deserializeContainer(response, NotificationGroup.class, type); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture>> getEnrichedActivities() throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedActivities(EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Pagination pagination) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Pagination pagination, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Filter filter) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Filter filter, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, flags); + } + + @Override + public CompletableFuture>> getEnrichedActivities(ActivityMarker marker) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedActivities(ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Filter filter, ActivityMarker marker) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, marker, flags); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Pagination pagination, ActivityMarker marker) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Pagination pagination, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + @Override + CompletableFuture>> getEnrichedActivities(Pagination pagination, Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getClient() + .getEnrichedActivities(getID(), pagination, filter, marker, flags) + .thenApply(response -> { + try { + return deserializeContainer(response, NotificationGroup.class, EnrichedActivity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, flags); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, ActivityMarker marker) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter, ActivityMarker marker) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, marker, flags); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, ActivityMarker marker) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + @Override + CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getClient() + .getEnrichedActivities(getID(), pagination, filter, marker, flags) + .thenApply(response -> { + try { + return deserializeContainer(response, NotificationGroup.class, type); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } +} diff --git a/src/main/java/io/getstream/client/PersonalizationClient.java b/src/main/java/io/getstream/client/PersonalizationClient.java new file mode 100644 index 00000000..e7ed80fe --- /dev/null +++ b/src/main/java/io/getstream/client/PersonalizationClient.java @@ -0,0 +1,73 @@ +package io.getstream.client; + +import com.google.common.collect.ImmutableMap; +import io.getstream.core.StreamPersonalization; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.utils.Auth.TokenAction; + +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +import static io.getstream.core.utils.Auth.buildPersonalizationToken; + +public final class PersonalizationClient { + private final String secret; + private final StreamPersonalization personalization; + + PersonalizationClient(String secret, StreamPersonalization personalization) { + this.secret = secret; + this.personalization = personalization; + } + + public CompletableFuture> get(String resource) throws StreamException { + return get(null, resource); + } + + public CompletableFuture> get(String resource, Map params) throws StreamException { + return get(null, resource, params); + } + + public CompletableFuture> get(String userID, String resource) throws StreamException { + return get(userID, resource, ImmutableMap.of()); + } + + public CompletableFuture> get(String userID, String resource, Map params) throws StreamException { + final Token token = buildPersonalizationToken(secret, userID, TokenAction.READ); + return personalization.get(token, userID, resource, params); + } + + public CompletableFuture post(String resource, Map payload) throws StreamException { + return post(null, resource, payload); + } + + public CompletableFuture post(String resource, Map params, Map payload) throws StreamException { + return post(null, resource, params, payload); + } + + public CompletableFuture post(String userID, String resource, Map payload) throws StreamException { + return post(userID, resource, ImmutableMap.of(), payload); + } + + public CompletableFuture post(String userID, String resource, Map params, Map payload) throws StreamException { + final Token token = buildPersonalizationToken(secret, userID, TokenAction.WRITE); + return personalization.post(token, userID, resource, params, payload); + } + + public CompletableFuture delete(String resource) throws StreamException { + return delete(null, resource); + } + + public CompletableFuture delete(String resource, Map params) throws StreamException { + return delete(null, resource, params); + } + + public CompletableFuture delete(String userID, String resource) throws StreamException { + return delete(userID, resource, ImmutableMap.of()); + } + + public CompletableFuture delete(String userID, String resource, Map params) throws StreamException { + final Token token = buildPersonalizationToken(secret, userID, TokenAction.DELETE); + return personalization.delete(token, userID, resource, params); + } +} diff --git a/src/main/java/io/getstream/client/ReactionsClient.java b/src/main/java/io/getstream/client/ReactionsClient.java new file mode 100644 index 00000000..dcd00ae2 --- /dev/null +++ b/src/main/java/io/getstream/client/ReactionsClient.java @@ -0,0 +1,118 @@ +package io.getstream.client; + +import com.google.common.collect.Iterables; +import io.getstream.core.LookupKind; +import io.getstream.core.StreamReactions; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.Reaction; +import io.getstream.core.options.Filter; +import io.getstream.core.utils.Auth.TokenAction; +import io.getstream.core.utils.DefaultOptions; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Auth.buildReactionsToken; + +public final class ReactionsClient { + private final String secret; + private final StreamReactions reactions; + + ReactionsClient(String secret, StreamReactions reactions) { + this.secret = secret; + this.reactions = reactions; + } + + public CompletableFuture get(String id) throws StreamException { + final Token token = buildReactionsToken(secret, TokenAction.READ); + return reactions.get(token, id); + } + + public CompletableFuture> filter(LookupKind lookup, String id) throws StreamException { + return filter(lookup, id, ""); + } + + public CompletableFuture> filter(LookupKind lookup, String id, Filter filter) throws StreamException { + return filter(lookup, id, filter, ""); + } + + public CompletableFuture> filter(LookupKind lookup, String id, String kind) throws StreamException { + return filter(lookup, id, DefaultOptions.DEFAULT_FILTER, kind); + } + + public CompletableFuture> filter(LookupKind lookup, String id, Filter filter, String kind) throws StreamException { + final Token token = buildReactionsToken(secret, TokenAction.READ); + return reactions.filter(token, lookup, id, filter, kind); + } + + public CompletableFuture add(String userID, String kind, String activityID, Iterable targetFeeds) throws StreamException { + return add(userID, kind, activityID, Iterables.toArray(targetFeeds, FeedID.class)); + } + + public CompletableFuture add(String userID, String kind, String activityID, FeedID... targetFeeds) throws StreamException { + checkNotNull(kind, "Reaction kind can't be null"); + checkArgument(!kind.isEmpty(), "Reaction kind can't be empty"); + checkNotNull(activityID, "Reaction activity id can't be null"); + checkArgument(!activityID.isEmpty(), "Reaction activity id can't be empty"); + + return add(userID, Reaction.builder().activityID(activityID).kind(kind).build(), targetFeeds); + } + + public CompletableFuture add(String userID, Reaction reaction, Iterable targetFeeds) throws StreamException { + return add(userID, reaction, Iterables.toArray(targetFeeds, FeedID.class)); + } + + public CompletableFuture add(String userID, Reaction reaction, FeedID... targetFeeds) throws StreamException { + final Token token = buildReactionsToken(secret, TokenAction.WRITE); + return reactions.add(token, userID, reaction, targetFeeds); + } + + public CompletableFuture addChild(String userID, String kind, String parentID, Iterable targetFeeds) throws StreamException { + Reaction child = Reaction.builder().kind(kind).parent(parentID).build(); + return add(userID, child, targetFeeds); + } + + public CompletableFuture addChild(String userID, String kind, String parentID, FeedID... targetFeeds) throws StreamException { + Reaction child = Reaction.builder().kind(kind).parent(parentID).build(); + return add(userID, child, targetFeeds); + } + + public CompletableFuture addChild(String userID, String parentID, Reaction reaction, Iterable targetFeeds) throws StreamException { + Reaction child = Reaction.builder().fromReaction(reaction).parent(parentID).build(); + return add(userID, child, targetFeeds); + } + + public CompletableFuture addChild(String userID, String parentID, Reaction reaction, FeedID... targetFeeds) throws StreamException { + Reaction child = Reaction.builder().fromReaction(reaction).parent(parentID).build(); + return add(userID, child, targetFeeds); + } + + public CompletableFuture update(String id, Iterable targetFeeds) throws StreamException { + return update(id, Iterables.toArray(targetFeeds, FeedID.class)); + } + + public CompletableFuture update(String id, FeedID... targetFeeds) throws StreamException { + checkNotNull(id, "Reaction id can't be null"); + checkArgument(!id.isEmpty(), "Reaction id can't be empty"); + + return update(Reaction.builder().id(id).build(), targetFeeds); + } + + public CompletableFuture update(Reaction reaction, Iterable targetFeeds) throws StreamException { + return update(reaction, Iterables.toArray(targetFeeds, FeedID.class)); + } + + public CompletableFuture update(Reaction reaction, FeedID... targetFeeds) throws StreamException { + final Token token = buildReactionsToken(secret, TokenAction.WRITE); + return reactions.update(token, reaction, targetFeeds); + } + + public CompletableFuture delete(String id) throws StreamException { + final Token token = buildReactionsToken(secret, TokenAction.DELETE); + return reactions.delete(token, id); + } +} diff --git a/src/main/java/io/getstream/client/User.java b/src/main/java/io/getstream/client/User.java new file mode 100644 index 00000000..a6e88cc6 --- /dev/null +++ b/src/main/java/io/getstream/client/User.java @@ -0,0 +1,98 @@ +package io.getstream.client; + +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.models.Data; +import io.getstream.core.models.ProfileData; + +import java.io.IOException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Serialization.deserialize; +import static io.getstream.core.utils.Serialization.deserializeError; + +public final class User { + private final Client client; + private final String id; + + public User(Client client, String id) { + checkNotNull(client, "Client can't be null"); + checkNotNull(id, "User ID can't be null"); + checkArgument(!id.isEmpty(), "User ID can't be empty"); + + this.client = client; + this.id = id; + } + + public String getID() { + return id; + } + + public CompletableFuture get() throws StreamException { + return client.getUser(id) + .thenApply(response -> { + try { + return deserialize(response, Data.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture delete() throws StreamException { + return client.deleteUser(id) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture getOrCreate(Data data) throws StreamException { + return client.getOrCreateUser(id, data) + .thenApply(response -> { + try { + return deserialize(response, Data.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture create(Data data) throws StreamException { + return client.createUser(id, data) + .thenApply(response -> { + try { + return deserialize(response, Data.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture update(Data data) throws StreamException { + return client.updateUser(id, data) + .thenApply(response -> { + try { + return deserialize(response, Data.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture profile() throws StreamException { + return client.userProfile(id) + .thenApply(response -> { + try { + return deserialize(response, ProfileData.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } +} diff --git a/src/main/java/io/getstream/cloud/CloudAggregatedFeed.java b/src/main/java/io/getstream/cloud/CloudAggregatedFeed.java new file mode 100644 index 00000000..4b6dca67 --- /dev/null +++ b/src/main/java/io/getstream/cloud/CloudAggregatedFeed.java @@ -0,0 +1,217 @@ +package io.getstream.cloud; + +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.models.Activity; +import io.getstream.core.models.EnrichedActivity; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.Group; +import io.getstream.core.options.ActivityMarker; +import io.getstream.core.options.EnrichmentFlags; +import io.getstream.core.options.Filter; +import io.getstream.core.options.Pagination; +import io.getstream.core.utils.DefaultOptions; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static io.getstream.core.utils.Serialization.deserializeContainer; + +public class CloudAggregatedFeed extends CloudFeed { + CloudAggregatedFeed(CloudClient client, FeedID id) { + super(client, id); + } + + public CompletableFuture>> getActivities() throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + public CompletableFuture>> getActivities(Pagination pagination) throws StreamException { + return getActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + public CompletableFuture>> getActivities(Filter filter) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER); + } + + public CompletableFuture>> getActivities(ActivityMarker marker) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker); + } + + public CompletableFuture>> getActivities(Filter filter, ActivityMarker marker) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, filter, marker); + } + + public CompletableFuture>> getActivities(Pagination pagination, ActivityMarker marker) throws StreamException { + return getActivities(pagination, DefaultOptions.DEFAULT_FILTER, marker); + } + + CompletableFuture>> getActivities(Pagination pagination, Filter filter, ActivityMarker marker) throws StreamException { + return getClient() + .getActivities(getID(), pagination, filter, marker) + .thenApply(response -> { + try { + return deserializeContainer(response, Group.class, Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture>> getCustomActivities(Class type) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + public CompletableFuture>> getCustomActivities(Class type, Pagination pagination) throws StreamException { + return getCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + public CompletableFuture>> getCustomActivities(Class type, Filter filter) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER); + } + + public CompletableFuture>> getCustomActivities(Class type, ActivityMarker marker) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker); + } + + public CompletableFuture>> getCustomActivities(Class type, Filter filter, ActivityMarker marker) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, marker); + } + + public CompletableFuture>> getCustomActivities(Class type, Pagination pagination, ActivityMarker marker) throws StreamException { + return getCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, marker); + } + + CompletableFuture>> getCustomActivities(Class type, Pagination pagination, Filter filter, ActivityMarker marker) throws StreamException { + return getClient() + .getActivities(getID(), pagination, filter, marker) + .thenApply(response -> { + try { + return deserializeContainer(response, Group.class, type); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture>> getEnrichedActivities() throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedActivities(EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + public CompletableFuture>> getEnrichedActivities(Pagination pagination) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedActivities(Pagination pagination, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + public CompletableFuture>> getEnrichedActivities(Filter filter) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedActivities(Filter filter, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, flags); + } + + public CompletableFuture>> getEnrichedActivities(ActivityMarker marker) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedActivities(ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + public CompletableFuture>> getEnrichedActivities(Filter filter, ActivityMarker marker) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedActivities(Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, marker, flags); + } + + public CompletableFuture>> getEnrichedActivities(Pagination pagination, ActivityMarker marker) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedActivities(Pagination pagination, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + CompletableFuture>> getEnrichedActivities(Pagination pagination, Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getClient() + .getEnrichedActivities(getID(), pagination, filter, marker, flags) + .thenApply(response -> { + try { + return deserializeContainer(response, Group.class, EnrichedActivity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, flags); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, ActivityMarker marker) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter, ActivityMarker marker) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, marker, flags); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, ActivityMarker marker) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getClient() + .getEnrichedActivities(getID(), pagination, filter, marker, flags) + .thenApply(response -> { + try { + return deserializeContainer(response, Group.class, type); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } +} diff --git a/src/main/java/io/getstream/cloud/CloudAnalyticsClient.java b/src/main/java/io/getstream/cloud/CloudAnalyticsClient.java new file mode 100644 index 00000000..62652afb --- /dev/null +++ b/src/main/java/io/getstream/cloud/CloudAnalyticsClient.java @@ -0,0 +1,32 @@ +package io.getstream.cloud; + +import com.google.common.collect.Iterables; +import io.getstream.core.StreamAnalytics; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.models.Engagement; +import io.getstream.core.models.Impression; + +import java.util.concurrent.CompletableFuture; + +public final class CloudAnalyticsClient { + private final Token token; + private final StreamAnalytics analytics; + + CloudAnalyticsClient(Token token, StreamAnalytics analytics) { + this.token = token; + this.analytics = analytics; + } + + public CompletableFuture trackEngagement(Iterable events) throws StreamException { + return trackEngagement(Iterables.toArray(events, Engagement.class)); + } + + public CompletableFuture trackEngagement(Engagement... events) throws StreamException { + return analytics.trackEngagement(token, events); + } + + public CompletableFuture trackImpression(Impression event) throws StreamException { + return analytics.trackImpression(token, event); + } +} diff --git a/src/main/java/io/getstream/cloud/CloudClient.java b/src/main/java/io/getstream/cloud/CloudClient.java new file mode 100644 index 00000000..b55810fa --- /dev/null +++ b/src/main/java/io/getstream/cloud/CloudClient.java @@ -0,0 +1,263 @@ +package io.getstream.cloud; + +import io.getstream.core.Region; +import io.getstream.core.Stream; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.HTTPClient; +import io.getstream.core.http.OKHTTPClientAdapter; +import io.getstream.core.http.Response; +import io.getstream.core.http.Token; +import io.getstream.core.models.Activity; +import io.getstream.core.models.Data; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.OGData; +import io.getstream.core.options.RequestOption; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.concurrent.CompletableFuture; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +public final class CloudClient { + private final Token token; + private final String userID; + private final Stream stream; + + private CloudClient(String key, String token, String userID, URL baseURL, HTTPClient httpClient) { + this.token = new Token(token); + this.userID = userID; + this.stream = new Stream(key, baseURL, httpClient); + } + + public static Builder builder(String apiKey, String secret, String userID) { + return new Builder(apiKey, secret, userID); + } + + public CompletableFuture openGraph(URL url) throws StreamException { + return stream.openGraph(token, url); + } + + public static final class Builder { + private static final String DEFAULT_HOST = "stream-io-api.com"; + + private final String apiKey; + private final String token; + private final String userID; + private HTTPClient httpClient; + + private String scheme = "https"; + private String region = Region.US_EAST.toString(); + private String host = DEFAULT_HOST; + private int port = 443; + + public Builder(String apiKey, String token, String userID) { + checkNotNull(apiKey, "API key can't be null"); + checkNotNull(token, "Token can't be null"); + checkNotNull(userID, "User ID can't be null"); + checkArgument(!apiKey.isEmpty(), "API key can't be empty"); + checkArgument(!token.isEmpty(), "Token can't be empty"); + checkArgument(!userID.isEmpty(), "User ID can't be empty"); + this.apiKey = apiKey; + this.token = token; + this.userID = userID; + } + + public Builder httpClient(HTTPClient httpClient) { + checkNotNull(httpClient, "HTTP client can't be null"); + this.httpClient = httpClient; + return this; + } + + public Builder scheme(String scheme) { + checkNotNull(scheme, "Scheme can't be null"); + checkArgument(!scheme.isEmpty(), "Scheme can't be empty"); + this.scheme = scheme; + return this; + } + + public Builder host(String host) { + checkNotNull(host, "Host can't be null"); + checkArgument(!host.isEmpty(), "Host can't be empty"); + this.host = host; + return this; + } + + public Builder port(int port) { + checkArgument(port > 0, "Port has to be a non-zero positive number"); + this.port = port; + return this; + } + + public Builder region(Region region) { + checkNotNull(region, "Region can't be null"); + this.region = region.toString(); + return this; + } + + public Builder region(String region) { + checkNotNull(region, "Region can't be null"); + checkArgument(!region.isEmpty(), "Region can't be empty"); + this.region = region; + return this; + } + + private String buildHost() { + final StringBuilder sb = new StringBuilder(); + if (host.equals(DEFAULT_HOST)) { + sb.append(region).append("."); + } + sb.append(host); + return sb.toString(); + } + + public CloudClient build() throws MalformedURLException { + if (httpClient == null) { + httpClient = new OKHTTPClientAdapter(); + } + return new CloudClient(apiKey, token, userID, new URL(scheme, buildHost(), port, ""), httpClient); + } + } + + public T getHTTPClientImplementation() { + return stream.getHTTPClientImplementation(); + } + + //TODO: add personalized feed versions + public CloudFlatFeed flatFeed(String slug) { + return flatFeed(slug, userID); + } + + public CloudFlatFeed flatFeed(String slug, CloudUser user) { + return flatFeed(slug, user.getID()); + } + + public CloudFlatFeed flatFeed(String slug, String userID) { + return flatFeed(new FeedID(slug, userID)); + } + + public CloudFlatFeed flatFeed(FeedID id) { + return new CloudFlatFeed(this, id); + } + + public CloudAggregatedFeed aggregatedFeed(String slug) { + return aggregatedFeed(slug, userID); + } + + public CloudAggregatedFeed aggregatedFeed(String slug, CloudUser user) { + return aggregatedFeed(slug, user.getID()); + } + + public CloudAggregatedFeed aggregatedFeed(String slug, String userID) { + return aggregatedFeed(new FeedID(slug, userID)); + } + + public CloudAggregatedFeed aggregatedFeed(FeedID id) { + return new CloudAggregatedFeed(this, id); + } + + public CloudNotificationFeed notificationFeed(String slug) { + return notificationFeed(slug, userID); + } + + public CloudNotificationFeed notificationFeed(String slug, CloudUser user) { + return notificationFeed(slug, user.getID()); + } + + public CloudNotificationFeed notificationFeed(String slug, String userID) { + return notificationFeed(new FeedID(slug, userID)); + } + + public CloudNotificationFeed notificationFeed(FeedID id) { + return new CloudNotificationFeed(this, id); + } + + public CloudUser user(String userID) { + return new CloudUser(this, userID); + } + + public CloudAnalyticsClient analytics() { + return new CloudAnalyticsClient(token, stream.analytics()); + } + + public CloudCollectionsClient collections() { + return new CloudCollectionsClient(token, userID, stream.collections()); + } + + public CloudReactionsClient reactions() { + return new CloudReactionsClient(token, userID, stream.reactions()); + } + + public CloudFileStorageClient files() { + return new CloudFileStorageClient(token, stream.files()); + } + + public CloudImageStorageClient images() { + return new CloudImageStorageClient(token, stream.images()); + } + + CompletableFuture getActivities(FeedID feed, RequestOption... options) throws StreamException { + return stream.getActivities(token, feed, options); + } + + CompletableFuture getEnrichedActivities(FeedID feed, RequestOption... options) throws StreamException { + return stream.getEnrichedActivities(token, feed, options); + } + + CompletableFuture addActivity(FeedID feed, Activity activity) throws StreamException { + return stream.addActivity(token, feed, activity); + } + + CompletableFuture addActivities(FeedID feed, Activity... activities) throws StreamException { + return stream.addActivities(token, feed, activities); + } + + CompletableFuture removeActivityByID(FeedID feed, String id) throws StreamException { + return stream.removeActivityByID(token, feed, id); + } + + CompletableFuture removeActivityByForeignID(FeedID feed, String foreignID) throws StreamException { + return stream.removeActivityByForeignID(token, feed, foreignID); + } + + CompletableFuture follow(FeedID source, FeedID target, int activityCopyLimit) throws StreamException { + return stream.follow(token, token, source, target, activityCopyLimit); + } + + CompletableFuture getFollowers(FeedID feed, RequestOption... options) throws StreamException { + return stream.getFollowers(token, feed, options); + } + + CompletableFuture getFollowed(FeedID feed, RequestOption... options) throws StreamException { + return stream.getFollowed(token, feed, options); + } + + CompletableFuture unfollow(FeedID source, FeedID target, RequestOption... options) throws StreamException { + return stream.unfollow(token, source, target, options); + } + + CompletableFuture getUser(String id) throws StreamException { + return stream.getUser(token, id, false); + } + + CompletableFuture deleteUser(String id) throws StreamException { + return stream.deleteUser(token, id); + } + + CompletableFuture getOrCreateUser(String id, Data data) throws StreamException { + return stream.createUser(token, id, data, true); + } + + CompletableFuture createUser(String id, Data data) throws StreamException { + return stream.createUser(token, id, data, false); + } + + CompletableFuture updateUser(String id, Data data) throws StreamException { + return stream.updateUser(token, id, data); + } + + CompletableFuture userProfile(String id) throws StreamException { + return stream.getUser(token, id, true); + } +} diff --git a/src/main/java/io/getstream/cloud/CloudCollectionsClient.java b/src/main/java/io/getstream/cloud/CloudCollectionsClient.java new file mode 100644 index 00000000..9ea483ad --- /dev/null +++ b/src/main/java/io/getstream/cloud/CloudCollectionsClient.java @@ -0,0 +1,81 @@ +package io.getstream.cloud; + +import io.getstream.core.StreamCollections; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.models.CollectionData; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +import static io.getstream.core.utils.Serialization.convert; + +public final class CloudCollectionsClient { + private final Token token; + private final String userID; + private final StreamCollections collections; + + CloudCollectionsClient(Token token, String userID, StreamCollections collections) { + this.token = token; + this.userID = userID; + this.collections = collections; + } + + public CompletableFuture addCustom(String collection, T item) throws StreamException { + return addCustom(userID, collection, item); + } + + public CompletableFuture addCustom(String userID, String collection, T item) throws StreamException { + return add(userID, collection, convert(item, CollectionData.class)) + .thenApply(data -> convert(data, (Class) item.getClass())); + } + + public CompletableFuture add(String collection, CollectionData item) throws StreamException { + return add(userID, collection, item); + } + + public CompletableFuture add(String userID, String collection, CollectionData item) throws StreamException { + return collections.add(token, userID, collection, item); + } + + public CompletableFuture updateCustom(String collection, T item) throws StreamException { + return updateCustom(userID, collection, item); + } + + public CompletableFuture updateCustom(String userID, String collection, T item) throws StreamException { + return update(userID, collection, convert(item, CollectionData.class)) + .thenApply(data -> convert(data, (Class) item.getClass())); + } + + public CompletableFuture update(String collection, CollectionData item) throws StreamException { + return update(userID, collection, item); + } + + public CompletableFuture update(String userID, String collection, CollectionData item) throws StreamException { + return collections.update(token, userID, collection, item); + } + + public CompletableFuture> customItems(Class type, String collection) throws StreamException { + return items(collection) + .thenApply(result -> result.stream() + .map(item -> convert(item, type)) + .collect(Collectors.toList())); + } + + public CompletableFuture> items(String collection) throws StreamException { + return collections.items(token, collection); + } + + public CompletableFuture getCustom(Class type, String collection, String id) throws StreamException { + return get(collection, id).thenApply(data -> convert(data, type)); + } + + public CompletableFuture get(String collection, String id) throws StreamException { + return collections.get(token, collection, id); + } + + public CompletableFuture delete(String collection, String id) throws StreamException { + return collections.delete(token, collection, id); + } +} diff --git a/src/main/java/io/getstream/cloud/CloudFeed.java b/src/main/java/io/getstream/cloud/CloudFeed.java new file mode 100644 index 00000000..47057cdc --- /dev/null +++ b/src/main/java/io/getstream/cloud/CloudFeed.java @@ -0,0 +1,246 @@ +package io.getstream.cloud; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Streams; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.models.Activity; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.FollowRelation; +import io.getstream.core.options.CustomQueryParameter; +import io.getstream.core.options.Pagination; +import io.getstream.core.options.RequestOption; +import io.getstream.core.utils.DefaultOptions; + +import java.io.IOException; +import java.lang.reflect.ParameterizedType; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Serialization.*; + +public class CloudFeed { + private final CloudClient client; + private final FeedID id; + + CloudFeed(CloudClient client, FeedID id) { + checkNotNull(client, "Can't create feed w/o a client"); + checkNotNull(id, "Can't create feed w/o an ID"); + + this.client = client; + this.id = id; + } + + protected final CloudClient getClient() { + return client; + } + + public final FeedID getID() { + return id; + } + + public final String getSlug() { + return id.getSlug(); + } + + public final String getUserID() { + return id.getUserID(); + } + + public final CompletableFuture addActivity(Activity activity) throws StreamException { + return getClient() + .addActivity(id, activity) + .thenApply(response -> { + try { + return deserialize(response, Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture addCustomActivity(T activity) throws StreamException { + return getClient() + .addActivity(id, Activity.builder().fromCustomActivity(activity).build()) + .thenApply(response -> { + try { + return deserialize(response, (Class) activity.getClass()); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture> addActivities(Iterable activities) throws StreamException { + return addActivities(Iterables.toArray(activities, Activity.class)); + } + + public final CompletableFuture> addCustomActivities(Iterable activities) throws StreamException { + final Activity[] custom = Streams.stream(activities) + .map(activity -> Activity.builder().fromCustomActivity(activity).build()) + .toArray(Activity[]::new); + return getClient() + .addActivities(id, custom) + .thenApply(response -> { + try { + Class element = (Class) ((ParameterizedType) getClass().getGenericSuperclass()) .getActualTypeArguments()[0]; + return deserializeContainer(response, "activities", element); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture> addActivities(Activity... activities) throws StreamException { + return getClient() + .addActivities(id, activities) + .thenApply(response -> { + try { + return deserializeContainer(response, "activities", Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture> addCustomActivities(T... activities) throws StreamException { + final Activity[] custom = Arrays.stream(activities) + .map(activity -> Activity.builder().fromCustomActivity(activity).build()) + .toArray(Activity[]::new); + return getClient() + .addActivities(id, custom) + .thenApply(response -> { + try { + Class element = (Class) activities.getClass().getComponentType(); + return deserializeContainer(response, "activities", element); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture removeActivityByID(String id) throws StreamException { + return client + .removeActivityByID(this.id, id) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture removeActivityByForeignID(String foreignID) throws StreamException { + return client + .removeActivityByForeignID(id, foreignID) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture follow(CloudFlatFeed feed) throws StreamException { + return follow(feed, DefaultOptions.DEFAULT_ACTIVITY_COPY_LIMIT); + } + + public final CompletableFuture follow(CloudFlatFeed feed, int activityCopyLimit) throws StreamException { + checkArgument(activityCopyLimit <= DefaultOptions.MAX_ACTIVITY_COPY_LIMIT, String.format("Activity copy limit should be less then %d", DefaultOptions.MAX_ACTIVITY_COPY_LIMIT)); + + return client + .follow(id, feed.getID(), activityCopyLimit) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture> getFollowers(Iterable feedIDs) throws StreamException { + return getFollowers(DefaultOptions.DEFAULT_PAGINATION, Iterables.toArray(feedIDs, FeedID.class)); + } + + public final CompletableFuture> getFollowers(FeedID... feedIDs) throws StreamException { + return getFollowers(DefaultOptions.DEFAULT_PAGINATION, feedIDs); + } + + public final CompletableFuture> getFollowers(Pagination pagination, Iterable feedIDs) throws StreamException { + return getFollowers(pagination, Iterables.toArray(feedIDs, FeedID.class)); + } + + public final CompletableFuture> getFollowers(Pagination pagination, FeedID... feeds) throws StreamException { + checkNotNull(feeds, "No feed ids to filter on"); + + final String[] feedIDs = Arrays.stream(feeds) + .map(id -> id.toString()) + .toArray(String[]::new); + final RequestOption[] options = feedIDs.length == 0 + ? new RequestOption[] { pagination } + : new RequestOption[] { pagination, new CustomQueryParameter("filter", String.join(",", feedIDs)) }; + return client + .getFollowers(id, options) + .thenApply(response -> { + try { + return deserializeContainer(response, FollowRelation.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture> getFollowed(Iterable feedIDs) throws StreamException { + return getFollowed(DefaultOptions.DEFAULT_PAGINATION, Iterables.toArray(feedIDs, FeedID.class)); + } + + public final CompletableFuture> getFollowed(FeedID... feedIDs) throws StreamException { + return getFollowed(DefaultOptions.DEFAULT_PAGINATION, feedIDs); + } + + public final CompletableFuture> getFollowed(Pagination pagination, Iterable feedIDs) throws StreamException { + return getFollowed(pagination, Iterables.toArray(feedIDs, FeedID.class)); + } + + public final CompletableFuture> getFollowed(Pagination pagination, FeedID... feeds) throws StreamException { + checkNotNull(feeds, "No feed ids to filter on"); + + final String[] feedIDs = Arrays.stream(feeds) + .map(id -> id.toString()) + .toArray(String[]::new); + final RequestOption[] options = feedIDs.length == 0 + ? new RequestOption[] { pagination } + : new RequestOption[] { pagination, new CustomQueryParameter("filter", String.join(",", feedIDs)) }; + return client + .getFollowed(id, options) + .thenApply(response -> { + try { + return deserializeContainer(response, FollowRelation.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public final CompletableFuture unfollow(CloudFlatFeed feed) throws StreamException { + return unfollow(feed, io.getstream.core.KeepHistory.NO); + } + + public final CompletableFuture unfollow(CloudFlatFeed feed, io.getstream.core.KeepHistory keepHistory) throws StreamException { + return client + .unfollow(id, feed.getID(), new io.getstream.core.options.KeepHistory(keepHistory)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } +} diff --git a/src/main/java/io/getstream/cloud/CloudFileStorageClient.java b/src/main/java/io/getstream/cloud/CloudFileStorageClient.java new file mode 100644 index 00000000..c2137c46 --- /dev/null +++ b/src/main/java/io/getstream/cloud/CloudFileStorageClient.java @@ -0,0 +1,31 @@ +package io.getstream.cloud; + +import io.getstream.core.StreamFiles; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; + +import java.io.File; +import java.net.URL; +import java.util.concurrent.CompletableFuture; + +public final class CloudFileStorageClient { + private final Token token; + private final StreamFiles files; + + CloudFileStorageClient(Token token, StreamFiles files) { + this.token = token; + this.files = files; + } + + public CompletableFuture upload(String fileName, byte[] content) throws StreamException { + return files.upload(token, fileName, content); + } + + public CompletableFuture upload(File content) throws StreamException { + return files.upload(token, content); + } + + public CompletableFuture delete(URL url) throws StreamException { + return files.delete(token, url); + } +} diff --git a/src/main/java/io/getstream/cloud/CloudFlatFeed.java b/src/main/java/io/getstream/cloud/CloudFlatFeed.java new file mode 100644 index 00000000..ba534bea --- /dev/null +++ b/src/main/java/io/getstream/cloud/CloudFlatFeed.java @@ -0,0 +1,225 @@ +package io.getstream.cloud; + +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.models.Activity; +import io.getstream.core.models.EnrichedActivity; +import io.getstream.core.models.FeedID; +import io.getstream.core.options.*; +import io.getstream.core.utils.DefaultOptions; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static io.getstream.core.utils.Serialization.deserializeContainer; + +public final class CloudFlatFeed extends CloudFeed { + CloudFlatFeed(CloudClient client, FeedID id) { + super(client, id); + } + + public CompletableFuture> getActivities() throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, null); + } + + public CompletableFuture> getActivities(String ranking) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, ranking); + } + + public CompletableFuture> getActivities(Filter filter) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, filter, null); + } + + public CompletableFuture> getActivities(Pagination pagination) throws StreamException { + return getActivities(pagination, DefaultOptions.DEFAULT_FILTER, null); + } + + public CompletableFuture> getActivities(Filter filter, String ranking) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, filter, ranking); + } + + public CompletableFuture> getActivities(Pagination pagination, String ranking) throws StreamException { + return getActivities(pagination, DefaultOptions.DEFAULT_FILTER, ranking); + } + + CompletableFuture> getActivities(Pagination pagination, Filter filter, String ranking) throws StreamException { + final RequestOption[] options = ranking == null + ? new RequestOption[] { pagination, filter, DefaultOptions.DEFAULT_MARKER } + : new RequestOption[] { pagination, filter, DefaultOptions.DEFAULT_MARKER, new Ranking(ranking) }; + return getClient() + .getActivities(getID(), options) + .thenApply(response -> { + try { + return deserializeContainer(response, Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture> getCustomActivities(Class type) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, null); + } + + public CompletableFuture> getCustomActivities(Class type, String ranking) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, ranking); + } + + public CompletableFuture> getCustomActivities(Class type, Filter filter) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, null); + } + + public CompletableFuture> getCustomActivities(Class type, Pagination pagination) throws StreamException { + return getCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, null); + } + + public CompletableFuture> getCustomActivities(Class type, Pagination pagination, String ranking) throws StreamException { + return getCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, ranking); + } + + public CompletableFuture> getCustomActivities(Class type, Filter filter, String ranking) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, ranking); + } + + CompletableFuture> getCustomActivities(Class type, Pagination pagination, Filter filter, String ranking) throws StreamException { + final RequestOption[] options = ranking == null + ? new RequestOption[] { pagination, filter, DefaultOptions.DEFAULT_MARKER } + : new RequestOption[] { pagination, filter, DefaultOptions.DEFAULT_MARKER, new Ranking(ranking) }; + return getClient() + .getActivities(getID(), options) + .thenApply(response -> { + try { + return deserializeContainer(response, type); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture> getEnrichedActivities() throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, null); + } + + public CompletableFuture> getEnrichedActivities(String ranking) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, ranking); + } + + public CompletableFuture> getEnrichedActivities(Filter filter) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, null); + } + + public CompletableFuture> getEnrichedActivities(Pagination pagination) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, null); + } + + public CompletableFuture> getEnrichedActivities(EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, flags, null); + } + + public CompletableFuture> getEnrichedActivities(EnrichmentFlags flags, String ranking) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, flags, ranking); + } + + public CompletableFuture> getEnrichedActivities(Filter filter, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, flags, null); + } + + public CompletableFuture> getEnrichedActivities(Pagination pagination, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, flags, null); + } + + public CompletableFuture> getEnrichedActivities(Filter filter, String ranking) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, ranking); + } + + public CompletableFuture> getEnrichedActivities(Pagination pagination, String ranking) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, ranking); + } + + public CompletableFuture> getEnrichedActivities(Filter filter, EnrichmentFlags flags, String ranking) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, flags, ranking); + } + + public CompletableFuture> getEnrichedActivities(Pagination pagination, EnrichmentFlags flags, String ranking) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, flags, ranking); + } + + CompletableFuture> getEnrichedActivities(Pagination pagination, Filter filter, EnrichmentFlags flags, String ranking) throws StreamException { + final RequestOption[] options = ranking == null + ? new RequestOption[] { pagination, filter, flags, DefaultOptions.DEFAULT_MARKER } + : new RequestOption[] { pagination, filter, flags, DefaultOptions.DEFAULT_MARKER, new Ranking(ranking) }; + return getClient() + .getEnrichedActivities(getID(), options) + .thenApply(response -> { + try { + return deserializeContainer(response, EnrichedActivity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, null); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, flags, null); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, String ranking) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, ranking); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, EnrichmentFlags flags, String ranking) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, flags, ranking); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Filter filter) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, null); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Filter filter, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, flags, null); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Pagination pagination) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, null); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Pagination pagination, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, flags, null); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Pagination pagination, String ranking) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, ranking); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Pagination pagination, EnrichmentFlags flags, String ranking) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, flags, ranking); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Filter filter, String ranking) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS, ranking); + } + + public CompletableFuture> getEnrichedCustomActivities(Class type, Filter filter, EnrichmentFlags flags, String ranking) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, flags, ranking); + } + + CompletableFuture> getEnrichedCustomActivities(Class type, Pagination pagination, Filter filter, EnrichmentFlags flags, String ranking) throws StreamException { + final RequestOption[] options = ranking == null + ? new RequestOption[] { pagination, filter, flags, DefaultOptions.DEFAULT_MARKER } + : new RequestOption[] { pagination, filter, flags, DefaultOptions.DEFAULT_MARKER, new Ranking(ranking) }; + return getClient() + .getActivities(getID(), options) + .thenApply(response -> { + try { + return deserializeContainer(response, type); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } +} diff --git a/src/main/java/io/getstream/cloud/CloudImageStorageClient.java b/src/main/java/io/getstream/cloud/CloudImageStorageClient.java new file mode 100644 index 00000000..b73e4b2b --- /dev/null +++ b/src/main/java/io/getstream/cloud/CloudImageStorageClient.java @@ -0,0 +1,41 @@ +package io.getstream.cloud; + +import io.getstream.core.StreamImages; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.options.Crop; +import io.getstream.core.options.Resize; + +import java.io.File; +import java.net.URL; +import java.util.concurrent.CompletableFuture; + +public final class CloudImageStorageClient { + private final Token token; + private final StreamImages images; + + CloudImageStorageClient(Token token, StreamImages images) { + this.token = token; + this.images = images; + } + + public CompletableFuture upload(String fileName, byte[] content) throws StreamException { + return images.upload(token, fileName, content); + } + + public CompletableFuture upload(File content) throws StreamException { + return images.upload(token, content); + } + + public CompletableFuture delete(URL url) throws StreamException { + return images.delete(token, url); + } + + public CompletableFuture process(URL url, Crop crop) throws StreamException { + return images.process(token, url, crop); + } + + public CompletableFuture process(URL url, Resize resize) throws StreamException { + return images.process(token, url, resize); + } +} diff --git a/src/main/java/io/getstream/cloud/CloudNotificationFeed.java b/src/main/java/io/getstream/cloud/CloudNotificationFeed.java new file mode 100644 index 00000000..24fd5226 --- /dev/null +++ b/src/main/java/io/getstream/cloud/CloudNotificationFeed.java @@ -0,0 +1,257 @@ +package io.getstream.cloud; + +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.models.Activity; +import io.getstream.core.models.EnrichedActivity; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.NotificationGroup; +import io.getstream.core.options.ActivityMarker; +import io.getstream.core.options.EnrichmentFlags; +import io.getstream.core.options.Filter; +import io.getstream.core.options.Pagination; +import io.getstream.core.utils.DefaultOptions; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static io.getstream.core.utils.Serialization.deserializeContainer; + +public final class CloudNotificationFeed extends CloudAggregatedFeed { + CloudNotificationFeed(CloudClient client, FeedID id) { + super(client, id); + } + + @Override + public CompletableFuture>> getActivities() throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + @Override + public CompletableFuture>> getActivities(Pagination pagination) throws StreamException { + return getActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + @Override + public CompletableFuture>> getActivities(Filter filter) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER); + } + + @Override + public CompletableFuture>> getActivities(ActivityMarker marker) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker); + } + + @Override + public CompletableFuture>> getActivities(Filter filter, ActivityMarker marker) throws StreamException { + return getActivities(DefaultOptions.DEFAULT_PAGINATION, filter, marker); + } + + @Override + public CompletableFuture>> getActivities(Pagination pagination, ActivityMarker marker) throws StreamException { + return getActivities(pagination, DefaultOptions.DEFAULT_FILTER, marker); + } + + @Override + CompletableFuture>> getActivities(Pagination pagination, Filter filter, ActivityMarker marker) throws StreamException { + return getClient() + .getActivities(getID(), pagination, filter, marker) + .thenApply(response -> { + try { + return deserializeContainer(response, NotificationGroup.class, Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture>> getCustomActivities(Class type) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + @Override + public CompletableFuture>> getCustomActivities(Class type, Pagination pagination) throws StreamException { + return getCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER); + } + + @Override + public CompletableFuture>> getCustomActivities(Class type, Filter filter) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER); + } + + @Override + public CompletableFuture>> getCustomActivities(Class type, ActivityMarker marker) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker); + } + + @Override + public CompletableFuture>> getCustomActivities(Class type, Filter filter, ActivityMarker marker) throws StreamException { + return getCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, marker); + } + + @Override + public CompletableFuture>> getCustomActivities(Class type, Pagination pagination, ActivityMarker marker) throws StreamException { + return getCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, marker); + } + + @Override + CompletableFuture>> getCustomActivities(Class type, Pagination pagination, Filter filter, ActivityMarker marker) throws StreamException { + return getClient() + .getActivities(getID(), pagination, filter, marker) + .thenApply(response -> { + try { + return deserializeContainer(response, NotificationGroup.class, type); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture>> getEnrichedActivities() throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedActivities(EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Pagination pagination) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Pagination pagination, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Filter filter) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Filter filter, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, flags); + } + + @Override + public CompletableFuture>> getEnrichedActivities(ActivityMarker marker) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedActivities(ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Filter filter, ActivityMarker marker) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(DefaultOptions.DEFAULT_PAGINATION, filter, marker, flags); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Pagination pagination, ActivityMarker marker) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedActivities(Pagination pagination, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedActivities(pagination, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + @Override + CompletableFuture>> getEnrichedActivities(Pagination pagination, Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getClient() + .getEnrichedActivities(getID(), pagination, filter, marker, flags) + .thenApply(response -> { + try { + return deserializeContainer(response, NotificationGroup.class, EnrichedActivity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, DefaultOptions.DEFAULT_MARKER, flags); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, DefaultOptions.DEFAULT_MARKER, flags); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, ActivityMarker marker) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter, ActivityMarker marker) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, DefaultOptions.DEFAULT_PAGINATION, filter, marker, flags); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, ActivityMarker marker) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, marker, DefaultOptions.DEFAULT_ENRICHMENT_FLAGS); + } + + @Override + public CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getEnrichedCustomActivities(type, pagination, DefaultOptions.DEFAULT_FILTER, marker, flags); + } + + @Override + CompletableFuture>> getEnrichedCustomActivities(Class type, Pagination pagination, Filter filter, ActivityMarker marker, EnrichmentFlags flags) throws StreamException { + return getClient() + .getEnrichedActivities(getID(), pagination, filter, marker, flags) + .thenApply(response -> { + try { + return deserializeContainer(response, NotificationGroup.class, type); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } +} diff --git a/src/main/java/io/getstream/cloud/CloudReactionsClient.java b/src/main/java/io/getstream/cloud/CloudReactionsClient.java new file mode 100644 index 00000000..c6aed665 --- /dev/null +++ b/src/main/java/io/getstream/cloud/CloudReactionsClient.java @@ -0,0 +1,109 @@ +package io.getstream.cloud; + +import com.google.common.collect.Iterables; +import io.getstream.core.LookupKind; +import io.getstream.core.StreamReactions; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.Token; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.Reaction; +import io.getstream.core.options.Filter; +import io.getstream.core.utils.DefaultOptions; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +public final class CloudReactionsClient { + private final Token token; + private final String userID; + private final StreamReactions reactions; + + CloudReactionsClient(Token token, String userID, StreamReactions reactions) { + this.token = token; + this.userID = userID; + this.reactions = reactions; + } + + public CompletableFuture get(String id) throws StreamException { + return reactions.get(token, id); + } + + public CompletableFuture> filter(LookupKind lookup, String id) throws StreamException { + return filter(lookup, id, ""); + } + + public CompletableFuture> filter(LookupKind lookup, String id, Filter filter) throws StreamException { + return filter(lookup, id, filter, ""); + } + + public CompletableFuture> filter(LookupKind lookup, String id, String kind) throws StreamException { + return filter(lookup, id, DefaultOptions.DEFAULT_FILTER, kind); + } + + public CompletableFuture> filter(LookupKind lookup, String id, Filter filter, String kind) throws StreamException { + return reactions.filter(token, lookup, id, filter, kind); + } + + public CompletableFuture add(String kind, String activityID, Iterable targetFeeds) throws StreamException { + return add(userID, kind, activityID, targetFeeds); + } + + public CompletableFuture add(String kind, String activityID, FeedID... targetFeeds) throws StreamException { + return add(userID, activityID, targetFeeds); + } + + public CompletableFuture add(Reaction reaction, Iterable targetFeeds) throws StreamException { + return add(userID, reaction, targetFeeds); + } + + public CompletableFuture add(Reaction reaction, FeedID... targetFeeds) throws StreamException { + return add(userID, reaction, targetFeeds); + } + + public CompletableFuture add(String userID, String kind, String activityID, Iterable targetFeeds) throws StreamException { + return add(userID, kind, activityID, Iterables.toArray(targetFeeds, FeedID.class)); + } + + public CompletableFuture add(String userID, String kind, String activityID, FeedID... targetFeeds) throws StreamException { + checkNotNull(kind, "Reaction kind can't be null"); + checkArgument(!kind.isEmpty(), "Reaction kind can't be empty"); + checkNotNull(activityID, "Reaction activity id can't be null"); + checkArgument(!activityID.isEmpty(), "Reaction activity id can't be empty"); + + return add(userID, Reaction.builder().activityID(activityID).kind(kind).build(), targetFeeds); + } + + public CompletableFuture add(String userID, Reaction reaction, Iterable targetFeeds) throws StreamException { + return add(userID, reaction, Iterables.toArray(targetFeeds, FeedID.class)); + } + + public CompletableFuture add(String userID, Reaction reaction, FeedID... targetFeeds) throws StreamException { + return reactions.add(token, userID, reaction, targetFeeds); + } + + public CompletableFuture update(String id, Iterable targetFeeds) throws StreamException { + return update(id, Iterables.toArray(targetFeeds, FeedID.class)); + } + + public CompletableFuture update(String id, FeedID... targetFeeds) throws StreamException { + checkNotNull(id, "Reaction id can't be null"); + checkArgument(!id.isEmpty(), "Reaction id can't be empty"); + + return update(Reaction.builder().id(id).build(), targetFeeds); + } + + public CompletableFuture update(Reaction reaction, Iterable targetFeeds) throws StreamException { + return update(reaction, Iterables.toArray(targetFeeds, FeedID.class)); + } + + public CompletableFuture update(Reaction reaction, FeedID... targetFeeds) throws StreamException { + return reactions.update(token, reaction, targetFeeds); + } + + public CompletableFuture delete(String id) throws StreamException { + return reactions.delete(token, id); + } +} diff --git a/src/main/java/io/getstream/cloud/CloudUser.java b/src/main/java/io/getstream/cloud/CloudUser.java new file mode 100644 index 00000000..8e661fc2 --- /dev/null +++ b/src/main/java/io/getstream/cloud/CloudUser.java @@ -0,0 +1,98 @@ +package io.getstream.cloud; + +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.models.Data; +import io.getstream.core.models.ProfileData; + +import java.io.IOException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Serialization.deserialize; +import static io.getstream.core.utils.Serialization.deserializeError; + +public final class CloudUser { + private final CloudClient client; + private final String id; + + public CloudUser(CloudClient client, String id) { + checkNotNull(client, "Client can't be null"); + checkNotNull(id, "User ID can't be null"); + checkArgument(!id.isEmpty(), "User ID can't be empty"); + + this.client = client; + this.id = id; + } + + public String getID() { + return id; + } + + public CompletableFuture get() throws StreamException { + return client.getUser(id) + .thenApply(response -> { + try { + return deserialize(response, Data.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture delete() throws StreamException { + return client.deleteUser(id) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture getOrCreate(Data data) throws StreamException { + return client.getOrCreateUser(id, data) + .thenApply(response -> { + try { + return deserialize(response, Data.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture create(Data data) throws StreamException { + return client.createUser(id, data) + .thenApply(response -> { + try { + return deserialize(response, Data.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture update(Data data) throws StreamException { + return client.updateUser(id, data) + .thenApply(response -> { + try { + return deserialize(response, Data.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } + + public CompletableFuture profile() throws StreamException { + return client.userProfile(id) + .thenApply(response -> { + try { + return deserialize(response, ProfileData.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } +} diff --git a/src/main/java/io/getstream/core/KeepHistory.java b/src/main/java/io/getstream/core/KeepHistory.java new file mode 100644 index 00000000..92ff2a86 --- /dev/null +++ b/src/main/java/io/getstream/core/KeepHistory.java @@ -0,0 +1,16 @@ +package io.getstream.core; + +public enum KeepHistory { + YES(true), + NO(false); + + private final boolean flag; + + KeepHistory(boolean flag) { + this.flag = flag; + } + + public boolean getFlag() { + return flag; + } +} diff --git a/src/main/java/io/getstream/core/LookupKind.java b/src/main/java/io/getstream/core/LookupKind.java new file mode 100644 index 00000000..a24dcc95 --- /dev/null +++ b/src/main/java/io/getstream/core/LookupKind.java @@ -0,0 +1,18 @@ +package io.getstream.core; + +public enum LookupKind { + ACTIVITY("activity_id"), + ACTIVITY_WITH_DATA("activity_id"), + REACTION("reaction_id"), + USER("user_id"); + + private final String kind; + + LookupKind(String kind) { + this.kind = kind; + } + + public String getKind() { + return kind; + } +} diff --git a/src/main/java/io/getstream/core/Region.java b/src/main/java/io/getstream/core/Region.java new file mode 100644 index 00000000..ce393e6a --- /dev/null +++ b/src/main/java/io/getstream/core/Region.java @@ -0,0 +1,20 @@ +package io.getstream.core; + +public enum Region { + US_EAST("us-east-api"), + TOKYO("tokyo-api"), + DUBLIN("dublin-api"), + SINGAPORE("singapore-api"), + CANADA("ca-central-1"); + + private final String region; + + Region(String region) { + this.region = region; + } + + @Override + public String toString() { + return region; + } +} diff --git a/src/main/java/io/getstream/core/Stream.java b/src/main/java/io/getstream/core/Stream.java new file mode 100644 index 00000000..9639fa72 --- /dev/null +++ b/src/main/java/io/getstream/core/Stream.java @@ -0,0 +1,369 @@ +package io.getstream.core; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.core.JsonProcessingException; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.HTTPClient; +import io.getstream.core.http.Response; +import io.getstream.core.http.Token; +import io.getstream.core.models.Activity; +import io.getstream.core.models.Data; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.OGData; +import io.getstream.core.options.CustomQueryParameter; +import io.getstream.core.options.RequestOption; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Arrays; +import java.util.Date; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Request.*; +import static io.getstream.core.utils.Routes.*; +import static io.getstream.core.utils.Serialization.deserialize; +import static io.getstream.core.utils.Serialization.toJSON; + +public final class Stream { + private final String key; + private final URL baseURL; + private final HTTPClient httpClient; + + public Stream(String key, URL baseURL, HTTPClient httpClient) { + this.key = key; + this.baseURL = baseURL; + this.httpClient = httpClient; + } + + public StreamBatch batch() { + return new StreamBatch(key, baseURL, httpClient); + } + + public StreamCollections collections() { + return new StreamCollections(key, baseURL, httpClient); + } + + public StreamPersonalization personalization() { + return new StreamPersonalization(key, baseURL, httpClient); + } + + public StreamAnalytics analytics() { + return new StreamAnalytics(key, baseURL, httpClient); + } + + public StreamReactions reactions() { + return new StreamReactions(key, baseURL, httpClient); + } + + public StreamFiles files() { + return new StreamFiles(key, baseURL, httpClient); + } + + public StreamImages images() { + return new StreamImages(key, baseURL, httpClient); + } + + public CompletableFuture updateActivityByID(Token token, String id, Map set, String[] unset) throws StreamException { + checkNotNull(id, "No activity to update"); + checkNotNull(set, "No activity properties to set"); + checkNotNull(unset, "No activity properties to unset"); + + try { + //XXX: renaming variables so we can unambiguously name payload fields 'id', 'set', 'unset' + String activityID = id; + Map propertiesToSet = set; + String[] propertiesToUnset = unset; + final byte[] payload = toJSON(new Object() { + public final String id = activityID; + public final Map set = propertiesToSet; + public final String[] unset = propertiesToUnset; + }); + final URL url = new URL(baseURL, "activity/"); + return httpClient.execute(buildPost(url, key, token, payload)) + .thenApply(response -> { + try { + return deserialize(response, Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture updateActivityByForeignID(Token token, String foreignID, Date timestamp, Map set, String[] unset) throws StreamException { + checkNotNull(foreignID, "No activity to update"); + checkNotNull(timestamp, "Missing timestamp"); + checkNotNull(set, "No activity properties to set"); + checkNotNull(unset, "No activity properties to unset"); + + try { + //XXX: renaming variables so we can unambiguously name payload fields 'set', 'unset' + Map propertiesToSet = set; + String[] propertiesToUnset = unset; + final byte[] payload = toJSON(new Object() { + public final String foreign_id = foreignID; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.S", timezone = "UTC") + public final Date time = timestamp; + public final Map set = propertiesToSet; + public final String[] unset = propertiesToUnset; + }); + final URL url = new URL(baseURL, "activity/"); + return httpClient.execute(buildPost(url, key, token, payload)) + .thenApply(response -> { + try { + return deserialize(response, Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture openGraph(Token token, URL targetURL) throws StreamException { + checkNotNull(targetURL, "Missing url"); + + try { + final URL url = buildOpenGraphURL(baseURL); + return httpClient.execute(buildGet(url, key, token, new CustomQueryParameter("url", targetURL.toExternalForm()))) + .thenApply(response -> { + try { + return deserialize(response, OGData.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public T getHTTPClientImplementation() { + return httpClient.getImplementation(); + } + + public CompletableFuture getActivities(Token token, FeedID feed, RequestOption... options) throws StreamException { + checkNotNull(options, "Missing request options"); + + try { + final URL url = buildFeedURL(baseURL, feed, "/"); + return httpClient.execute(buildGet(url, key, token, options)); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture getEnrichedActivities(Token token, FeedID feed, RequestOption... options) throws StreamException { + checkNotNull(options, "Missing request options"); + + try { + final URL url = buildEnrichedFeedURL(baseURL, feed, "/"); + return httpClient.execute(buildGet(url, key, token, options)); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture addActivity(Token token, FeedID feed, Activity activity) throws StreamException { + checkNotNull(activity, "No activity to add"); + + try { + final byte[] payload = toJSON(activity); + final URL url = buildFeedURL(baseURL, feed, "/"); + return httpClient.execute(buildPost(url, key, token, payload)); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture addActivities(Token token, FeedID feed, Activity... activityObjects) throws StreamException { + checkNotNull(activityObjects, "No activities to add"); + + try { + final byte[] payload = toJSON(new Object() { + public final Activity[] activities = activityObjects; + }); + final URL url = buildFeedURL(baseURL, feed, "/"); + return httpClient.execute(buildPost(url, key, token, payload)); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture removeActivityByID(Token token, FeedID feed, String id) throws StreamException { + checkNotNull(id, "No activity id to remove"); + + try { + final URL url = buildFeedURL(baseURL, feed, '/' + id + '/'); + return httpClient.execute(buildDelete(url, key, token)); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture removeActivityByForeignID(Token token, FeedID feed, String foreignID) throws StreamException { + checkNotNull(foreignID, "No activity id to remove"); + + try { + final URL url = buildFeedURL(baseURL, feed, '/' + foreignID + '/'); + return httpClient.execute(buildDelete(url, key, token, new CustomQueryParameter("foreign_id", "1"))); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture follow(Token token, Token targetToken, FeedID sourceFeed, FeedID targetFeed, int activityCopyLimit) throws StreamException { + checkNotNull(targetFeed, "No feed to follow"); + checkArgument(sourceFeed != targetFeed, "Feed can't follow itself"); + checkArgument(activityCopyLimit >= 0, "Activity copy limit should be a non-negative number"); + + try { + final byte[] payload = toJSON(new Object() { + public String target = targetFeed.toString(); + public int activity_copy_limit = activityCopyLimit; + public String target_token = targetToken.toString(); + }); + final URL url = buildFeedURL(baseURL, sourceFeed, "/following/"); + return httpClient.execute(buildPost(url, key, token, payload)); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture getFollowers(Token token, FeedID feed, RequestOption... options) throws StreamException { + checkNotNull(options, "Missing request options"); + + try { + final URL url = buildFeedURL(baseURL, feed, "/followers/"); + return httpClient.execute(buildGet(url, key, token, options)); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture getFollowed(Token token, FeedID feed, RequestOption... options) throws StreamException { + checkNotNull(options, "Missing request options"); + + try { + final URL url = buildFeedURL(baseURL, feed, "/following/"); + return httpClient.execute(buildGet(url, key, token, options)); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture unfollow(Token token, FeedID source, FeedID target, RequestOption... options) throws StreamException { + checkNotNull(options, "Missing request options"); + checkNotNull(target, "No target feed to unfollow"); + + try { + final URL url = buildFeedURL(baseURL, source, "/following/" + target + '/'); + return httpClient.execute(buildDelete(url, key, token, options)); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture updateActivityToTargets(Token token, FeedID feed, Activity activity, FeedID[] add, FeedID[] remove, FeedID[] replace) throws StreamException { + checkNotNull(activity, "No activity to update"); + checkNotNull(activity.getForeignID(), "Activity is required to have foreign ID attribute"); + checkNotNull(activity.getTime(), "Activity is required to have time attribute"); + checkNotNull(add, "No targets to add"); + checkNotNull(remove, "No targets to remove"); + checkNotNull(replace, "No targets to set"); + boolean modification = replace.length == 0 && (add.length > 0 || remove.length > 0); + boolean replacement = replace.length > 0 && add.length == 0 && remove.length == 0; + checkArgument(modification || replacement, "Can't replace and modify activity to targets at the same time"); + + final String[] addedTargets = Arrays.stream(add) + .map(id -> id.toString()) + .toArray(String[]::new); + final String[] removedTargets = Arrays.stream(remove) + .map(id -> id.toString()) + .toArray(String[]::new); + final String[] newTargets = Arrays.stream(replace) + .map(id -> id.toString()) + .toArray(String[]::new); + + try { + final byte[] payload = toJSON(new Object() { + public String foreign_id = activity.getForeignID(); + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.S", timezone = "UTC") + public Date time = activity.getTime(); + public String[] added_targets = addedTargets; + public String[] removed_targets = removedTargets; + public String[] new_targets = newTargets; + }); + final URL url = buildToTargetUpdateURL(baseURL, feed); + return httpClient.execute(buildPost(url, key, token, payload)); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture getUser(Token token, String id, boolean withFollowCounts) throws StreamException { + checkNotNull(id, "Missing user ID"); + checkArgument(!id.isEmpty(), "Missing user ID"); + + try { + final URL url = buildUsersURL(baseURL, id + '/'); + return httpClient.execute(buildGet(url, key, token, new CustomQueryParameter("with_follow_counts", Boolean.toString(withFollowCounts)))); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture deleteUser(Token token, String id) throws StreamException { + checkNotNull(id, "Missing user ID"); + checkArgument(!id.isEmpty(), "Missing user ID"); + + try { + final URL url = buildUsersURL(baseURL, id + '/'); + return httpClient.execute(buildDelete(url, key, token)); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture createUser(Token token, String userID, Data userData, boolean getOrCreate) throws StreamException { + checkNotNull(userID, "Missing user ID"); + checkNotNull(userData, "Missing user data"); + checkArgument(!userID.isEmpty(), "Missing user ID"); + + try { + final byte[] payload = toJSON(new Object() { + public String id = userID; + public Map data = userData.getData(); + }); + final URL url = buildUsersURL(baseURL); + return httpClient.execute(buildPost(url, key, token, payload, new CustomQueryParameter("get_or_create", Boolean.toString(getOrCreate)))); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture updateUser(Token token, String userID, Data userData) throws StreamException { + checkNotNull(userID, "Missing user ID"); + checkNotNull(userData, "Missing user data"); + checkArgument(!userID.isEmpty(), "Missing user ID"); + + try { + final byte[] payload = toJSON(new Object() { + public Map data = userData.getData(); + }); + final URL url = buildUsersURL(baseURL, userID + '/'); + return httpClient.execute(buildPut(url, key, token, payload)); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } +} diff --git a/src/main/java/io/getstream/core/StreamAnalytics.java b/src/main/java/io/getstream/core/StreamAnalytics.java new file mode 100644 index 00000000..f45b1a98 --- /dev/null +++ b/src/main/java/io/getstream/core/StreamAnalytics.java @@ -0,0 +1,93 @@ +package io.getstream.core; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.base.Charsets; +import com.google.common.collect.ObjectArrays; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.HTTPClient; +import io.getstream.core.http.Token; +import io.getstream.core.models.Engagement; +import io.getstream.core.models.Impression; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Request.buildPost; +import static io.getstream.core.utils.Routes.buildAnalyticsURL; +import static io.getstream.core.utils.Serialization.deserializeError; +import static io.getstream.core.utils.Serialization.toJSON; + +public final class StreamAnalytics { + private final String key; + private final URL baseURL; + private final HTTPClient httpClient; + + StreamAnalytics(String key, URL baseURL, HTTPClient httpClient) { + this.key = key; + this.baseURL = baseURL; + this.httpClient = httpClient; + } + + public CompletableFuture trackEngagement(Token token, Engagement... events) throws StreamException { + checkNotNull(events, "No events to track"); + checkArgument(events.length > 0, "No events to track"); + + try { + final byte[] payload = toJSON(new Object() { + public final Engagement[] content_list = events; + }); + final URL url = buildAnalyticsURL(baseURL, "engagement/"); + return httpClient.execute(buildPost(url, key, token, payload)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture trackImpression(Token token, Impression event) throws StreamException { + checkNotNull(event, "No events to track"); + + try { + final byte[] payload = toJSON(event); + final URL url = buildAnalyticsURL(baseURL, "impression/"); + return httpClient.execute(buildPost(url, key, token, payload)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public URL createRedirectURL(Token token, URL url, Impression[] impressions, Engagement[] engagements) throws StreamException { + try { + final byte[] events = toJSON(ObjectArrays.concat(impressions, engagements, Object.class)); + return HTTPClient.requestBuilder() + .url(buildAnalyticsURL(baseURL, "redirect/")) + .addQueryParameter("api_key", key) + .addQueryParameter("url", url.toExternalForm()) + .addQueryParameter("events", new String(events, Charsets.UTF_8)) + .addQueryParameter("auth_type", "jwt") + .addQueryParameter("authorization", token.toString()) + .build().getURL(); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } +} diff --git a/src/main/java/io/getstream/core/StreamBatch.java b/src/main/java/io/getstream/core/StreamBatch.java new file mode 100644 index 00000000..5dd3adca --- /dev/null +++ b/src/main/java/io/getstream/core/StreamBatch.java @@ -0,0 +1,183 @@ +package io.getstream.core; + +import com.fasterxml.jackson.core.JsonProcessingException; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.HTTPClient; +import io.getstream.core.http.Token; +import io.getstream.core.models.Activity; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.FollowRelation; +import io.getstream.core.models.ForeignIDTimePair; +import io.getstream.core.options.CustomQueryParameter; +import io.getstream.core.options.RequestOption; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Request.buildGet; +import static io.getstream.core.utils.Request.buildPost; +import static io.getstream.core.utils.Routes.buildActivitiesURL; +import static io.getstream.core.utils.Serialization.*; + +public final class StreamBatch { + private static final SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd"); + + private final String key; + private final URL baseURL; + private final HTTPClient httpClient; + + public StreamBatch(String key, URL baseURL, HTTPClient httpClient) { + this.key = key; + this.baseURL = baseURL; + this.httpClient = httpClient; + } + + public CompletableFuture addToMany(Token token, Activity activity, FeedID... feeds) throws StreamException { + checkNotNull(activity, "Missing activity"); + checkNotNull(feeds, "No feeds to add to"); + checkArgument(feeds.length > 0, "No feeds to add to"); + + //XXX: renaming the variable so we can unambiguously name payload field 'activity' + Activity data = activity; + String[] feedIDs = Arrays.stream(feeds).map(feed -> feed.toString()).toArray(String[]::new); + try { + final byte[] payload = toJSON(new Object() { + public final Activity activity = data; + public final String[] feed_ids = feedIDs; + }); + final URL url = new URL(baseURL, "feed/add_to_many/"); + return httpClient.execute(buildPost(url, key, token, payload)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture followMany(Token token, int activityCopyLimit, FollowRelation... follows) throws StreamException { + checkArgument(activityCopyLimit >= 0, "Activity copy limit must be non negative"); + checkNotNull(follows, "No feeds to follow"); + checkArgument(follows.length > 0, "No feeds to follow"); + + try { + final byte[] payload = toJSON(follows); + final URL url = new URL(baseURL, "follow_many/"); + return httpClient.execute(buildPost(url, key, token, payload, new CustomQueryParameter("activity_copy_limit", Integer.toString(activityCopyLimit)))) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture unfollowMany(Token token, FollowRelation... follows) throws StreamException { + checkNotNull(follows, "No feeds to unfollow"); + checkArgument(follows.length > 0, "No feeds to unfollow"); + + try { + final byte[] payload = toJSON(follows); + final URL url = new URL(baseURL, "unfollow_many/"); + return httpClient.execute(buildPost(url, key, token, payload)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture> getActivitiesByID(Token token, String... activityIDs) throws StreamException { + checkNotNull(activityIDs, "No activities to update"); + checkArgument(activityIDs.length > 0, "No activities to update"); + + try { + final URL url = buildActivitiesURL(baseURL); + return httpClient.execute(buildGet(url, key, token, new CustomQueryParameter("ids", String.join(",", activityIDs)))) + .thenApply(response -> { + try { + return deserializeContainer(response, Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture> getActivitiesByForeignID(Token token, ForeignIDTimePair... activityIDTimePairs) throws StreamException { + checkNotNull(activityIDTimePairs, "No activities to get"); + checkArgument(activityIDTimePairs.length > 0, "No activities to get"); + + String[] foreignIDs = Arrays.stream(activityIDTimePairs) + .map(pair -> pair.getForeignID()) + .toArray(String[]::new); + String[] timestamps = Arrays.stream(activityIDTimePairs) + .map(pair -> timestampFormat.format(pair.getTime())) + .toArray(String[]::new); + try { + final URL url = buildActivitiesURL(baseURL); + final RequestOption[] options = new RequestOption[]{ + new CustomQueryParameter("foreign_ids", String.join(",", foreignIDs)), + new CustomQueryParameter("timestamps", String.join(",", timestamps)) + }; + return httpClient.execute(buildGet(url, key, token, options)) + .thenApply(response -> { + try { + return deserializeContainer(response, Activity.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture updateActivities(Token token, Activity... activities) throws StreamException { + checkNotNull(activities, "No activities to update"); + checkArgument(activities.length > 0, "No activities to update"); + + try { + //XXX: renaming the variable so we can unambiguously name payload field 'activities' + Activity[] data = activities; + final byte[] payload = toJSON(new Object() { + public final Activity[] activities = data; + }); + final URL url = buildActivitiesURL(baseURL); + return httpClient.execute(buildPost(url, key, token, payload)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } +} diff --git a/src/main/java/io/getstream/core/StreamCollections.java b/src/main/java/io/getstream/core/StreamCollections.java new file mode 100644 index 00000000..6478b8a8 --- /dev/null +++ b/src/main/java/io/getstream/core/StreamCollections.java @@ -0,0 +1,226 @@ +package io.getstream.core; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.collect.ImmutableMap; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.HTTPClient; +import io.getstream.core.http.Token; +import io.getstream.core.models.CollectionData; +import io.getstream.core.options.CustomQueryParameter; +import io.getstream.core.options.RequestOption; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.stream.Collectors; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Request.*; +import static io.getstream.core.utils.Routes.buildBatchCollectionsURL; +import static io.getstream.core.utils.Routes.buildCollectionsURL; +import static io.getstream.core.utils.Serialization.*; + +public final class StreamCollections { + private final String key; + private final URL baseURL; + private final HTTPClient httpClient; + + StreamCollections(String key, URL baseURL, HTTPClient httpClient) { + this.key = key; + this.baseURL = baseURL; + this.httpClient = httpClient; + } + + public CompletableFuture add(Token token, String userID, String collection, CollectionData item) throws StreamException { + checkNotNull(collection, "Collection name can't be null"); + checkArgument(!collection.isEmpty(), "Collection name can't be empty"); + checkNotNull(item, "Collection data can't be null"); + + try { + ImmutableMap.Builder builder = new ImmutableMap.Builder() + .put("data", item.getData()); + if (userID != null) { + builder.put("user_id", userID); + } + if (item.getID() != null) { + builder.put("id", item.getID()); + } + final byte[] payload = toJSON(builder.build()); + final URL url = buildCollectionsURL(baseURL, collection + '/'); + return httpClient.execute(buildPost(url, key, token, payload)) + .thenApply(response -> { + try { + return deserialize(response, CollectionData.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture update(Token token, String userID, String collection, CollectionData item) throws StreamException { + checkNotNull(collection, "Collection name can't be null"); + checkArgument(!collection.isEmpty(), "Collection name can't be empty"); + checkNotNull(item, "Collection data can't be null"); + + try { + ImmutableMap.Builder builder = new ImmutableMap.Builder() + .put("data", item.getData()); + if (userID != null) { + builder.put("user_id", userID); + } + final byte[] payload = toJSON(builder.build()); + final URL url = buildCollectionsURL(baseURL, collection + '/' + item.getID() + '/'); + return httpClient.execute(buildPut(url, key, token, payload)) + .thenApply(response -> { + try { + return deserialize(response, CollectionData.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture upsert(Token token, String collection, CollectionData... items) throws StreamException { + checkNotNull(collection, "Collection name can't be null"); + checkArgument(!collection.isEmpty(), "Collection name can't be empty"); + checkArgument(items.length > 0, "Collection data can't be empty"); + + try { + final byte[] payload = toJSON(new Object() { + public final Map data = ImmutableMap.of(collection, items); + }); + final URL url = buildBatchCollectionsURL(baseURL); + return httpClient.execute(buildPost(url, key, token, payload)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture> items(Token token, String collection) throws StreamException { + checkNotNull(collection, "Collection name can't be null"); + checkArgument(!collection.isEmpty(), "Collection name can't be empty"); + + try { + final URL url = buildCollectionsURL(baseURL, collection + '/'); + return httpClient.execute(buildGet(url, key, token)) + .thenApply(response -> { + try { + return deserializeContainer(response, CollectionData.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture get(Token token, String collection, String id) throws StreamException { + checkNotNull(collection, "Collection name can't be null"); + checkArgument(!collection.isEmpty(), "Collection name can't be empty"); + checkNotNull(id, "Collection id can't be null"); + checkArgument(!id.isEmpty(), "Collection id can't be empty"); + + try { + final URL url = buildCollectionsURL(baseURL, collection + '/' + id + '/'); + return httpClient.execute(buildGet(url, key, token)) + .thenApply(response -> { + try { + return deserialize(response, CollectionData.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture> select(Token token, String collection, String... ids) throws StreamException { + checkNotNull(collection, "Collection name can't be null"); + checkArgument(!collection.isEmpty(), "Collection name can't be empty"); + checkArgument(ids.length > 0, "Collection ids can't be empty"); + + List foreignIDs = Arrays.stream(ids) + .map(id -> String.format("%s:%s", collection, id)) + .collect(Collectors.toList()); + try { + final URL url = buildBatchCollectionsURL(baseURL); + return httpClient.execute(buildGet(url, key, token, new CustomQueryParameter("foreign_ids", String.join(",", foreignIDs)))) + .thenApply(response -> { + try { + return deserializeContainer(response, "response.data", CollectionData.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture delete(Token token, String collection, String id) throws StreamException { + checkNotNull(collection, "Collection name can't be null"); + checkArgument(!collection.isEmpty(), "Collection name can't be empty"); + checkNotNull(id, "Collection id can't be null"); + checkArgument(!id.isEmpty(), "Collection id can't be empty"); + + try { + final URL url = buildCollectionsURL(baseURL, collection + '/' + id + '/'); + return httpClient.execute(buildDelete(url, key, token)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture deleteMany(Token token, String collection, String... ids) throws StreamException { + checkNotNull(collection, "Collection name can't be null"); + checkArgument(!collection.isEmpty(), "Collection name can't be empty"); + checkArgument(ids.length > 0, "Collection ids can't be empty"); + + try { + final URL url = buildBatchCollectionsURL(baseURL); + final RequestOption[] options = new RequestOption[] { + new CustomQueryParameter("collection_name", collection), + new CustomQueryParameter("ids", String.join(",", ids)) + }; + return httpClient.execute(buildDelete(url, key, token, options)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } +} diff --git a/src/main/java/io/getstream/core/StreamFiles.java b/src/main/java/io/getstream/core/StreamFiles.java new file mode 100644 index 00000000..cf35d2a6 --- /dev/null +++ b/src/main/java/io/getstream/core/StreamFiles.java @@ -0,0 +1,90 @@ +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.options.CustomQueryParameter; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Request.buildDelete; +import static io.getstream.core.utils.Request.buildMultiPartPost; +import static io.getstream.core.utils.Routes.buildFilesURL; +import static io.getstream.core.utils.Serialization.deserialize; +import static io.getstream.core.utils.Serialization.deserializeError; + +public class StreamFiles { + private final String key; + private final URL baseURL; + private final HTTPClient httpClient; + + StreamFiles(String key, URL baseURL, HTTPClient httpClient) { + this.key = key; + this.baseURL = baseURL; + this.httpClient = httpClient; + } + + public CompletableFuture upload(Token token, String fileName, byte[] content) throws StreamException { + checkNotNull(content, "No data to upload"); + checkArgument(content.length > 0, "No data to upload"); + + try { + final URL url = buildFilesURL(baseURL); + return httpClient.execute(buildMultiPartPost(url, key, token, fileName, content)) + .thenApply(response -> { + try { + return deserialize(response, "file", URL.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture upload(Token token, File content) throws StreamException { + checkNotNull(content, "No file to upload"); + checkArgument(content.exists(), "No file to upload"); + + try { + final URL url = buildFilesURL(baseURL); + return httpClient.execute(buildMultiPartPost(url, key, token, content)) + .thenApply(response -> { + try { + return deserialize(response, "file", URL.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture delete(Token token, URL targetURL) throws StreamException { + checkNotNull(targetURL, "No file to delete"); + + try { + final URL url = buildFilesURL(baseURL); + return httpClient.execute(buildDelete(url, key, token, new CustomQueryParameter("url", targetURL.toExternalForm()))) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } +} diff --git a/src/main/java/io/getstream/core/StreamImages.java b/src/main/java/io/getstream/core/StreamImages.java new file mode 100644 index 00000000..662d1ac6 --- /dev/null +++ b/src/main/java/io/getstream/core/StreamImages.java @@ -0,0 +1,108 @@ +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.options.CustomQueryParameter; +import io.getstream.core.options.RequestOption; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Request.*; +import static io.getstream.core.utils.Routes.buildImagesURL; +import static io.getstream.core.utils.Serialization.deserialize; +import static io.getstream.core.utils.Serialization.deserializeError; + +public class StreamImages { + private final String key; + private final URL baseURL; + private final HTTPClient httpClient; + + StreamImages(String key, URL baseURL, HTTPClient httpClient) { + this.key = key; + this.baseURL = baseURL; + this.httpClient = httpClient; + } + + public CompletableFuture upload(Token token, String fileName, byte[] content) throws StreamException { + checkNotNull(content, "No data to upload"); + checkArgument(content.length > 0, "No data to upload"); + + try { + final URL url = buildImagesURL(baseURL); + return httpClient.execute(buildMultiPartPost(url, key, token, fileName, content)) + .thenApply(response -> { + try { + return deserialize(response, "file", URL.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture upload(Token token, File content) throws StreamException { + checkNotNull(content, "No file to upload"); + checkArgument(content.exists(), "No file to upload"); + + try { + final URL url = buildImagesURL(baseURL); + return httpClient.execute(buildMultiPartPost(url, key, token, content)) + .thenApply(response -> { + try { + return deserialize(response, "file", URL.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture delete(Token token, URL targetURL) throws StreamException { + checkNotNull(targetURL, "No image to delete"); + + try { + final URL url = buildImagesURL(baseURL); + return httpClient.execute(buildDelete(url, key, token, new CustomQueryParameter("url", targetURL.toExternalForm()))) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture process(Token token, URL targetURL, RequestOption option) throws StreamException { + checkNotNull(targetURL, "No image to process"); + + try { + final URL url = buildImagesURL(baseURL); + return httpClient.execute(buildGet(url, key, token, option, new CustomQueryParameter("url", targetURL.toExternalForm()))) + .thenApply(response -> { + try { + return deserialize(response, "file", URL.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } +} diff --git a/src/main/java/io/getstream/core/StreamPersonalization.java b/src/main/java/io/getstream/core/StreamPersonalization.java new file mode 100644 index 00000000..929d24b7 --- /dev/null +++ b/src/main/java/io/getstream/core/StreamPersonalization.java @@ -0,0 +1,108 @@ +package io.getstream.core; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.HTTPClient; +import io.getstream.core.http.Token; +import io.getstream.core.options.CustomQueryParameter; +import io.getstream.core.options.RequestOption; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Request.*; +import static io.getstream.core.utils.Routes.buildPersonalizationURL; +import static io.getstream.core.utils.Serialization.*; + +public final class StreamPersonalization { + private final String key; + private final URL baseURL; + private final HTTPClient httpClient; + + StreamPersonalization(String key, URL baseURL, HTTPClient httpClient) { + this.key = key; + this.baseURL = baseURL; + this.httpClient = httpClient; + } + + public CompletableFuture> get(Token token, String userID, String resource, Map params) throws StreamException { + checkNotNull(resource, "Resource can't be empty"); + checkArgument(!resource.isEmpty(), "Resource can't be empty"); + checkNotNull(params, "Missing params"); + + try { + final URL url = buildPersonalizationURL(baseURL, resource + '/'); + final RequestOption[] options = params.entrySet().stream() + .map(entry -> new CustomQueryParameter(entry.getKey(), entry.getValue().toString())) + .toArray(RequestOption[]::new); + return httpClient.execute(buildGet(url, key, token, options)) + .thenApply(response -> { + try { + return deserialize(response, new TypeReference>() {}); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture post(Token token, String userID, String resource, Map params, Map payload) throws StreamException { + checkNotNull(resource, "Resource can't be empty"); + checkArgument(!resource.isEmpty(), "Resource can't be empty"); + checkNotNull(params, "Missing params"); + checkNotNull(params, "Missing payload"); + + try { + final byte[] jsonPayload = toJSON(new Object() { + public final Map data = payload; + }); + final URL url = buildPersonalizationURL(baseURL, resource + '/'); + final RequestOption[] options = params.entrySet().stream() + .map(entry -> new CustomQueryParameter(entry.getKey(), entry.getValue().toString())) + .toArray(RequestOption[]::new); + return httpClient.execute(buildPost(url, key, token, jsonPayload, options)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture delete(Token token, String userID, String resource, Map params) throws StreamException { + checkNotNull(resource, "Resource can't be empty"); + checkArgument(!resource.isEmpty(), "Resource can't be empty"); + checkNotNull(params, "Missing params"); + + try { + final URL url = buildPersonalizationURL(baseURL, resource + '/'); + final RequestOption[] options = params.entrySet().stream() + .map(entry -> new CustomQueryParameter(entry.getKey(), entry.getValue().toString())) + .toArray(RequestOption[]::new); + return httpClient.execute(buildDelete(url, key, token, options)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } +} diff --git a/src/main/java/io/getstream/core/StreamReactions.java b/src/main/java/io/getstream/core/StreamReactions.java new file mode 100644 index 00000000..47089620 --- /dev/null +++ b/src/main/java/io/getstream/core/StreamReactions.java @@ -0,0 +1,182 @@ +package io.getstream.core; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.collect.ImmutableMap; +import io.getstream.core.exceptions.StreamException; +import io.getstream.core.http.HTTPClient; +import io.getstream.core.http.Token; +import io.getstream.core.models.FeedID; +import io.getstream.core.models.Reaction; +import io.getstream.core.options.CustomQueryParameter; +import io.getstream.core.options.Filter; +import io.getstream.core.options.RequestOption; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import static com.google.common.base.MoreObjects.firstNonNull; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Request.*; +import static io.getstream.core.utils.Routes.buildReactionsURL; +import static io.getstream.core.utils.Serialization.*; + +public final class StreamReactions { + private final String key; + private final URL baseURL; + private final HTTPClient httpClient; + + StreamReactions(String key, URL baseURL, HTTPClient httpClient) { + this.key = key; + this.baseURL = baseURL; + this.httpClient = httpClient; + } + + public CompletableFuture get(Token token, String id) throws StreamException { + checkNotNull(id, "Reaction id can't be null"); + checkArgument(!id.isEmpty(), "Reaction id can't be empty"); + + try { + final URL url = buildReactionsURL(baseURL, id + '/'); + return httpClient.execute(buildGet(url, key, token)) + .thenApply(response -> { + try { + return deserialize(response, Reaction.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture> filter(Token token, LookupKind lookup, String id, Filter filter, String kind) throws StreamException { + checkNotNull(lookup, "Lookup kind can't be null"); + checkNotNull(id, "Reaction ID can't be null"); + checkArgument(!id.isEmpty(), "Reaction ID can't be empty"); + checkNotNull(filter, "Filter can't be null"); + checkNotNull(kind, "Kind can't be null"); + + try { + final URL url = buildReactionsURL(baseURL, lookup.getKind() + '/' + id + '/'); + RequestOption reactionType = new CustomQueryParameter("kind", kind); + RequestOption withActivityData = new CustomQueryParameter("with_activity_data", Boolean.toString(lookup == LookupKind.ACTIVITY_WITH_DATA)); + return httpClient.execute(buildGet(url, key, token, filter, reactionType, withActivityData)) + .thenApply(response -> { + try { + return deserializeContainer(response, Reaction.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture add(Token token, String userID, Reaction reaction, FeedID... targetFeeds) throws StreamException { + checkNotNull(reaction, "Reaction can't be null"); + checkArgument(reaction.getActivityID() != null || reaction.getParent() != null, "Reaction has to either have and activity ID or parent"); + checkArgument(reaction.getActivityID() == null || reaction.getParent() == null, "Reaction can't have both activity ID and parent"); + if (reaction.getActivityID() != null) { + checkArgument(!reaction.getActivityID().isEmpty(), "Reaction activity ID can't be empty"); + } + if (reaction.getParent() != null) { + checkArgument(!reaction.getParent().isEmpty(), "Reaction parent can't be empty"); + } + checkNotNull(reaction.getKind(), "Reaction kind can't be null"); + checkArgument(!reaction.getKind().isEmpty(), "Reaction kind can't be empty"); + + String[] targetFeedIDs = Arrays.stream(targetFeeds) + .map(feed -> feed.toString()) + .toArray(String[]::new); + + try { + ImmutableMap.Builder payloadBuilder = ImmutableMap.builder(); + payloadBuilder.put("kind", reaction.getKind()); + payloadBuilder.put("target_feeds", targetFeedIDs); + if (reaction.getActivityID() != null) { + payloadBuilder.put("activity_id", reaction.getActivityID()); + } + if (userID != null || reaction.getUserID() != null) { + payloadBuilder.put("user_id", firstNonNull(userID, reaction.getUserID())); + } + if (reaction.getParent() != null) { + payloadBuilder.put("parent", reaction.getParent()); + } + if (reaction.getId() != null) { + payloadBuilder.put("id", reaction.getId()); + } + if (reaction.getExtra() != null) { + payloadBuilder.put("data", reaction.getExtra()); + } + final byte[] payload = toJSON(payloadBuilder.build()); + final URL url = buildReactionsURL(baseURL); + return httpClient.execute(buildPost(url, key, token, payload)) + .thenApply(response -> { + try { + return deserialize(response, Reaction.class); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture update(Token token, Reaction reaction, FeedID... targetFeeds) throws StreamException { + checkNotNull(reaction, "Reaction can't be null"); + checkNotNull(reaction.getId(), "Reaction id can't be null"); + checkArgument(!reaction.getId().isEmpty(), "Reaction id can't be empty"); + + String[] targetFeedIDs = Arrays.stream(targetFeeds) + .map(feed -> feed.toString()) + .toArray(String[]::new); + + try { + final byte[] payload = toJSON(new Object() { + public final Map data = reaction.getExtra(); + public final String[] target_feeds = targetFeedIDs; + }); + final URL url = buildReactionsURL(baseURL, reaction.getId() + '/'); + return httpClient.execute(buildPut(url, key, token, payload)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (JsonProcessingException | MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } + + public CompletableFuture delete(Token token, String id) throws StreamException { + checkNotNull(id, "Reaction id can't be null"); + checkArgument(!id.isEmpty(), "Reaction id can't be empty"); + + try { + final URL url = buildReactionsURL(baseURL, id + '/'); + return httpClient.execute(buildDelete(url, key, token)) + .thenApply(response -> { + try { + return deserializeError(response); + } catch (StreamException | IOException e) { + throw new CompletionException(e); + } + }); + } catch (MalformedURLException | URISyntaxException e) { + throw new StreamException(e); + } + } +} diff --git a/src/main/java/io/getstream/core/exceptions/StreamAPIException.java b/src/main/java/io/getstream/core/exceptions/StreamAPIException.java new file mode 100644 index 00000000..ec8f15db --- /dev/null +++ b/src/main/java/io/getstream/core/exceptions/StreamAPIException.java @@ -0,0 +1,60 @@ +package io.getstream.core.exceptions; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public final class StreamAPIException extends StreamException { + private final int errorCode; + private final int statusCode; + private final String errorName; + + @JsonCreator + public StreamAPIException( + @JsonProperty("detail") String message, + @JsonProperty("code") int errorCode, + @JsonProperty("status_code") int statusCode, + @JsonProperty("exception") String errorName) { + super(formatMessage(message, errorName, errorCode, statusCode)); + + this.errorCode = errorCode; + this.statusCode = statusCode; + this.errorName = errorName; + } + + private static String formatMessage(String message, String errorName, int errorCode, int statusCode) { + StringBuilder result = new StringBuilder(); + if (errorName != null && !errorName.isEmpty()) { + result.append(errorName); + } + if (message != null && !message.isEmpty()) { + if (result.length() > 0) { + result.append(": "); + } + + result.append(message); + } + if (result.length() > 0) { + result.append(" "); + } + result.append("(code = "); + result.append(errorCode); + result.append(" status = "); + result.append(statusCode); + result.append(')'); + return result.toString(); + } + + public int getErrorCode() { + return errorCode; + } + + public int getStatusCode() { + return statusCode; + } + + public String getErrorName() { + return errorName; + } +} diff --git a/src/main/java/io/getstream/core/exceptions/StreamException.java b/src/main/java/io/getstream/core/exceptions/StreamException.java new file mode 100644 index 00000000..e9a027d8 --- /dev/null +++ b/src/main/java/io/getstream/core/exceptions/StreamException.java @@ -0,0 +1,23 @@ +package io.getstream.core.exceptions; + +public class StreamException extends Exception { + public StreamException() { + super(); + } + + public StreamException(String message) { + super(message); + } + + public StreamException(String message, Throwable cause) { + super(message, cause); + } + + public StreamException(Throwable cause) { + super(cause); + } + + protected StreamException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/io/getstream/core/http/HTTPClient.java b/src/main/java/io/getstream/core/http/HTTPClient.java new file mode 100644 index 00000000..b699849e --- /dev/null +++ b/src/main/java/io/getstream/core/http/HTTPClient.java @@ -0,0 +1,12 @@ +package io.getstream.core.http; + +import java.util.concurrent.CompletableFuture; + +public abstract class HTTPClient { + public static Request.Builder requestBuilder() { + return Request.builder(); + } + + public abstract T getImplementation(); + public abstract CompletableFuture execute(Request request); +} diff --git a/src/main/java/io/getstream/core/http/OKHTTPClientAdapter.java b/src/main/java/io/getstream/core/http/OKHTTPClientAdapter.java new file mode 100644 index 00000000..cd3739ce --- /dev/null +++ b/src/main/java/io/getstream/core/http/OKHTTPClientAdapter.java @@ -0,0 +1,114 @@ +package io.getstream.core.http; + +import io.getstream.core.utils.Info; +import okhttp3.*; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URLConnection; +import java.util.concurrent.CompletableFuture; + +import static com.google.common.base.Preconditions.checkNotNull; + +public final class OKHTTPClientAdapter extends HTTPClient { + private static final String userAgentTemplate = "okhttp3 stream-java2 %s v%s"; + + private final OkHttpClient client; + + public OKHTTPClientAdapter() { + this.client = new OkHttpClient.Builder() + .followRedirects(false) + .followSslRedirects(false) + .build(); + } + + public OKHTTPClientAdapter(OkHttpClient client) { + checkNotNull(client); + this.client = client; + } + + @Override + public T getImplementation() { + return (T) client; + } + + private okhttp3.RequestBody buildOkHttpRequestBody(io.getstream.core.http.RequestBody body) { + okhttp3.RequestBody okBody = null; + MediaType mediaType; + switch (body.getType()) { + case JSON: + mediaType = MediaType.parse(body.getType().toString()); + okBody = okhttp3.RequestBody.create(mediaType, body.getBytes()); + break; + case MULTI_PART: + String mimeType = URLConnection.guessContentTypeFromName(body.getFileName()); + mediaType = MediaType.parse(mimeType); + MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM); + if (body.getBytes() != null) { + builder.addFormDataPart("file", body.getFileName(), okhttp3.RequestBody.create(mediaType, body.getBytes())); + } else { + builder.addFormDataPart("file", body.getFileName(), okhttp3.RequestBody.create(mediaType, body.getFile())); + } + okBody = builder.build(); + break; + } + return okBody; + } + + private okhttp3.Request buildOkHttpRequest(io.getstream.core.http.Request request) { + String version = Info.getProperties().getProperty(Info.VERSION); + String userAgent = String.format(userAgentTemplate, System.getProperty("os.name"), version); + okhttp3.Request.Builder builder = new okhttp3.Request.Builder() + .url(request.getURL()) + .addHeader("Stream-Auth-Type", "jwt") + .addHeader("Authorization", request.getToken().toString()) + .addHeader("User-Agent", userAgent); + + MediaType mediaType; + switch (request.getMethod()) { + case GET: + builder.get(); + break; + case DELETE: + builder.delete(); + break; + case PUT: + builder.put(buildOkHttpRequestBody(request.getBody())); + break; + case POST: + builder.post(buildOkHttpRequestBody(request.getBody())); + break; + } + return builder.build(); + } + + private io.getstream.core.http.Response buildResponse(okhttp3.Response response) { + final InputStream body = response.body() != null ? response.body().byteStream() : null; + return new io.getstream.core.http.Response(response.code(), body); + } + + @Override + public CompletableFuture execute(io.getstream.core.http.Request request) { + final CompletableFuture result = new CompletableFuture<>(); + + client.newCall(buildOkHttpRequest(request)).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + result.completeExceptionally(e); + } + + @Override + public void onResponse(Call call, okhttp3.Response response) { + io.getstream.core.http.Response httpResponse = buildResponse(response); + try (InputStream ignored = httpResponse.getBody()){ + result.complete(httpResponse); + } catch (Exception e) { + result.completeExceptionally(e); + } + } + }); + + return result; + } +} + diff --git a/src/main/java/io/getstream/core/http/Request.java b/src/main/java/io/getstream/core/http/Request.java new file mode 100644 index 00000000..b16629db --- /dev/null +++ b/src/main/java/io/getstream/core/http/Request.java @@ -0,0 +1,157 @@ +package io.getstream.core.http; + +import com.google.common.base.MoreObjects; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Objects; + +public final class Request { + private final Token token; + private final URL url; + private final Method method; + private final RequestBody body; + + private Request(Builder builder) throws MalformedURLException { + token = builder.token; + url = builder.uri.toURL(); + method = builder.method; + body = builder.body; + } + + public Token getToken() { + return token; + } + + public URL getURL() { + return url; + } + + public Method getMethod() { + return method; + } + + public RequestBody getBody() { + return body; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Request request = (Request) o; + return Objects.equals(token, request.token) && + Objects.equals(url, request.url) && + method == request.method && + Objects.equals(body, request.body); + } + + @Override + public int hashCode() { + return Objects.hash(token, url, method, body); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("token", this.token) + .add("url", this.url) + .add("method", this.method) + .add("body", this.body) + .toString(); + } + + public static Builder builder() { + return new Builder(); + } + + public enum Method { + GET, + POST, + PUT, + DELETE + } + + public static final class Builder { + private Token token; + private URI uri; + private StringBuilder query; + private Method method; + private RequestBody body; + + public Builder token(Token token) { + this.token = token; + return this; + } + + public Builder url(URL url) throws URISyntaxException { + uri = url.toURI(); + if (uri.getQuery() != null) { + query = new StringBuilder(uri.getQuery()); + } else { + query = new StringBuilder(); + } + return this; + } + + public Builder addQueryParameter(String key, String value) { + if (query.length() > 0) { + query.append('&'); + } + query.append(key); + query.append('='); + query.append(value); + return this; + } + + public Builder get() { + this.method = Method.GET; + this.body = null; + return this; + } + + public Builder post(byte[] body) { + this.method = Method.POST; + this.body = new RequestBody(body, RequestBody.Type.JSON); + return this; + } + + public Builder multiPartPost(String fileName, byte[] body) { + this.method = Method.POST; + this.body = new RequestBody(fileName, body, RequestBody.Type.MULTI_PART); + return this; + } + + public Builder multiPartPost(File body) { + this.method = Method.POST; + this.body = new RequestBody(body, RequestBody.Type.MULTI_PART); + return this; + } + + public Builder put(byte[] body) { + this.method = Method.PUT; + this.body = new RequestBody(body, RequestBody.Type.JSON); + return this; + } + + public Builder delete() { + this.method = Method.DELETE; + this.body = null; + return this; + } + + public Request build() throws MalformedURLException, URISyntaxException { + this.uri = new URI(uri.getScheme(), + uri.getUserInfo(), + uri.getHost(), + uri.getPort(), + uri.getPath(), + query.toString(), + null); + return new Request(this); + } + } +} diff --git a/src/main/java/io/getstream/core/http/RequestBody.java b/src/main/java/io/getstream/core/http/RequestBody.java new file mode 100644 index 00000000..515d08a5 --- /dev/null +++ b/src/main/java/io/getstream/core/http/RequestBody.java @@ -0,0 +1,93 @@ +package io.getstream.core.http; + +import com.google.common.base.MoreObjects; + +import java.io.File; +import java.util.Arrays; +import java.util.Objects; + +public final class RequestBody { + public enum Type { + JSON("application/json"), + MULTI_PART("multipart/form-data"); + + private final String type; + + Type(String type) { + this.type = type; + } + + @Override + public String toString() { + return type; + } + } + + private final Type type; + private final byte[] bytes; + private final File file; + private final String fileName; + + RequestBody(byte[] bytes, Type type) { + this.type = type; + this.bytes = bytes; + this.file = null; + this.fileName = null; + } + + RequestBody(String fileName, byte[] bytes, Type type) { + this.type = type; + this.bytes = bytes; + this.file = null; + this.fileName = fileName; + } + + RequestBody(File file, Type type) { + this.type = type; + this.bytes = null; + this.file = file; + this.fileName = file.getName(); + } + + public Type getType() { + return type; + } + + public byte[] getBytes() { + return bytes; + } + + public File getFile() { + return file; + } + + public String getFileName() { + return fileName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RequestBody that = (RequestBody) o; + return type == that.type && + Arrays.equals(bytes, that.bytes) && + Objects.equals(file, that.file); + } + + @Override + public int hashCode() { + int result = Objects.hash(type, file); + result = 31 * result + Arrays.hashCode(bytes); + return result; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(RequestBody.class) + .add("type", type) + .add("bytes", bytes) + .add("file", file) + .toString(); + } +} diff --git a/src/main/java/io/getstream/core/http/Response.java b/src/main/java/io/getstream/core/http/Response.java new file mode 100644 index 00000000..c530059f --- /dev/null +++ b/src/main/java/io/getstream/core/http/Response.java @@ -0,0 +1,49 @@ +package io.getstream.core.http; + +import com.google.common.base.MoreObjects; + +import java.io.InputStream; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; + +public final class Response { + private final int code; + private final InputStream body; + + public Response(int code, InputStream body) { + checkArgument(code >= 100 && code <= 599, "Invalid HTTP status code"); + this.code = code; + this.body = body; + } + + public int getCode() { + return code; + } + + public InputStream getBody() { + return body; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Response response = (Response) o; + return code == response.code && + Objects.equals(body, response.body); + } + + @Override + public int hashCode() { + return Objects.hash(code, body); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("code", this.code) + .add("body", this.body) + .toString(); + } +} diff --git a/src/main/java/io/getstream/core/http/Token.java b/src/main/java/io/getstream/core/http/Token.java new file mode 100644 index 00000000..32a294b8 --- /dev/null +++ b/src/main/java/io/getstream/core/http/Token.java @@ -0,0 +1,35 @@ +package io.getstream.core.http; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +public final class Token { + private final String token; + + public Token(String token) { + checkNotNull(token, "Token can't be null"); + checkArgument(!token.isEmpty(), "Token can't be null"); + + this.token = token; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Token token1 = (Token) o; + return Objects.equals(token, token1.token); + } + + @Override + public int hashCode() { + return Objects.hash(token); + } + + @Override + public String toString() { + return token; + } +} diff --git a/src/main/java/io/getstream/core/models/Activity.java b/src/main/java/io/getstream/core/models/Activity.java new file mode 100644 index 00000000..3644e633 --- /dev/null +++ b/src/main/java/io/getstream/core/models/Activity.java @@ -0,0 +1,265 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Serialization.convert; + +@JsonInclude(Include.NON_NULL) +@JsonDeserialize(builder = Activity.Builder.class) +public class Activity { + private final String id; + private final String actor; + private final String verb; + private final String object; + private final String foreignID; + private final String target; + //TODO: support Java 8 Date/Time types? + private final Date time; + private final String origin; + private final List to; + private final Double score; + private final Map extra; + + private Activity(Builder builder) { + id = builder.id; + actor = builder.actor; + verb = builder.verb; + object = builder.object; + foreignID = builder.foreignID; + target = builder.target; + time = builder.time; + origin = builder.origin; + to = builder.to; + score = builder.score; + extra = builder.extra; + } + + public String getID() { + return id; + } + + public String getActor() { + return actor; + } + + public String getVerb() { + return verb; + } + + public String getObject() { + return object; + } + + @JsonProperty("foreign_id") + public String getForeignID() { + return foreignID; + } + + public String getTarget() { + return target; + } + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.S", timezone = "UTC") + public Date getTime() { + return time; + } + + public String getOrigin() { + return origin; + } + + public List getTo() { + return to; + } + + public Double getScore() { + return score; + } + + @JsonAnyGetter + public Map getExtra() { + return extra; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Activity activity = (Activity) o; + return Objects.equals(id, activity.id) && + Objects.equals(actor, activity.actor) && + Objects.equals(verb, activity.verb) && + Objects.equals(object, activity.object) && + Objects.equals(foreignID, activity.foreignID) && + Objects.equals(target, activity.target) && + Objects.equals(time, activity.time) && + Objects.equals(origin, activity.origin) && + Objects.equals(to, activity.to) && + Objects.equals(score, activity.score) && + Objects.equals(extra, activity.extra); + } + + @Override + public int hashCode() { + return Objects.hash(id, actor, verb, object, foreignID, target, time, origin, to, score, extra); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", this.id) + .add("actor", this.actor) + .add("verb", this.verb) + .add("object", this.object) + .add("foreignID", this.foreignID) + .add("target", this.target) + .add("time", this.time) + .add("origin", this.origin) + .add("to", this.to) + .add("score", this.score) + .add("extra", this.extra) + .toString(); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonPOJOBuilder(withPrefix = "") + public static final class Builder { + private String id; + private String actor; + private String verb; + private String object; + private String foreignID; + private String target; + private Date time; + private String origin; + private List to; + private Double score; + private Map extra; + + public Builder id(String id) { + this.id = id; + return this; + } + + public Builder actor(String actor) { + this.actor = actor; + return this; + } + + public Builder verb(String verb) { + this.verb = verb; + return this; + } + + public Builder object(String object) { + this.object = object; + return this; + } + + @JsonProperty("foreign_id") + public Builder foreignID(String foreignID) { + this.foreignID = foreignID; + return this; + } + + public Builder target(String target) { + this.target = target; + return this; + } + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.S", timezone = "UTC") + public Builder time(Date time) { + this.time = time; + return this; + } + + public Builder origin(String origin) { + this.origin = origin; + return this; + } + + @JsonProperty("to") + public Builder to(List to) { + this.to = to; + return this; + } + + @JsonIgnore + public Builder to(Iterable to) { + this.to = Lists.newArrayList(to); + return this; + } + + @JsonIgnore + public Builder to(FeedID... to) { + this.to = Lists.newArrayList(to); + return this; + } + + public Builder score(double score) { + this.score = score; + return this; + } + + @JsonAnySetter + public Builder extraField(String key, Object value) { + if (extra == null) { + extra = Maps.newHashMap(); + } + extra.put(key, value); + return this; + } + + @JsonIgnore + public Builder extra(Map extra) { + if (!extra.isEmpty()) { + this.extra = extra; + } + return this; + } + + @JsonIgnore + public Builder fromActivity(Activity activity) { + this.id = activity.id; + this.actor = activity.actor; + this.verb = activity.verb; + this.object = activity.object; + this.foreignID = activity.foreignID; + this.target = activity.target; + this.time = activity.time; + this.origin = activity.origin; + this.to = activity.to; + this.score = activity.score; + this.extra = activity.extra; + return this; + } + + @JsonIgnore + public Builder fromCustomActivity(T custom) { + return fromActivity(convert(custom, Activity.class)); + } + + public Activity build() { + checkNotNull(actor, "Activity 'actor' field required"); + checkNotNull(verb, "Activity 'verb' field required"); + checkNotNull(object, "Activity 'object' field required"); + + return new Activity(this); + } + } +} diff --git a/src/main/java/io/getstream/core/models/CollectionData.java b/src/main/java/io/getstream/core/models/CollectionData.java new file mode 100644 index 00000000..8b47952f --- /dev/null +++ b/src/main/java/io/getstream/core/models/CollectionData.java @@ -0,0 +1,105 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Maps; + +import java.util.Map; +import java.util.Objects; + +import static com.google.common.base.MoreObjects.firstNonNull; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Serialization.convert; + +public final class CollectionData { + private final String id; + private final String collection; + private final Map data; + + @JsonCreator + public CollectionData( + @JsonProperty("collection") + String collection, + @JsonProperty("id") + String id, + @JsonProperty("data") + Map data) { + this.collection = collection; + this.data = firstNonNull(data, Maps.newHashMap()); + this.id = checkNotNull(id, "ID required"); + } + + public CollectionData() { + this(null, "", null); + } + + public CollectionData(String id) { + this(null, id, null); + } + + public static CollectionData buildFrom(T data) { + return convert(data, CollectionData.class); + } + + public String getID() { + return id; + } + + @JsonIgnore + public String getCollection() { + return collection; + } + + @JsonAnyGetter + public Map getData() { + return data; + } + + @JsonAnySetter + public CollectionData set(String key, T value) { + checkArgument(!"id".equals(key), "Key can't be named 'id'"); + checkNotNull(key, "Key can't be null"); + checkNotNull(value, "Value can't be null"); + + data.put(key, value); + return this; + } + + public CollectionData from(T data) { + checkNotNull(data, "Can't extract data from null"); + + Map map = convert(data, new TypeReference>() {}); + for (Map.Entry entry : map.entrySet()) { + set(entry.getKey(), entry.getValue()); + } + return this; + } + + public T get(String key) { + return (T) data.get(checkNotNull(key, "Key can't be null")); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CollectionData collectionData = (CollectionData) o; + return Objects.equals(id, collectionData.id) && + Objects.equals(data, collectionData.data); + } + + @Override + public int hashCode() { + return Objects.hash(id, data); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", this.id) + .add("data", this.data) + .toString(); + } +} diff --git a/src/main/java/io/getstream/core/models/Content.java b/src/main/java/io/getstream/core/models/Content.java new file mode 100644 index 00000000..1f0426ab --- /dev/null +++ b/src/main/java/io/getstream/core/models/Content.java @@ -0,0 +1,86 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Maps; + +import java.util.Map; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Serialization.convert; + +public final class Content { + private final String foreignID; + private final Map data = Maps.newHashMap(); + + @JsonCreator + public Content(@JsonProperty("foreign_id") String foreignID) { + this.foreignID = checkNotNull(foreignID, "ID required"); + } + + public static Content buildFrom(T data) { + return convert(data, Content.class); + } + + @JsonProperty("foreign_id") + public String getForeignID() { + return foreignID; + } + + @JsonAnyGetter + public Map getData() { + return data; + } + + @JsonAnySetter + public Content set(String key, T value) { + checkArgument(!"foreignID".equals(key), "Key can't be named 'foreignID'"); + checkNotNull(key, "Key can't be null"); + checkNotNull(value, "Value can't be null"); + + data.put(key, value); + return this; + } + + public Content from(T data) { + checkNotNull(data, "Can't extract data from null"); + + Map map = convert(data, new TypeReference>() {}); + for (Map.Entry entry : map.entrySet()) { + set(entry.getKey(), entry.getValue()); + } + return this; + } + + public T get(String key) { + return (T) data.get(checkNotNull(key, "Key can't be null")); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Content collectionData = (Content) o; + return Objects.equals(foreignID, collectionData.foreignID) && + Objects.equals(data, collectionData.data); + } + + @Override + public int hashCode() { + return Objects.hash(foreignID, data); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", this.foreignID) + .add("data", this.data) + .toString(); + } +} diff --git a/src/main/java/io/getstream/core/models/Data.java b/src/main/java/io/getstream/core/models/Data.java new file mode 100644 index 00000000..df451e02 --- /dev/null +++ b/src/main/java/io/getstream/core/models/Data.java @@ -0,0 +1,90 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Maps; +import io.getstream.core.models.serialization.DataDeserializer; + +import java.util.Map; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Serialization.convert; + +@JsonDeserialize(using = DataDeserializer.class) +public final class Data { + private final String id; + private final Map data = Maps.newHashMap(); + + public Data(String id) { + this.id = checkNotNull(id, "ID required"); + } + + public Data() { + this(""); + } + + public static Data buildFrom(T data) { + return convert(data, Data.class); + } + + public String getID() { + return id; + } + + @JsonAnyGetter + public Map getData() { + return data; + } + + public Data set(String key, T value) { + checkArgument(!"id".equals(key), "Key can't be named 'id'"); + checkNotNull(key, "Key can't be null"); + checkNotNull(value, "Value can't be null"); + + data.put(key, value); + return this; + } + + public Data from(T data) { + return from(convert(data, new TypeReference>() {})); + } + + public Data from(Map map) { + checkNotNull(data, "Can't extract data from null"); + + for (Map.Entry entry : map.entrySet()) { + set(entry.getKey(), entry.getValue()); + } + return this; + } + + public T get(String key) { + return (T) data.get(checkNotNull(key, "Key can't be null")); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Data data = (Data) o; + return Objects.equals(id, data.id) && + Objects.equals(data, data.data); + } + + @Override + public int hashCode() { + return Objects.hash(id, data); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", this.id) + .add("data", this.data) + .toString(); + } +} diff --git a/src/main/java/io/getstream/core/models/Engagement.java b/src/main/java/io/getstream/core/models/Engagement.java new file mode 100644 index 00000000..faace27a --- /dev/null +++ b/src/main/java/io/getstream/core/models/Engagement.java @@ -0,0 +1,210 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import com.google.common.base.MoreObjects; + +import java.util.Date; +import java.util.List; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Serialization.convert; + +@JsonInclude(Include.NON_NULL) +@JsonDeserialize(builder = Engagement.Builder.class) +public class Engagement { + private final String feedID; + private final UserData userData; + private final String label; + private final Content content; + private final Integer boost; + private final Integer position; + private final String location; + private final List features; + private final Date trackedAt; + + private Engagement(Builder builder) { + label = builder.label; + content = builder.content; + boost = builder.boost; + position = builder.position; + feedID = builder.feedID; + location = builder.location; + userData = builder.userData; + features = builder.features; + trackedAt = builder.trackedAt; + } + + public static Builder builder() { + return new Builder(); + } + + public String getLabel() { + return label; + } + + public Content getContent() { + return content; + } + + public int getBoost() { + return boost; + } + + public int getPosition() { + return position; + } + + @JsonProperty("feed_id") + public String getFeedID() { + return feedID; + } + + public String getLocation() { + return location; + } + + @JsonProperty("user_data") + public UserData getUserData() { + return userData; + } + + public List getFeatures() { + return features; + } + + @JsonProperty("tracked_at") + public Date getTrackedAt() { + return trackedAt; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Engagement that = (Engagement) o; + return Objects.equals(label, that.label) && + Objects.equals(content, that.content) && + Objects.equals(boost, that.boost) && + Objects.equals(position, that.position) && + Objects.equals(feedID, that.feedID) && + Objects.equals(location, that.location) && + Objects.equals(userData, that.userData) && + Objects.equals(features, that.features) && + Objects.equals(trackedAt, that.trackedAt); + } + + @Override + public int hashCode() { + return Objects.hash(label, content, boost, position, feedID, location, userData, features, trackedAt); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("label", this.label) + .add("content", this.content) + .add("boost", this.boost) + .add("position", this.position) + .add("feedID", this.feedID) + .add("location", this.location) + .add("userData", this.userData) + .add("features", this.features) + .add("trackedAt", this.trackedAt) + .toString(); + } + + @JsonPOJOBuilder(withPrefix = "") + public static final class Builder { + private String label; + private Content content; + private Integer boost; + private Integer position; + private String feedID; + private String location; + private UserData userData; + private List features; + private Date trackedAt; + + public Builder label(String label) { + this.label = label; + return this; + } + + public Builder content(Content content) { + this.content = content; + return this; + } + + public Builder boost(int boost) { + this.boost = boost; + return this; + } + + public Builder position(int position) { + this.position = position; + return this; + } + + @JsonProperty("feed_id") + public Builder feedID(String feedID) { + this.feedID = feedID; + return this; + } + + public Builder location(String location) { + this.location = location; + return this; + } + + @JsonProperty("user_data") + public Builder userData(UserData userData) { + this.userData = userData; + return this; + } + + public Builder features(List features) { + this.features = features; + return this; + } + + @JsonProperty("tracked_at") + public Builder trackedAt(Date trackedAt) { + this.trackedAt = trackedAt; + return this; + } + + @JsonIgnore + public Builder fromEngagement(Engagement engagement) { + label = engagement.label; + content = engagement.content; + boost = engagement.boost; + position = engagement.position; + feedID = engagement.feedID; + location = engagement.location; + userData = engagement.userData; + features = engagement.features; + trackedAt = engagement.trackedAt; + return this; + } + + @JsonIgnore + public Builder fromCustomEngagement(T custom) { + return fromEngagement(convert(custom, Engagement.class)); + } + + public Engagement build() { + checkNotNull(feedID, "Engagement 'feedID' field required"); + checkNotNull(userData, "Engagement 'userData' field required"); + checkNotNull(label, "Engagement 'label' field required"); + checkNotNull(content, "Engagement 'content' field required"); + + return new Engagement(this); + } + } +} diff --git a/src/main/java/io/getstream/core/models/EnrichedActivity.java b/src/main/java/io/getstream/core/models/EnrichedActivity.java new file mode 100644 index 00000000..ccd4bc89 --- /dev/null +++ b/src/main/java/io/getstream/core/models/EnrichedActivity.java @@ -0,0 +1,333 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Serialization.convert; + +@JsonInclude(Include.NON_NULL) +@JsonDeserialize(builder = EnrichedActivity.Builder.class) +public class EnrichedActivity { + private final String id; + private final Data actor; + private final Data verb; + private final Data object; + private final String foreignID; + private final Data target; + //TODO: support Java 8 Date/Time types? + private final Date time; + private final Data origin; + private final List to; + private final Double score; + private final Map reactionCounts; + private final Map> ownReactions; + private final Map> latestReactions; + private final Map extra; + + private EnrichedActivity(Builder builder) { + id = builder.id; + actor = builder.actor; + verb = builder.verb; + object = builder.object; + foreignID = builder.foreignID; + target = builder.target; + time = builder.time; + origin = builder.origin; + to = builder.to; + score = builder.score; + reactionCounts = builder.reactionCounts; + ownReactions = builder.ownReactions; + latestReactions = builder.latestReactions; + extra = builder.extra; + } + + public String getID() { + return id; + } + + public Data getActor() { + return actor; + } + + public Data getVerb() { + return verb; + } + + public Data getObject() { + return object; + } + + @JsonProperty("foreign_id") + public String getForeignID() { + return foreignID; + } + + public Data getTarget() { + return target; + } + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.S", timezone = "UTC") + public Date getTime() { + return time; + } + + public Data getOrigin() { + return origin; + } + + public List getTo() { + return to; + } + + public Double getScore() { + return score; + } + + @JsonAnyGetter + public Map getExtra() { + return extra; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + EnrichedActivity activity = (EnrichedActivity) o; + return Objects.equals(id, activity.id) && + Objects.equals(actor, activity.actor) && + Objects.equals(verb, activity.verb) && + Objects.equals(object, activity.object) && + Objects.equals(foreignID, activity.foreignID) && + Objects.equals(target, activity.target) && + Objects.equals(time, activity.time) && + Objects.equals(origin, activity.origin) && + Objects.equals(to, activity.to) && + Objects.equals(score, activity.score) && + Objects.equals(extra, activity.extra); + } + + @Override + public int hashCode() { + return Objects.hash(id, actor, verb, object, foreignID, target, time, origin, to, score, extra); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", this.id) + .add("actor", this.actor) + .add("verb", this.verb) + .add("object", this.object) + .add("foreignID", this.foreignID) + .add("target", this.target) + .add("time", this.time) + .add("origin", this.origin) + .add("to", this.to) + .add("score", this.score) + .add("ownReactions", this.ownReactions) + .add("latestReactions", this.latestReactions) + .add("reactionCounts", this.reactionCounts) + .add("extra", this.extra) + .toString(); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonPOJOBuilder(withPrefix = "") + public static final class Builder { + private String id; + private Data actor; + private Data verb; + private Data object; + private String foreignID; + private Data target; + private Date time; + private Data origin; + private List to; + private Double score; + private Map reactionCounts; + private Map> ownReactions; + private Map> latestReactions; + private Map extra; + + public Builder id(String id) { + this.id = id; + return this; + } + + @JsonIgnore + public Builder actor(String actor) { + this.actor = new Data(actor); + return this; + } + + @JsonProperty("actor") + public Builder actor(Data actor) { + this.actor = actor; + return this; + } + + @JsonIgnore + public Builder verb(String verb) { + this.verb = new Data(verb); + return this; + } + + @JsonProperty("verb") + public Builder verb(Data verb) { + this.verb = verb; + return this; + } + + @JsonIgnore + public Builder object(String object) { + this.object = new Data(object); + return this; + } + + @JsonProperty("object") + public Builder object(Data object) { + this.object = object; + return this; + } + + @JsonProperty("foreign_id") + public Builder foreignID(String foreignID) { + this.foreignID = foreignID; + return this; + } + + @JsonIgnore + public Builder target(String target) { + this.target = new Data(target); + return this; + } + + @JsonProperty("target") + public Builder target(Data target) { + this.target = target; + return this; + } + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.S", timezone = "UTC") + public Builder time(Date time) { + this.time = time; + return this; + } + + @JsonIgnore + public Builder origin(String origin) { + this.origin = new Data(origin); + return this; + } + + @JsonProperty("origin") + public Builder origin(Data origin) { + this.origin = origin; + return this; + } + + @JsonProperty("to") + public Builder to(List to) { + this.to = to; + return this; + } + + @JsonIgnore + public Builder to(Iterable to) { + this.to = Lists.newArrayList(to); + return this; + } + + @JsonIgnore + public Builder to(FeedID... to) { + this.to = Lists.newArrayList(to); + return this; + } + + public Builder score(double score) { + this.score = score; + return this; + } + + @JsonProperty("own_reactions") + public Builder ownReactions(Map> ownReactions) { + this.ownReactions = ownReactions; + return this; + } + + @JsonProperty("latest_reactions") + public Builder latestReactions(Map> latestReactions) { + this.latestReactions = latestReactions; + return this; + } + + @JsonProperty("reaction_counts") + public Builder reactionCounts(Map reactionCounts) { + this.reactionCounts = reactionCounts; + return this; + } + + @JsonAnySetter + public Builder extraField(String key, Object value) { + if (extra == null) { + extra = Maps.newHashMap(); + } + extra.put(key, value); + return this; + } + + @JsonIgnore + public Builder extra(Map extra) { + if (!extra.isEmpty()) { + this.extra = extra; + } + return this; + } + + @JsonIgnore + public Builder fromEnrichedActivity(EnrichedActivity activity) { + this.id = activity.id; + this.actor = activity.actor; + this.verb = activity.verb; + this.object = activity.object; + this.foreignID = activity.foreignID; + this.target = activity.target; + this.time = activity.time; + this.origin = activity.origin; + this.to = activity.to; + this.score = activity.score; + this.ownReactions = activity.ownReactions; + this.latestReactions = activity.latestReactions; + this.reactionCounts = activity.reactionCounts; + this.extra = activity.extra; + return this; + } + + @JsonIgnore + public Builder fromCustomEnrichedActivity(T custom) { + return fromEnrichedActivity(convert(custom, EnrichedActivity.class)); + } + + public EnrichedActivity build() { + checkNotNull(actor, "EnrichedActivity 'actor' field required"); + checkNotNull(verb, "EnrichedActivity 'verb' field required"); + checkNotNull(object, "EnrichedActivity 'object' field required"); + + return new EnrichedActivity(this); + } + } +} diff --git a/src/main/java/io/getstream/core/models/Feature.java b/src/main/java/io/getstream/core/models/Feature.java new file mode 100644 index 00000000..ef7d3481 --- /dev/null +++ b/src/main/java/io/getstream/core/models/Feature.java @@ -0,0 +1,48 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +public final class Feature { + private final String group; + private final String value; + + @JsonCreator + public Feature(@JsonProperty("group") String group, @JsonProperty("value") String value) { + this.group = group; + this.value = value; + } + + public String getGroup() { + return group; + } + + public String getValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Feature feature = (Feature) o; + return Objects.equals(group, feature.group) && + Objects.equals(value, feature.value); + } + + @Override + public int hashCode() { + return Objects.hash(group, value); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("group", this.group) + .add("value", this.value) + .toString(); + } +} diff --git a/src/main/java/io/getstream/core/models/FeedID.java b/src/main/java/io/getstream/core/models/FeedID.java new file mode 100644 index 00000000..680609ca --- /dev/null +++ b/src/main/java/io/getstream/core/models/FeedID.java @@ -0,0 +1,62 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +@JsonSerialize(using = ToStringSerializer.class) +public final class FeedID { + private final String slug; + private final String userID; + + public FeedID(String slug, String userID) { + checkNotNull(slug, "Feed slug can't be null"); + checkArgument(!slug.contains(":"), "Invalid slug"); + checkNotNull(userID, "Feed user ID can't be null"); + checkArgument(!userID.contains(":"), "Invalid user ID"); + + this.slug = slug; + this.userID = userID; + } + + public FeedID(String id) { + checkNotNull(id, "Feed ID can't be null"); + checkArgument(id.contains(":"), "Invalid feed ID"); + + String[] parts = id.split(":"); + checkArgument(parts.length == 2, "Invalid feed ID"); + this.slug = parts[0]; + this.userID = parts[1]; + } + + public String getSlug() { + return slug; + } + + public String getUserID() { + return userID; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FeedID feedID = (FeedID) o; + return Objects.equals(slug, feedID.slug) && + Objects.equals(userID, feedID.userID); + } + + @Override + public int hashCode() { + return Objects.hash(slug, userID); + } + + @Override + public String toString() { + return slug + ':' + userID; + } +} diff --git a/src/main/java/io/getstream/core/models/FollowRelation.java b/src/main/java/io/getstream/core/models/FollowRelation.java new file mode 100644 index 00000000..6383b5cc --- /dev/null +++ b/src/main/java/io/getstream/core/models/FollowRelation.java @@ -0,0 +1,55 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +@JsonIgnoreProperties(ignoreUnknown = true) +public final class FollowRelation { + private final String source; + private final String target; + + @JsonCreator + public FollowRelation(@JsonProperty("feed_id") String source, @JsonProperty("target_id") String target) { + checkNotNull(source, "FollowRelation 'source' field required"); + checkNotNull(target, "FollowRelation 'target' field required"); + + this.source = source; + this.target = target; + } + + public String getSource() { + return this.source; + } + + public String getTarget() { + return this.target; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FollowRelation that = (FollowRelation) o; + return Objects.equals(source, that.source) && + Objects.equals(target, that.target); + } + + @Override + public int hashCode() { + return Objects.hash(source, target); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("source", this.source) + .add("target", this.target) + .toString(); + } +} diff --git a/src/main/java/io/getstream/core/models/ForeignIDTimePair.java b/src/main/java/io/getstream/core/models/ForeignIDTimePair.java new file mode 100644 index 00000000..0d8b65fa --- /dev/null +++ b/src/main/java/io/getstream/core/models/ForeignIDTimePair.java @@ -0,0 +1,46 @@ +package io.getstream.core.models; + +import com.google.common.base.MoreObjects; + +import java.util.Date; +import java.util.Objects; + +public final class ForeignIDTimePair { + private final String foreignID; + private final Date time; + + public ForeignIDTimePair(String foreignID, Date time) { + this.foreignID = foreignID; + this.time = time; + } + + public String getForeignID() { + return foreignID; + } + + public Date getTime() { + return time; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ForeignIDTimePair that = (ForeignIDTimePair) o; + return Objects.equals(foreignID, that.foreignID) && + Objects.equals(time, that.time); + } + + @Override + public int hashCode() { + return Objects.hash(foreignID, time); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("foreignID", this.foreignID) + .add("time", this.time) + .toString(); + } +} diff --git a/src/main/java/io/getstream/core/models/Group.java b/src/main/java/io/getstream/core/models/Group.java new file mode 100644 index 00000000..25679ee4 --- /dev/null +++ b/src/main/java/io/getstream/core/models/Group.java @@ -0,0 +1,93 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.MoreObjects; + +import java.util.Date; +import java.util.List; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Group { + private final String group; + private final List activities; + private final int actorCount; + private final Date createdAt; + private final Date updatedAt; + + @JsonCreator + public Group( + @JsonProperty("group") + String group, + @JsonProperty("activities") + List activities, + @JsonProperty("actor_count") + int actorCount, + @JsonProperty("created_at") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.S", timezone = "UTC") + Date createdAt, + @JsonProperty("updated_at") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.S", timezone = "UTC") + Date updatedAt) { + checkNotNull(group, "Group 'group' field required"); + checkNotNull(activities, "Group 'activities' field required"); + + this.group = group; + this.activities = activities; + this.actorCount = actorCount; + this.createdAt = createdAt; + this.updatedAt = updatedAt; + } + + public String getGroup() { + return group; + } + + public List getActivities() { + return activities; + } + + public int getActorCount() { + return actorCount; + } + + public Date getCreatedAt() { + return createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Group that = (Group) o; + return actorCount == that.actorCount && + Objects.equals(group, that.group) && + Objects.equals(activities, that.activities) && + Objects.equals(createdAt, that.createdAt) && + Objects.equals(updatedAt, that.updatedAt); + } + + @Override + public int hashCode() { + return Objects.hash(group, activities, actorCount, createdAt, updatedAt); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("activities", this.activities) + .add("actorCount", this.actorCount) + .add("createdAt", this.createdAt) + .add("updatedAt", this.updatedAt) + .toString(); + } +} diff --git a/src/main/java/io/getstream/core/models/Impression.java b/src/main/java/io/getstream/core/models/Impression.java new file mode 100644 index 00000000..8e95841c --- /dev/null +++ b/src/main/java/io/getstream/core/models/Impression.java @@ -0,0 +1,193 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; + +import java.util.Date; +import java.util.List; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.getstream.core.utils.Serialization.convert; + +@JsonInclude(Include.NON_NULL) +@JsonDeserialize(builder = Impression.Builder.class) +public class Impression { + private final String feedID; + private final UserData userData; + private final List contentList; + private final String position; + private final String location; + private final List features; + private final Date trackedAt; + + private Impression(Builder builder) { + position = builder.position; + feedID = builder.feedID; + location = builder.location; + userData = builder.userData; + contentList = builder.contentList; + features = builder.features; + trackedAt = builder.trackedAt; + } + + public static Builder builder() { + return new Builder(); + } + + public String getPosition() { + return position; + } + + @JsonProperty("feed_id") + public String getFeedID() { + return feedID; + } + + public String getLocation() { + return location; + } + + @JsonProperty("user_data") + public UserData getUserData() { + return userData; + } + + @JsonProperty("content_list") + public List getContentList() { + return contentList; + } + + public List getFeatures() { + return features; + } + + @JsonProperty("tracked_at") + public Date getTrackedAt() { + return trackedAt; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Impression that = (Impression) o; + return Objects.equals(position, that.position) && + Objects.equals(feedID, that.feedID) && + Objects.equals(location, that.location) && + Objects.equals(userData, that.userData) && + Objects.equals(contentList, that.contentList) && + Objects.equals(features, that.features) && + Objects.equals(trackedAt, that.trackedAt); + } + + @Override + public int hashCode() { + return Objects.hash(position, feedID, location, userData, contentList, features, trackedAt); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("position", this.position) + .add("feedID", this.feedID) + .add("location", this.location) + .add("userData", this.userData) + .add("contentList", this.contentList) + .add("features", this.features) + .add("trackedAt", this.trackedAt) + .toString(); + } + + @JsonPOJOBuilder(withPrefix = "") + public static final class Builder { + private String position; + private String feedID; + private String location; + private UserData userData; + private List contentList; + private List features; + private Date trackedAt; + + public Builder position(String position) { + this.position = position; + return this; + } + + @JsonProperty("feed_id") + public Builder feedID(String feedID) { + this.feedID = feedID; + return this; + } + + public Builder location(String location) { + this.location = location; + return this; + } + + @JsonProperty("user_data") + public Builder userData(UserData userData) { + this.userData = userData; + return this; + } + + @JsonProperty("content_list") + public Builder contentList(List contentList) { + this.contentList = contentList; + return this; + } + + @JsonIgnore + public Builder contentList(Iterable contentList) { + this.contentList = Lists.newArrayList(contentList); + return this; + } + + @JsonIgnore + public Builder contentList(Content... contentList) { + this.contentList = Lists.newArrayList(contentList); + return this; + } + + public Builder features(List features) { + this.features = features; + return this; + } + + @JsonProperty("tracked_at") + public Builder trackedAt(Date trackedAt) { + this.trackedAt = trackedAt; + return this; + } + + @JsonIgnore + public Builder fromImpression(Impression impression) { + position = impression.position; + feedID = impression.feedID; + location = impression.location; + userData = impression.userData; + contentList = impression.contentList; + features = impression.features; + trackedAt = impression.trackedAt; + return this; + } + + @JsonIgnore + public Builder fromCustomImpression(T custom) { + return fromImpression(convert(custom, Impression.class)); + } + + public Impression build() { + checkNotNull(feedID, "Impression 'feedID' field required"); + checkNotNull(userData, "Impression 'userData' field required"); + + return new Impression(this); + } + } +} diff --git a/src/main/java/io/getstream/core/models/NotificationGroup.java b/src/main/java/io/getstream/core/models/NotificationGroup.java new file mode 100644 index 00000000..7c47ada5 --- /dev/null +++ b/src/main/java/io/getstream/core/models/NotificationGroup.java @@ -0,0 +1,76 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.MoreObjects; + +import java.util.Date; +import java.util.List; +import java.util.Objects; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class NotificationGroup extends Group { + private final boolean seen; + private final boolean read; + + @JsonCreator + public NotificationGroup( + @JsonProperty("group") + String group, + @JsonProperty("activities") + List activities, + @JsonProperty("actor_count") + int actorCount, + @JsonProperty("created_at") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.S", timezone = "UTC") + Date createdAt, + @JsonProperty("updated_at") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.S", timezone = "UTC") + Date updatedAt, + @JsonProperty("is_seen") + boolean isSeen, + @JsonProperty("is_read") + boolean isRead) { + super(group, activities, actorCount, createdAt, updatedAt); + + this.seen = isSeen; + this.read = isRead; + } + + public boolean isSeen() { + return seen; + } + + public boolean isRead() { + return read; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + NotificationGroup that = (NotificationGroup) o; + return seen == that.seen && + read == that.read; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), seen, read); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("activities", getActivities()) + .add("actorCount", getActorCount()) + .add("createdAt", getCreatedAt()) + .add("updatedAt", getUpdatedAt()) + .add("isSeen", seen) + .add("isRead", read) + .toString(); + } +} diff --git a/src/main/java/io/getstream/core/models/OGData.java b/src/main/java/io/getstream/core/models/OGData.java new file mode 100644 index 00000000..edb478ff --- /dev/null +++ b/src/main/java/io/getstream/core/models/OGData.java @@ -0,0 +1,268 @@ +package io.getstream.core.models; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class OGData { + public static class Image { + private final String image; + private final String url; + private final String secureUrl; + private final String width; + private final String height; + private final String type; + private final String alt; + + @JsonCreator + public Image( + @JsonProperty("image") + String image, + @JsonProperty("url") + String url, + @JsonProperty("secure_url") + String secureUrl, + @JsonProperty("width") + String width, + @JsonProperty("height") + String height, + @JsonProperty("type") + String type, + @JsonProperty("alt") + String alt) { + this.image = image; + this.url = url; + this.secureUrl = secureUrl; + this.width = width; + this.height = height; + this.type = type; + this.alt = alt; + } + + public String getImage() { + return image; + } + + public String getURL() { + return url; + } + + public String getSecureUrl() { + return secureUrl; + } + + public String getWidth() { + return width; + } + + public String getHeight() { + return height; + } + + public String getType() { + return type; + } + + public String getAlt() { + return alt; + } + } + + public static class Video { + private final String video; + private final String alt; + private final String url; + private final String secureURL; + private final String type; + private final String width; + private final String height; + + @JsonCreator + public Video( + @JsonProperty("video") + String video, + @JsonProperty("alt") + String alt, + @JsonProperty("url") + String url, + @JsonProperty("secure_url") + String secureURL, + @JsonProperty("type") + String type, + @JsonProperty("width") + String width, + @JsonProperty("height") + String height) { + this.video = video; + this.alt = alt; + this.url = url; + this.secureURL = secureURL; + this.type = type; + this.width = width; + this.height = height; + } + + public String getSecureURL() { + return secureURL; + } + + public String getURL(){ + return url; + } + + public String getWidth() { + return width; + } + + public String getHeight() { + return height; + } + + public String getType() { + return type; + } + + public String getAlt() { + return alt; + } + + public String getVideo() { + return video; + } + } + + public static class Audio { + private final String url; + private final String secureURL; + private final String type; + private final String audio; + + @JsonCreator + public Audio( + @JsonProperty("url") + String url, + @JsonProperty("secure_url") + String secureURL, + @JsonProperty("type") + String type, + @JsonProperty("audio") + String audio) { + this.type = type; + this.audio = audio; + this.url = url; + this.secureURL = secureURL; + } + + public String getSecureURL() { + return secureURL; + } + + public String getURL(){ + return url; + } + + public String getType() { + return type; + } + + public String getAudio() { + return audio; + } + } + + private final String title; + private final String type; + private final String description; + private final String determiner; + private final String locale; + private final String siteName; + private final List images; + private final List