From 4100a1d12a2dd3f4fc37edd049c733df101fc146 Mon Sep 17 00:00:00 2001 From: Sebastien Chauvin Date: Mon, 11 Feb 2019 11:47:41 +0100 Subject: [PATCH 1/6] Personal recommendation implemented for RTS Home --- .../pfff/config/AuthenticationConfig.java | 2 +- .../controller/RecommendationController.java | 13 ++- .../example/pfff/model/RecommendedList.java | 10 +++ .../peach/PersonalRecommendationResult.java | 56 +++++++++++++ .../pfff/service/RecommendationService.java | 31 +++++++ .../RecommendationServiceTests.java | 83 +++++++++++++------ 6 files changed, 166 insertions(+), 29 deletions(-) create mode 100644 src/main/java/com/example/pfff/model/peach/PersonalRecommendationResult.java diff --git a/src/main/java/com/example/pfff/config/AuthenticationConfig.java b/src/main/java/com/example/pfff/config/AuthenticationConfig.java index 3134cdf..a1dbad3 100644 --- a/src/main/java/com/example/pfff/config/AuthenticationConfig.java +++ b/src/main/java/com/example/pfff/config/AuthenticationConfig.java @@ -38,7 +38,7 @@ public AuthenticationConfig( protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() - .antMatchers("/api/v1/update/check", "/api/v1/whatisnew/text", "/api/v1/whatisnew/html", "/api/v1/version", "/api/v*/playlist/recommendation/**", "/webjars/bootstrap/**", "/webjars/bootstrap/**", "/webjars/jquery/**", "/webjars/font-awesome/**").permitAll() + .antMatchers("/api/v1/update/check", "/api/v1/whatisnew/text", "/api/v1/whatisnew/html", "/api/v1/version", "/api/v*/playlist/**", "/webjars/bootstrap/**", "/webjars/bootstrap/**", "/webjars/jquery/**", "/webjars/font-awesome/**").permitAll() .anyRequest().authenticated() .and() .formLogin() diff --git a/src/main/java/com/example/pfff/controller/RecommendationController.java b/src/main/java/com/example/pfff/controller/RecommendationController.java index 3d1ca99..bcdc197 100644 --- a/src/main/java/com/example/pfff/controller/RecommendationController.java +++ b/src/main/java/com/example/pfff/controller/RecommendationController.java @@ -24,6 +24,7 @@ public class RecommendationController { @Autowired RecommendationService service; + @Deprecated @RequestMapping("/api/v1/playlist/recommendation/{purpose}/{urn}") @ResponseBody Object recommendationV1( @@ -47,7 +48,7 @@ Object recommendationV1( @RequestMapping("/api/v2/playlist/recommendation/{purpose}/{urn}") @ResponseBody - Object recommendationV2( + RecommendedList recommendationV2( HttpServletRequest request, @PathVariable("purpose") String purpose, @PathVariable("urn") String urn, @@ -60,4 +61,14 @@ private RecommendedList getRecommendationList(@PathVariable("purpose") String pu recommendedList.addUrn(0, urn); return recommendedList; } + + + @RequestMapping("/api/v2/playlist/personal_recommendation/{type}/{userId}") + @ResponseBody + RecommendedList personalRecommendation( + HttpServletRequest request, + @PathVariable("type") String type, @PathVariable("userId") String userId) { + return service.getPersonalRecommendation(type, userId); + } + } diff --git a/src/main/java/com/example/pfff/model/RecommendedList.java b/src/main/java/com/example/pfff/model/RecommendedList.java index 2578ba9..e34a100 100644 --- a/src/main/java/com/example/pfff/model/RecommendedList.java +++ b/src/main/java/com/example/pfff/model/RecommendedList.java @@ -17,6 +17,12 @@ public class RecommendedList { private String recommendationId; private List urns; + private String title; + + public RecommendedList(String title, String host, String recommendationId, List urns) { + this(host, recommendationId, urns); + this.title = title; + } public RecommendedList(String host, String recommendationId, List urns) { if (host != null && recommendationId != null) { @@ -42,6 +48,10 @@ public List getUrns() { return urns; } + public String getTitle() { + return title; + } + public void addUrn(int index, String urn) { this.urns.add(index, urn); } diff --git a/src/main/java/com/example/pfff/model/peach/PersonalRecommendationResult.java b/src/main/java/com/example/pfff/model/peach/PersonalRecommendationResult.java new file mode 100644 index 0000000..d9ba56c --- /dev/null +++ b/src/main/java/com/example/pfff/model/peach/PersonalRecommendationResult.java @@ -0,0 +1,56 @@ +package com.example.pfff.model.peach; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class PersonalRecommendationResult { + public String status; + public String codops; + public Result result; + + public static class Result { + + @JsonProperty("fallback_used") + public boolean fallbackUsed; + public String title; + public List items; + public String id; + } + public static class Item { + + public String urn; + //TODO Implement once explanation semantics has been implemented in peach backend + public Explanation explanation; + + } + /** + * Explanation has been defined in Jan. 2019 but not yet used. + */ + public static class Explanation { + + public String text; + @JsonProperty("media_reference_urn") + public String mediaReferenceUrn; + } + + public String getTitle() { + return result != null ? result.title : null; + } + + public String getRecommendationId() { + return result == null ? null : result.id; + } + + public List getUrns() { + if (result != null && result.items != null) { + return result.items.stream().map((i) -> i.urn).collect(Collectors.toList()); + } else { + return null; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/example/pfff/service/RecommendationService.java b/src/main/java/com/example/pfff/service/RecommendationService.java index b0dfb34..11d4532 100644 --- a/src/main/java/com/example/pfff/service/RecommendationService.java +++ b/src/main/java/com/example/pfff/service/RecommendationService.java @@ -5,9 +5,11 @@ import ch.srg.il.domain.v2_0.Media; import ch.srg.il.domain.v2_0.MediaType; import com.example.pfff.model.Environment; +import com.example.pfff.model.peach.PersonalRecommendationResult; import com.example.pfff.model.RecommendedList; import com.example.pfff.model.peach.RecommendationResult; import com.google.common.collect.Lists; +import org.checkerframework.checker.nullness.qual.NonNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; @@ -33,6 +35,7 @@ public RecommendationService() { restTemplate = new RestTemplate(); } + @NonNull public RecommendedList getRecommendedUrns(String purpose, String urn, boolean standalone) { if (urn.contains(":rts:")) { if (urn.contains(":video:")) { @@ -47,6 +50,7 @@ public RecommendedList getRecommendedUrns(String purpose, String urn, boolean st } } + @NonNull private RecommendedList rtsAudioRecommendedList(String urn) { Media media = integrationLayerRequest.getMedia(urn, Environment.PROD); if (media == null || media.getType() == LIVESTREAM || media.getType() == SCHEDULED_LIVESTREAM || media.getShow() == null) { @@ -112,6 +116,7 @@ private RecommendedList rtsAudioRecommendedList(String urn) { return new RecommendedList(host, recommendationId, recommendationResult); } + @NonNull private RecommendedList rtsVideoRecommendedList(String purpose, String urn, boolean standalone) { UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance().scheme("http") .host("peach.ebu.io").path("api/v1/chrts/continuous_playback_mobile"); @@ -128,4 +133,30 @@ private RecommendedList rtsVideoRecommendedList(String purpose, String urn, bool return new RecommendedList(url.getHost(), recommendationResult.getRecommendationId(), recommendationResult.getUrns()); } + + @NonNull + public RecommendedList getPersonalRecommendation(String type, String userId) { + switch (type) { + case "rtsPeachHome": + return rtsPlayHomePersonalRecommendation(userId); + default: + return new RecommendedList(); + } + + } + + @NonNull + private RecommendedList rtsPlayHomePersonalRecommendation(String userId) { + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance().scheme("http") + .host("peach.ebu.io").path("api/v1/chrts/play_home_personal_rec"); + uriComponentsBuilder.queryParam("user_id", userId); + UriComponents url = uriComponentsBuilder.build(); + + System.out.println(url.toUriString()); + + PersonalRecommendationResult result = restTemplate + .exchange(url.toUriString(), HttpMethod.GET, null, PersonalRecommendationResult.class).getBody(); + + return new RecommendedList(result.getTitle(), url.getHost(), result.getRecommendationId(), result.getUrns()); + } } \ No newline at end of file diff --git a/src/test/java/com/example/pfff/controller/RecommendationServiceTests.java b/src/test/java/com/example/pfff/controller/RecommendationServiceTests.java index a6974b6..fefd3d3 100644 --- a/src/test/java/com/example/pfff/controller/RecommendationServiceTests.java +++ b/src/test/java/com/example/pfff/controller/RecommendationServiceTests.java @@ -11,6 +11,10 @@ import java.util.List; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + @RunWith(SpringRunner.class) @SpringBootTest public class RecommendationServiceTests { @@ -27,9 +31,7 @@ public void getRecommendedUrnsContinuousplaybackRTSVideoTest() { Assert.assertNotNull(recommendedList.getRecommendationId()); Assert.assertTrue(recommendedList.getRecommendationId().startsWith("io.ebu.peach:")); - Assert.assertNotNull(recommendedList.getUrns()); - Assert.assertTrue(recommendedList.getUrns().size() > 0); - Assert.assertTrue(recommendedList.getUrns().size() < 50); + assertValidList(recommendedList); } @Test @@ -41,9 +43,7 @@ public void getRecommendedUrnsContinuousplaybackStandaloneRTSVideoTest() { Assert.assertNotNull(recommendedList.getRecommendationId()); Assert.assertTrue(recommendedList.getRecommendationId().startsWith("io.ebu.peach:")); - Assert.assertNotNull(recommendedList.getUrns()); - Assert.assertTrue(recommendedList.getUrns().size() > 0); - Assert.assertTrue(recommendedList.getUrns().size() < 50); + assertValidList(recommendedList); } @Test @@ -57,9 +57,7 @@ public void getRecommendedUrnsContinuousplaybackRTSAudioFullTest() { Assert.assertNotNull(recommendedList.getRecommendationId()); Assert.assertTrue(recommendedList.getRecommendationId().startsWith("ch.srgssr.playfff:EpisodeComposition/LatestByShow/" + showURN + "/FullLength/")); Assert.assertTrue(recommendedList.getRecommendationId().contains(mediaURN)); - Assert.assertNotNull(recommendedList.getUrns()); - Assert.assertTrue(recommendedList.getUrns().size() > 0); - Assert.assertTrue(recommendedList.getUrns().size() < 50); + assertValidList(recommendedList); } @Test @@ -73,9 +71,7 @@ public void getRecommendedUrnsContinuousplaybackStandaloneRTSAudioFullTest() { Assert.assertNotNull(recommendedList.getRecommendationId()); Assert.assertTrue(recommendedList.getRecommendationId().startsWith("ch.srgssr.playfff:EpisodeComposition/LatestByShow/" + showURN + "/FullLength/")); Assert.assertTrue(recommendedList.getRecommendationId().contains(mediaURN)); - Assert.assertNotNull(recommendedList.getUrns()); - Assert.assertTrue(recommendedList.getUrns().size() > 0); - Assert.assertTrue(recommendedList.getUrns().size() < 50); + assertValidList(recommendedList); } @Test @@ -89,9 +85,7 @@ public void getRecommendedUrnsContinuousplaybackRTSAudioClipTest() { Assert.assertNotNull(recommendedList.getRecommendationId()); Assert.assertTrue(recommendedList.getRecommendationId().startsWith("ch.srgssr.playfff:EpisodeComposition/LatestByShow/" + showURN + "/Clip/")); Assert.assertTrue(recommendedList.getRecommendationId().contains(mediaURN)); - Assert.assertNotNull(recommendedList.getUrns()); - Assert.assertTrue(recommendedList.getUrns().size() > 0); - Assert.assertTrue(recommendedList.getUrns().size() < 50); + assertValidList(recommendedList); } @Test @@ -105,9 +99,7 @@ public void getRecommendedUrnsContinuousplaybackStandaloneRTSAudioClipTest() { Assert.assertNotNull(recommendedList.getRecommendationId()); Assert.assertTrue(recommendedList.getRecommendationId().startsWith("ch.srgssr.playfff:EpisodeComposition/LatestByShow/" + showURN + "/Clip/")); Assert.assertTrue(recommendedList.getRecommendationId().contains(mediaURN)); - Assert.assertNotNull(recommendedList.getUrns()); - Assert.assertTrue(recommendedList.getUrns().size() > 0); - Assert.assertTrue(recommendedList.getUrns().size() < 50); + assertValidList(recommendedList); } @Test @@ -117,9 +109,7 @@ public void getRecommendedUrnsContinuousplaybackSRFTest() { boolean standalone = false; RecommendedList recommendedList = recommendationService.getRecommendedUrns(purpose, mediaURN, standalone); - Assert.assertNull(recommendedList.getRecommendationId()); - Assert.assertNotNull(recommendedList.getUrns()); - Assert.assertEquals(recommendedList.getUrns().size(), 0); + assertInvalidList(recommendedList); } @Test @@ -129,9 +119,7 @@ public void getRecommendedUrnsContinuousplaybackStandaloneSRFTest() { boolean standalone = true; RecommendedList recommendedList = recommendationService.getRecommendedUrns(purpose, mediaURN, standalone); - Assert.assertNull(recommendedList.getRecommendationId()); - Assert.assertNotNull(recommendedList.getUrns()); - Assert.assertEquals(recommendedList.getUrns().size(), 0); + assertInvalidList(recommendedList); } @Test @@ -141,9 +129,7 @@ public void getRecommendedUrnsContinuousplaybackSwissTxtTest() { boolean standalone = false; RecommendedList recommendedList = recommendationService.getRecommendedUrns(purpose, mediaURN, standalone); - Assert.assertNull(recommendedList.getRecommendationId()); - Assert.assertNotNull(recommendedList.getUrns()); - Assert.assertEquals(recommendedList.getUrns().size(), 0); + assertInvalidList(recommendedList); } @Test @@ -153,6 +139,49 @@ public void getRecommendedUrnsContinuousplaybackStandaloneSwisstxtTest() { boolean standalone = true; RecommendedList recommendedList = recommendationService.getRecommendedUrns(purpose, mediaURN, standalone); + assertInvalidList(recommendedList); + } + + @Test + public void playHomeTestInvalidType() { + RecommendedList recommendedList = recommendationService.getPersonalRecommendation("invalid type", "unknown"); + + assertInvalidList(recommendedList); + } + + @Test + public void playHomeTestInvalidUser() { + RecommendedList recommendedList = recommendationService.getPersonalRecommendation("rtsPeachHome", "invalid user"); + + assertValidList(recommendedList); + } + + @Test + public void playHomeTestUserUnknown() { + RecommendedList recommendedList = recommendationService.getPersonalRecommendation("rtsPeachHome", "unknown"); + + assertValidList(recommendedList); + } + + @Test + public void playHomeTestUser9() { + RecommendedList recommendedList = recommendationService.getPersonalRecommendation("rtsPeachHome", "9"); + + assertValidList(recommendedList); + } + + private void assertValidList(RecommendedList recommendedList) { + Assert.assertTrue(recommendedList.getUrns().size() > 0); + Assert.assertTrue(recommendedList.getUrns().size() < 50); + } + + private void assertEmptyList(RecommendedList recommendedList) { + Assert.assertNotNull(recommendedList.getRecommendationId()); + Assert.assertNotNull(recommendedList.getUrns()); + Assert.assertEquals(recommendedList.getUrns().size(), 0); + } + + private void assertInvalidList(RecommendedList recommendedList) { Assert.assertNull(recommendedList.getRecommendationId()); Assert.assertNotNull(recommendedList.getUrns()); Assert.assertEquals(recommendedList.getUrns().size(), 0); From b20bc95c4c53e1895ba4d58f962a004fee6a698b Mon Sep 17 00:00:00 2001 From: Sebastien Chauvin Date: Mon, 11 Feb 2019 14:34:36 +0100 Subject: [PATCH 2/6] Remove guava dependency --- pom.xml | 326 +++++++++--------- .../pfff/service/RecommendationService.java | 14 +- 2 files changed, 165 insertions(+), 175 deletions(-) diff --git a/pom.xml b/pom.xml index c5cdd1d..eaf286f 100644 --- a/pom.xml +++ b/pom.xml @@ -1,58 +1,58 @@ - 4.0.0 - - - - Pfff repository - https://raw.github.com/SRGSSR/pfff/mvn-repo/ - - - - com.example - pfff - 9 - jar - - pfff - Play Features and Functionalities with Flair - - - org.springframework.boot - spring-boot-starter-parent - 1.5.9.RELEASE - - - - - UTF-8 - UTF-8 - 1.8 - - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.postgresql - postgresql - 9.4-1201-jdbc4 - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + + + Pfff repository + https://raw.github.com/SRGSSR/pfff/mvn-repo/ + + + + com.example + pfff + 9 + jar + + pfff + Play Features and Functionalities with Flair + + + org.springframework.boot + spring-boot-starter-parent + 1.5.9.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.postgresql + postgresql + 9.4-1201-jdbc4 + com.h2database @@ -64,117 +64,111 @@ spring-boot-starter-thymeleaf - - org.springframework.boot - spring-boot-starter-security - - - - org.springframework.security - spring-security-test - test - - - - org.webjars - jquery - 3.3.1 - - - org.webjars - bootstrap - 3.3.7 - - - org.webjars - webjars-locator - - - org.webjars - font-awesome - 5.4.1 - - - org.assertj - assertj-core - - - ch.srf.integrationlayer - integrationlayer-domain-objects - 1.20.272 - - - - com.google.guava - guava - 27.0.1-jre - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - maven-clean-plugin - 2.5 - - - - src/main/resources/static - - * - - - - - - - - com.github.eirslett - frontend-maven-plugin - 1.6 - - portal-app - - - - install node and npm - - install-node-and-npm - - - v6.9.5 - 3.10.10 - - - - - npm install - - npm - - - install - - - - - prod - - npm - - - run-script prod - - generate-resources - - - - - + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.security + spring-security-test + test + + + + org.webjars + jquery + 3.3.1 + + + org.webjars + bootstrap + 3.3.7 + + + org.webjars + webjars-locator + + + org.webjars + font-awesome + 5.4.1 + + + org.assertj + assertj-core + + + ch.srf.integrationlayer + integrationlayer-domain-objects + 1.20.272 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + maven-clean-plugin + 2.5 + + + + src/main/resources/static + + * + + + + + + + + com.github.eirslett + frontend-maven-plugin + 1.6 + + portal-app + + + + install node and npm + + install-node-and-npm + + + v6.9.5 + 3.10.10 + + + + + npm install + + npm + + + install + + + + + prod + + npm + + + run-script prod + + generate-resources + + + + + diff --git a/src/main/java/com/example/pfff/service/RecommendationService.java b/src/main/java/com/example/pfff/service/RecommendationService.java index 11d4532..f8fb18b 100644 --- a/src/main/java/com/example/pfff/service/RecommendationService.java +++ b/src/main/java/com/example/pfff/service/RecommendationService.java @@ -8,8 +8,6 @@ import com.example.pfff.model.peach.PersonalRecommendationResult; import com.example.pfff.model.RecommendedList; import com.example.pfff.model.peach.RecommendationResult; -import com.google.common.collect.Lists; -import org.checkerframework.checker.nullness.qual.NonNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; @@ -18,6 +16,7 @@ import org.springframework.web.util.UriComponentsBuilder; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -35,7 +34,6 @@ public RecommendationService() { restTemplate = new RestTemplate(); } - @NonNull public RecommendedList getRecommendedUrns(String purpose, String urn, boolean standalone) { if (urn.contains(":rts:")) { if (urn.contains(":video:")) { @@ -50,7 +48,6 @@ public RecommendedList getRecommendedUrns(String purpose, String urn, boolean st } } - @NonNull private RecommendedList rtsAudioRecommendedList(String urn) { Media media = integrationLayerRequest.getMedia(urn, Environment.PROD); if (media == null || media.getType() == LIVESTREAM || media.getType() == SCHEDULED_LIVESTREAM || media.getShow() == null) { @@ -64,7 +61,8 @@ private RecommendedList rtsAudioRecommendedList(String urn) { return new RecommendedList(); } - List episodes = Lists.reverse(episodeComposition.getList()); + List episodes = new ArrayList<>(episodeComposition.getList()); + Collections.reverse(episodes); List fullLengthUrns = episodes.stream().map(EpisodeWithMedias::getFullLengthUrn).collect(Collectors.toList()); List clipUrns = episodes.stream().flatMap(e -> e.getMediaList().stream().filter(m -> m.getMediaType() == MediaType.AUDIO)).map(Media::getUrn).collect(Collectors.toList()); clipUrns.removeAll(fullLengthUrns); @@ -101,7 +99,8 @@ private RecommendedList rtsAudioRecommendedList(String urn) { urns.remove(urn); if (episodeComposition.getNext() != null) { - recommendationResult.addAll(Lists.reverse(urns)); + Collections.reverse(urns); + recommendationResult.addAll(urns); } else { recommendationResult.addAll(urns); } @@ -116,7 +115,6 @@ private RecommendedList rtsAudioRecommendedList(String urn) { return new RecommendedList(host, recommendationId, recommendationResult); } - @NonNull private RecommendedList rtsVideoRecommendedList(String purpose, String urn, boolean standalone) { UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance().scheme("http") .host("peach.ebu.io").path("api/v1/chrts/continuous_playback_mobile"); @@ -134,7 +132,6 @@ private RecommendedList rtsVideoRecommendedList(String purpose, String urn, bool recommendationResult.getUrns()); } - @NonNull public RecommendedList getPersonalRecommendation(String type, String userId) { switch (type) { case "rtsPeachHome": @@ -145,7 +142,6 @@ public RecommendedList getPersonalRecommendation(String type, String userId) { } - @NonNull private RecommendedList rtsPlayHomePersonalRecommendation(String userId) { UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance().scheme("http") .host("peach.ebu.io").path("api/v1/chrts/play_home_personal_rec"); From b21f900d7f766e14c1c11f34552306b1e764881c Mon Sep 17 00:00:00 2001 From: Pierre-Yves Bertholon Date: Mon, 11 Feb 2019 16:53:38 +0100 Subject: [PATCH 3/6] Remove unused import and method --- .../pfff/controller/RecommendationServiceTests.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/test/java/com/example/pfff/controller/RecommendationServiceTests.java b/src/test/java/com/example/pfff/controller/RecommendationServiceTests.java index fefd3d3..a1e9535 100644 --- a/src/test/java/com/example/pfff/controller/RecommendationServiceTests.java +++ b/src/test/java/com/example/pfff/controller/RecommendationServiceTests.java @@ -9,12 +9,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import java.util.List; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @RunWith(SpringRunner.class) @SpringBootTest public class RecommendationServiceTests { @@ -175,12 +169,6 @@ private void assertValidList(RecommendedList recommendedList) { Assert.assertTrue(recommendedList.getUrns().size() < 50); } - private void assertEmptyList(RecommendedList recommendedList) { - Assert.assertNotNull(recommendedList.getRecommendationId()); - Assert.assertNotNull(recommendedList.getUrns()); - Assert.assertEquals(recommendedList.getUrns().size(), 0); - } - private void assertInvalidList(RecommendedList recommendedList) { Assert.assertNull(recommendedList.getRecommendationId()); Assert.assertNotNull(recommendedList.getUrns()); From 0b0477bfce158d3d270389274d75141c1ae5c1c4 Mon Sep 17 00:00:00 2001 From: Sebastien Chauvin Date: Tue, 12 Feb 2019 08:57:40 +0100 Subject: [PATCH 4/6] Simplify API --- .../pfff/controller/RecommendationController.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/example/pfff/controller/RecommendationController.java b/src/main/java/com/example/pfff/controller/RecommendationController.java index bcdc197..b0ae925 100644 --- a/src/main/java/com/example/pfff/controller/RecommendationController.java +++ b/src/main/java/com/example/pfff/controller/RecommendationController.java @@ -4,10 +4,7 @@ import com.example.pfff.service.RecommendationService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.view.RedirectView; import org.springframework.web.util.UriComponentsBuilder; @@ -63,12 +60,11 @@ private RecommendedList getRecommendationList(@PathVariable("purpose") String pu } - @RequestMapping("/api/v2/playlist/personal_recommendation/{type}/{userId}") + @RequestMapping("/api/v2/playlist/personalRecommendation/{userId}") @ResponseBody RecommendedList personalRecommendation( - HttpServletRequest request, - @PathVariable("type") String type, @PathVariable("userId") String userId) { - return service.getPersonalRecommendation(type, userId); + HttpServletRequest request, @PathVariable("userId") String userId) { + return service.getPersonalRecommendation("rtsPeachHome", userId); } } From c2676add8b97abf0530f0e09f9080558bdd29267 Mon Sep 17 00:00:00 2001 From: Sebastien Chauvin Date: Tue, 12 Feb 2019 10:26:54 +0100 Subject: [PATCH 5/6] Simplify service, remove named service userId as optional query parameter --- .../pfff/controller/RecommendationController.java | 8 ++++---- .../example/pfff/service/RecommendationService.java | 12 +----------- .../pfff/controller/RecommendationServiceTests.java | 13 +++---------- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/example/pfff/controller/RecommendationController.java b/src/main/java/com/example/pfff/controller/RecommendationController.java index b0ae925..58cefa7 100644 --- a/src/main/java/com/example/pfff/controller/RecommendationController.java +++ b/src/main/java/com/example/pfff/controller/RecommendationController.java @@ -59,12 +59,12 @@ private RecommendedList getRecommendationList(@PathVariable("purpose") String pu return recommendedList; } - - @RequestMapping("/api/v2/playlist/personalRecommendation/{userId}") + @RequestMapping("/api/v2/playlist/personalRecommendation") @ResponseBody RecommendedList personalRecommendation( - HttpServletRequest request, @PathVariable("userId") String userId) { - return service.getPersonalRecommendation("rtsPeachHome", userId); + HttpServletRequest request, + @RequestParam(value = "user", required = false, defaultValue = "unknown") String userId) { + return service.rtsPlayHomePersonalRecommendation(userId); } } diff --git a/src/main/java/com/example/pfff/service/RecommendationService.java b/src/main/java/com/example/pfff/service/RecommendationService.java index f8fb18b..868dd94 100644 --- a/src/main/java/com/example/pfff/service/RecommendationService.java +++ b/src/main/java/com/example/pfff/service/RecommendationService.java @@ -132,17 +132,7 @@ private RecommendedList rtsVideoRecommendedList(String purpose, String urn, bool recommendationResult.getUrns()); } - public RecommendedList getPersonalRecommendation(String type, String userId) { - switch (type) { - case "rtsPeachHome": - return rtsPlayHomePersonalRecommendation(userId); - default: - return new RecommendedList(); - } - - } - - private RecommendedList rtsPlayHomePersonalRecommendation(String userId) { + public RecommendedList rtsPlayHomePersonalRecommendation(String userId) { UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance().scheme("http") .host("peach.ebu.io").path("api/v1/chrts/play_home_personal_rec"); uriComponentsBuilder.queryParam("user_id", userId); diff --git a/src/test/java/com/example/pfff/controller/RecommendationServiceTests.java b/src/test/java/com/example/pfff/controller/RecommendationServiceTests.java index a1e9535..73c45eb 100644 --- a/src/test/java/com/example/pfff/controller/RecommendationServiceTests.java +++ b/src/test/java/com/example/pfff/controller/RecommendationServiceTests.java @@ -136,30 +136,23 @@ public void getRecommendedUrnsContinuousplaybackStandaloneSwisstxtTest() { assertInvalidList(recommendedList); } - @Test - public void playHomeTestInvalidType() { - RecommendedList recommendedList = recommendationService.getPersonalRecommendation("invalid type", "unknown"); - - assertInvalidList(recommendedList); - } - @Test public void playHomeTestInvalidUser() { - RecommendedList recommendedList = recommendationService.getPersonalRecommendation("rtsPeachHome", "invalid user"); + RecommendedList recommendedList = recommendationService.rtsPlayHomePersonalRecommendation("invalid user"); assertValidList(recommendedList); } @Test public void playHomeTestUserUnknown() { - RecommendedList recommendedList = recommendationService.getPersonalRecommendation("rtsPeachHome", "unknown"); + RecommendedList recommendedList = recommendationService.rtsPlayHomePersonalRecommendation("unknown"); assertValidList(recommendedList); } @Test public void playHomeTestUser9() { - RecommendedList recommendedList = recommendationService.getPersonalRecommendation("rtsPeachHome", "9"); + RecommendedList recommendedList = recommendationService.rtsPlayHomePersonalRecommendation("9"); assertValidList(recommendedList); } From f346dc20b574a9cb28344f12c1b756d3eff726a0 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Bertholon Date: Tue, 12 Feb 2019 10:49:42 +0100 Subject: [PATCH 6/6] Update documentation --- docs/README.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index f1aa8a1..059c5ff 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,7 +24,8 @@ A wide list of parameters are available. * `urn` (string): an unique identifier. * `recommendedList` (object): a recommended result list with proterties: * `recommendationId` (string): the recommendation identifer from the service. - * `urns`(array): array of `urn`. + * `urns` (array): array of `urn`. + * `title` (string, optional): title of the playlist. * `package` (string): Android package name or iOS bundle identifier. * `version` (string): mobile application version. @@ -43,16 +44,22 @@ A wide list of parameters are available. * `/api/v1/whatisnew/text?package={package}&version={version}` : get WhatIsNewResult object. * `/api/v1/whatisnew/html?package={package}&version={version}` : get What's new html format. -#### Recommendation +#### Recommendation for a media * `/api/v2/playlist/recommendation/continuousPlayback/{urn}` : get media list object. * `standalone` (optional, boolean): Recommendation for the playback mode. Default is `false`. * Returns a `recommendedList` object. -* `/api/v1/playlist/recommendation/continuousPlayback/{urn}` : get media list object. +* *Deprecated* `/api/v1/playlist/recommendation/continuousPlayback/{urn}` : get media list object. * `standalone` (optional, boolean): Recommendation for the playback mode. Default is `false`. * `format` (optional, string): If set to `urn`, it returns an URN list. Default is `media` and redirects to an IL media list response. +#### Personnal recommendation for a user + +* `/api/v2/playlist/recommendation/personalRecommendation` : get media list object. + * `user` (optional, string): `UserId` to use for a personal recommendation. + * Returns a `recommendedList` object. + ## Private APIs Private APIs need a user authentification.