BC export, first look
authorVásáry Dániel <vasary@elgekko.net>
Wed, 15 Nov 2023 19:49:05 +0000 (20:49 +0100)
committerVásáry Dániel <vasary@elgekko.net>
Wed, 15 Nov 2023 19:49:05 +0000 (20:49 +0100)
33 files changed:
mc-vod-sync/QUESTIONS.md
mc-vod-sync/mc-vod-sync-app/src/main/java/hu/user/mcvodsync/VodSyncEntry.java
mc-vod-sync/mc-vod-sync-app/src/main/resources/application-dev.yaml
mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/AssetMapperIT.java [new file with mode: 0644]
mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/BrightCoveClientIT.java
mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/EmailSendServiceTest.java [new file with mode: 0644]
mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/RepositoryIT.java
mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/VodSyncEntryTest.java [deleted file]
mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/VodXlsProcessorIT.java
mc-vod-sync/mc-vod-sync-brightcove/pom.xml
mc-vod-sync/mc-vod-sync-brightcove/src/main/java/hu/user/mcvodsync/brightcove/BrightCoveClient.java
mc-vod-sync/mc-vod-sync-brightcove/src/main/java/hu/user/mcvodsync/brightcove/ExtendedApiClient.java [new file with mode: 0644]
mc-vod-sync/mc-vod-sync-brightcove/src/main/java/hu/user/mcvodsync/brightcove/PagedSearch.java [new file with mode: 0644]
mc-vod-sync/mc-vod-sync-brightcove/src/main/java/hu/user/mcvodsync/brightcove/RestTemplateResponseErrorHandler.java [new file with mode: 0644]
mc-vod-sync/mc-vod-sync-brightcove/src/main/resources/openapi.yaml
mc-vod-sync/mc-vod-sync-db/migrations/scripts/003_create_business_tables.sql
mc-vod-sync/mc-vod-sync-db/pom.xml
mc-vod-sync/mc-vod-sync-db/src/main/java/hu/user/mcvodsync/db/Asset.java
mc-vod-sync/mc-vod-sync-db/src/main/java/hu/user/mcvodsync/db/AssetSync.java
mc-vod-sync/mc-vod-sync-db/src/main/java/hu/user/mcvodsync/db/PlaylistSync.java
mc-vod-sync/mc-vod-sync-db/src/main/java/hu/user/mcvodsync/db/SyncType.java
mc-vod-sync/mc-vod-sync-db/src/main/java/hu/user/mcvodsync/db/repository/AssetSyncRepository.java
mc-vod-sync/mc-vod-sync-service/pom.xml
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/ServiceProperties.java [new file with mode: 0644]
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/export/AssetExportService.java [new file with mode: 0644]
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/export/CustomPropertiesTranslator.java [new file with mode: 0644]
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/export/VideoMapper.java [new file with mode: 0644]
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/import/AssetImportService.java [moved from mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/xls/AssetImportService.java with 96% similarity]
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/import/AssetMapper.java [moved from mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/xls/AssetMapper.java with 100% similarity]
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/import/ImportSummary.java [moved from mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/xls/ImportSummary.java with 100% similarity]
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/import/VodXlsProcessor.java [moved from mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/xls/VodXlsProcessor.java with 100% similarity]
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/mail/EmailSendService.java [new file with mode: 0644]
mc-vod-sync/pom.xml

index 2bff3a6c3c06b38828b13014e771dc8956d5d027..196c36f87043ac40968fa242c16a641150e43810 100644 (file)
@@ -1,3 +1,6 @@
+* A custom fields API kellhet? Ott be lehet állítani a custom filed-re pl. azt, hogy kötelező e, így amíg nincs értéke
+  addig a videó nem aktív. Ennek használata nélkül is létrehozható video?
+*
 * A sunset kezelése is kell, tehát jöhet adat későbbi sunset-el?
 * A sunset és sunrise formátuma legyen egyforma (mindegy melyik) minden sorra!
 * Mik a kötelező mezők? Most: playlist, sunset, sunrise, title
index cbabc15b41ab20b4e6b522b06ee6b109d4b6c079..065235ddced46870cc93a61259096813f729bcc2 100644 (file)
@@ -8,9 +8,7 @@ package hu.user.mcvodsync;
 import lombok.extern.log4j.Log4j2;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.builder.SpringApplicationBuilder;
 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
-import org.springframework.context.ApplicationContext;
 import org.springframework.core.SpringVersion;
 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 import org.springframework.scheduling.annotation.EnableScheduling;
@@ -23,19 +21,9 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 @EnableScheduling
 public class VodSyncEntry extends SpringBootServletInitializer {
 
-
     public static void main(String[] args) {
-//        AnsiConsole.systemInstall();
-//        System.out.println( ansi().eraseScreen());
         log.info("Spring version: {}", SpringVersion.getVersion());
-        ApplicationContext applicationContext = SpringApplication.run(VodSyncEntry.class, args);
-//        AnsiConsole.systemUninstall();
-    }
-
-    @Override
-    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
-        logger.info("Starting configure");
-        return builder.sources(VodSyncEntry.class);
+        SpringApplication.run(VodSyncEntry.class, args);
     }
 
 }
index e37ada87110f879183728712c00252b86ba4b8cf..167d87e6a821ddd67fc4840807a9c60d5afd478d 100644 (file)
@@ -24,6 +24,13 @@ spring:
     retrieveMessagesFromServerOnGetMessage: true
     username: db2admin
     password: password
+  mail:
+    host: mx.in.useribm.hu
+#    port: 587
+#  spring.mail.username=<login user to smtp server>
+#  spring.mail.password=<login password to smtp server>
+#  spring.mail.properties.mail.smtp.auth=true
+#  spring.mail.properties.mail.smtp.starttls.enable=true
 camunda.bpm:
   generic-properties.properties:
     telemetry-reporter-activate: false
diff --git a/mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/AssetMapperIT.java b/mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/AssetMapperIT.java
new file mode 100644 (file)
index 0000000..44c4c85
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) $today.year-$today.month-24.
+ * By elGekko
+ */
+
+package hu.user.mcvodsync;
+
+import com.brightcove.cms.client.model.Video;
+import hu.user.mcvodsync.db.Asset;
+import hu.user.mcvodsync.service.export.VideoMapper;
+import lombok.extern.log4j.Log4j2;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.junit.Assert.assertEquals;
+
+
+@Log4j2
+@RunWith(SpringRunner.class)
+@ComponentScan("hu.user.lis")
+@SpringBootTest
+@ActiveProfiles("dev")
+public class AssetMapperIT {
+    @Autowired
+    private VideoMapper videoMapper;
+
+    @Test
+    public void mapAssetToVideoTest() {
+        Asset asset = Asset.builder()
+                .progLocalTitle("progLocalTitle")
+                .catalogId("catalogId")
+                .hubInfo("hubInfo")
+                .build();
+        Video video = videoMapper.toVideo(asset);
+
+        assertEquals(asset.getCatalogId(), video.getReferenceId());
+        assertEquals(asset.getProgLocalTitle(), video.getName());
+        assertEquals(asset.getHubInfo(), video.getCustomFields().get(VideoMapper.NOTES));
+    }
+
+    @Test
+    public void mapVideoToAssetTest() {
+        Video video = new Video();
+        video.setReferenceId("setReferenceId");
+        video.setName("name");
+        video.putCustomFieldsItem(VideoMapper.NOTES, "notes");
+        Asset asset = videoMapper.toAsset(video);
+
+        assertEquals(video.getReferenceId(), asset.getCatalogId());
+        assertEquals(video.getName(), asset.getProgLocalTitle());
+        assertEquals(video.getCustomFields().get(VideoMapper.NOTES), asset.getHubInfo());
+    }
+}
index 4bc34606c02a59fc7648825625a07860e04074ed..54f5874321c970812c88b8de57584d2b77a2d242 100644 (file)
@@ -2,8 +2,11 @@ package hu.user.mcvodsync;
 
 import com.brightcove.cms.client.model.CreateVideoRequestBodyFields;
 import com.brightcove.cms.client.model.Playlist;
+import com.brightcove.cms.client.model.PlaylistInputFields;
 import com.brightcove.cms.client.model.Video;
+import com.google.common.collect.ImmutableMap;
 import hu.user.mcvodsync.brightcove.BrightCoveClient;
+import hu.user.mcvodsync.brightcove.PagedSearch;
 import lombok.extern.log4j.Log4j2;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -13,8 +16,13 @@ import org.springframework.context.annotation.ComponentScan;
 import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @Log4j2
 @RunWith(SpringRunner.class)
@@ -28,14 +36,61 @@ public class BrightCoveClientIT {
     private BrightCoveClient bcClient;
 
 
+    private List<String> getVideos() {
+        List<String> ids = new ArrayList<>();
+        PagedSearch<Video> page = PagedSearch.<Video>builder()
+                .query("tags:mc-vod-sync")
+                .sort("reference_id")
+                .build();
+        while (bcClient.getVideosPaged(page)) {
+            List<String> currentIds = page.getData().stream().map(Video::getId).collect(Collectors.toList());
+            ids.addAll(currentIds);
+        }
+        return ids;
+    }
+
     @Test
-    public void testGetPlayLists() {
+    public void testCreate5PlayLists() {
         try {
-            List<Playlist> playLists = bcClient.getPlayLists(0, 10);
+            List<String> ids = getVideos();
+
+            for (int i = 1; i < 6; i++) {
+                PlaylistInputFields fields = new PlaylistInputFields();
+                fields.setType(PlaylistInputFields.TypeEnum.EXPLICIT);
+                fields.setName("Playlist 0000" + i);
+                fields.setVideoIds(ids);
+                fields.setDescription("mc-vod-sync");
+                Playlist playList = bcClient.createPlaylist(fields);
+                logPlaylist(playList);
+            }
+
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+
+    @Test
+    public void updatePlayLists() {
+        try {
+
+            PagedSearch<Playlist> page = PagedSearch.<Playlist>builder()
+                    .query("description:mc-vod-sync")
+                    .sort("name")
+                    .build();
+            bcClient.getPlaylistsPaged(page);
+            Playlist playlist = page.getData().get(0);
+            playlist.setVideoIds(getVideos());
+
+//            List<String> videoIds = playlist.getVideoIds();
+//            assertNotNull(videoIds);
+//            String id1 = videoIds.get(0);
+//            String id2 = videoIds.get(videoIds.size() - 1);
+//            videoIds.set(0, id2);
+//            videoIds.set(videoIds.size() - 1, id1);
 
-            playLists.forEach(playList -> {
-                log.info(playList.getName());
-            });
+
+            Playlist playList = bcClient.updatePlaylist(playlist);
+            logPlaylist(playList);
 
         } catch (Exception e) {
             log.error(e);
@@ -43,24 +98,42 @@ public class BrightCoveClientIT {
     }
 
     @Test
-    public void testGetVideos() {
+    public void testGetPlayLists() {
         try {
-            List<Video> videos = bcClient.getVideos(0, 10);
+            PagedSearch<Playlist> page = PagedSearch.<Playlist>builder()
+                    .query("description:mc-vod-sync")
+                    .sort("name")
+                    .build();
+            while (bcClient.getPlaylistsPaged(page)) {
+                page.getData().forEach(this::logPlaylist);
+            }
 
-            videos.forEach(video -> {
-                log.info("{} ref: {} {} {}", video.getId(), video.getReferenceId(), video.getName(), video.getState());
-            });
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
 
+    @Test
+    public void testGetVideos() {
+        try {
+            PagedSearch<Video> page = PagedSearch.<Video>builder()
+                    .query("tags:mc-vod-sync")
+                    .sort("reference_id")
+                    .build();
+            while (bcClient.getVideosPaged(page)) {
+                page.getData().forEach(this::logVideo);
+            }
         } catch (Exception e) {
             log.error(e);
         }
     }
 
+
     @Test
     public void testGetVideoById() {
         try {
             Video video = bcClient.getVideoById("6328122715112");
-            log.info("{} {} {}", video.getId(), video.getReferenceId(), video.getName());
+            logVideo(video);
         } catch (Exception e) {
             log.error(e);
         }
@@ -70,9 +143,7 @@ public class BrightCoveClientIT {
     public void testGetVideosById() {
         try {
             List<Video> videos = bcClient.getVideosById("6328122715112,6339727091112");
-            videos.forEach(video -> {
-                log.info("{} {} {}", video.getId(), video.getReferenceId(), video.getName());
-            });
+            videos.forEach(this::logVideo);
         } catch (Exception e) {
             log.error(e);
         }
@@ -84,11 +155,41 @@ public class BrightCoveClientIT {
         try {
             CreateVideoRequestBodyFields fields = new CreateVideoRequestBodyFields();
             fields.setName("TEST video 00001");
-            fields.setReferenceId("MCVODSYNC00001");
+            fields.setReferenceId("MCVODSYNC10001");
             fields.setState(CreateVideoRequestBodyFields.StateEnum.INACTIVE);
             fields.setEconomics(CreateVideoRequestBodyFields.EconomicsEnum.FREE);
+            fields.setTags(Collections.singletonList("mc-vod-sync"));
+            fields.setCustomFields(ImmutableMap.of("Notes", "notes"));
             Video video = bcClient.createVideo(fields);
-            log.info("{} {} {}", video.getId(), video.getReferenceId(), video.getName());
+            logVideo(video);
+
+
+            log.info("Search result");
+            List<Video> videos = bcClient.getVideos(0, 10, "tags:mc-vod-sync");
+            videos.forEach(this::logVideo);
+
+
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+
+    @Test
+    public void testCreate13Videos() {
+        try {
+
+            int i = 13;
+            while (i > 0) {
+                CreateVideoRequestBodyFields fields = new CreateVideoRequestBodyFields();
+                fields.setName("TEST video 0000" + i);
+                fields.setReferenceId("MCVODSYNC0000" + i);
+                fields.setState(CreateVideoRequestBodyFields.StateEnum.INACTIVE);
+                fields.setEconomics(CreateVideoRequestBodyFields.EconomicsEnum.FREE);
+                fields.setTags(Collections.singletonList("mc-vod-sync"));
+                Video video = bcClient.createVideo(fields);
+                logVideo(video);
+                i--;
+            }
         } catch (Exception e) {
             log.error(e);
         }
@@ -97,8 +198,27 @@ public class BrightCoveClientIT {
     @Test
     public void testGetVideoByRefId() {
         try {
-            Video video = bcClient.getVideoById("ref:MCVODSYNC00001");
-            log.info("{} {} {}", video.getId(), video.getReferenceId(), video.getName());
+            Video video = bcClient.getVideoByReferenceId("MCVODSYNC00001_");
+            logVideo(video);
+
+        } catch (HttpClientErrorException e) {
+            log.warn(e);
+        } catch (HttpServerErrorException e) {
+            log.error("Server error", e);
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+
+
+    @Test
+    public void deleteVideos() {
+        try {
+            List<Video> videos = bcClient.getVideos(0, 10, "tags:mc-vod-sync");
+            videos.forEach(video -> {
+                bcClient.deleteVideo(video.getId());
+            });
+
         } catch (Exception e) {
             log.error(e);
         }
@@ -107,11 +227,19 @@ public class BrightCoveClientIT {
     @Test
     public void testDeleteVideo() {
         try {
-            bcClient.deleteVideo("ref:MCVODSYNC00001");
+//            bcClient.deleteVideo("ref:MCVODSYNC00001");
+            bcClient.deleteVideo("6340725850112,6340726442112,6340725849112,6340727220112");
         } catch (Exception e) {
             log.error(e);
         }
     }
 
+    private void logVideo(Video video) {
+        log.info("{} ref: {} {} {} {} {}", video.getId(), video.getReferenceId(), video.getName(), video.getState(), video.getTags(), video.getCustomFields());
+    }
+
+    private void logPlaylist(Playlist playlist) {
+        log.info("{} {} {} {}\r\n{}", playlist.getId(), playlist.getName(), playlist.getType(), playlist.getDescription(), playlist.getVideoIds());
+    }
 
 }
diff --git a/mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/EmailSendServiceTest.java b/mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/EmailSendServiceTest.java
new file mode 100644 (file)
index 0000000..5976c91
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) $today.year-$today.month-24.
+ * By elGekko
+ */
+
+package hu.user.mcvodsync;
+
+import hu.user.mcvodsync.service.mail.EmailSendService;
+import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@ActiveProfiles("dev")
+@TestPropertySource("classpath:application-dev.yaml")
+public class EmailSendServiceTest {
+
+    @Autowired
+    EmailSendService emailSendService;
+
+
+    @Test
+    public void sendEmail() {
+        emailSendService.sendSimpleMessage();
+    }
+
+}
index 55d5a7b9a033c7dae9f29f8412dcfc84bb3cab75..fbf370dea07328be8142fc29272ad75acd205364 100644 (file)
@@ -5,6 +5,8 @@
 
 package hu.user.mcvodsync;
 
+import hu.user.mcvodsync.db.AssetSync;
+import hu.user.mcvodsync.db.SyncType;
 import hu.user.mcvodsync.db.repository.AssetRepository;
 import hu.user.mcvodsync.db.repository.AssetSyncRepository;
 import hu.user.mcvodsync.service.xls.AssetImportService;
@@ -16,16 +18,16 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import java.sql.Date;
+import java.time.Instant;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.List;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.*;
 
 
 @Log4j2
@@ -33,9 +35,6 @@ import static org.junit.Assert.assertNotNull;
 @ComponentScan("hu.user.lis")
 @SpringBootTest
 @ActiveProfiles("dev")
-//@Profile("dev")
-@TestPropertySource("classpath:application-dev.yaml")
-//@AutoConfigureMockMvc
 public class RepositoryIT {
     @Autowired
     private AssetRepository assetRepository;
@@ -71,4 +70,43 @@ public class RepositoryIT {
 
     }
 
+    @Test
+    public void queryForExport() {
+        List<AssetSync> assetSyncs = new ArrayList<>();
+
+        for (int i = 0; i < 3; i++) {
+            assetSyncs.add(AssetSync.builder()
+                    .syncType(SyncType.INSERT)
+                    .catalogId("XXX" + i)
+                    .build());
+            assetSyncs.add(AssetSync.builder()
+                    .syncType(SyncType.UPDATE)
+                    .catalogId("YYY" + i)
+                    .build());
+            assetSyncs.add(AssetSync.builder()
+                    .syncType(SyncType.DELETE)
+                    .catalogId("ZZZ" + i)
+                    .build());
+        }
+        assetSyncRepository.saveAllAndFlush(assetSyncs);
+
+        while (true) {
+            List<AssetSync> result = assetSyncRepository.findFirst100ByExportedSuccessIsNullOrderByCreated();
+            if (result.isEmpty()) {
+                break;
+            }
+            result.forEach(this::processAssetSync);
+        }
+
+        List<AssetSync> result = assetSyncRepository.findFirst100ByExportedSuccessIsNullOrderByCreated();
+        assertTrue(result.isEmpty());
+        assetSyncRepository.deleteAllInBatch();
+    }
+
+    private void processAssetSync(AssetSync assetSync) {
+        assetSync.setExportedSuccess(java.util.Date.from(Instant.now()));
+        assetSyncRepository.saveAndFlush(assetSync);
+        log.info("Processed {}", assetSync);
+    }
+
 }
diff --git a/mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/VodSyncEntryTest.java b/mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/VodSyncEntryTest.java
deleted file mode 100644 (file)
index b06d9e1..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) $today.year-$today.month-24.
- * By elGekko
- */
-
-package hu.user.mcvodsync;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-
-@SpringBootTest
-public class VodSyncEntryTest {
-
-
-    @Test
-    public void contextLoads() {
-
-    }
-
-}
index b1de9ce4be416e5a82818a8bb972c78c2f7a6b12..3799890e284425592f2629a0cf61abc92493489f 100644 (file)
@@ -16,7 +16,6 @@ import lombok.extern.log4j.Log4j2;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.junit.jupiter.api.Order;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -39,6 +38,7 @@ import static org.junit.Assert.assertEquals;
 @ActiveProfiles("dev")
 @TestPropertySource("classpath:application-dev.yaml")
 public class VodXlsProcessorIT {
+
     @Autowired
     private VodXlsProcessor vodXlsProcessor;
 
@@ -111,14 +111,12 @@ public class VodXlsProcessorIT {
     }
 
     @Test
-    @Order(5)
     public void changePlaylistAddAssetTest() {
         log.info("changePlaylistAddAssetTest");
 //        "src/test/resources/testdata-playlist-add-asset.xlsx"
     }
 
     @Test
-    @Order(6)
     public void changePlaylistRemoveAssetTest() {
         log.info("changePlaylistRemoveAssetTest");
 //        "src/test/resources/testdata-playlist-remove-asset.xlsx"
@@ -164,4 +162,5 @@ public class VodXlsProcessorIT {
         assertEquals(expectedAllCount, playlistSyncRepository.count());
     }
 
+
 }
index 9702cd7d8e812ad09be62ca763302ac4644e9df1..7166ef32b3482636e4753374e4e73ef329e4f15f 100644 (file)
             <artifactId>org.apache.oltu.oauth2.client</artifactId>
             <version>0.31</version>
         </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>org.apache.httpcomponents</groupId>-->
+        <!--            <artifactId>httpcore</artifactId>-->
+        <!--            <version>4.4.16</version>-->
+        <!--        </dependency>-->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.14</version>
+        </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-web</artifactId>
index 60def14aca7b834e17b98ac62d5b2daa96158a7e..506d37d38f4f6ba2b709a72df9e2292333ca7333 100644 (file)
@@ -1,10 +1,9 @@
 package hu.user.mcvodsync.brightcove;
 
+import com.brightcove.cms.client.ApiClient;
 import com.brightcove.cms.client.api.PlaylistsApi;
 import com.brightcove.cms.client.api.VideosApi;
-import com.brightcove.cms.client.model.CreateVideoRequestBodyFields;
-import com.brightcove.cms.client.model.Playlist;
-import com.brightcove.cms.client.model.Video;
+import com.brightcove.cms.client.model.*;
 import lombok.extern.log4j.Log4j2;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.oltu.oauth2.client.OAuthClient;
@@ -24,19 +23,25 @@ import org.springframework.web.client.RestClientException;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 @Log4j2
 @Service
 public class BrightCoveClient {
     private String authToken;
     public static final String BEARER = "Bearer ";
+    private final ApiClient apiClient = new ExtendedApiClient();
     private final PlaylistsApi playListApi = new PlaylistsApi();
-
     private final VideosApi videosApi = new VideosApi();
 
     @Autowired
     private ApiProperties apiProperties;
 
+    public BrightCoveClient() {
+        playListApi.setApiClient(apiClient);
+        videosApi.setApiClient(apiClient);
+    }
+
     public String createToken() {
         String token = null;
         try {
@@ -63,19 +68,103 @@ public class BrightCoveClient {
         return authToken;
     }
 
-    public List<Playlist> getPlayLists(int offset, int limit) throws RestClientException {
+    public Playlist updatePlaylist(Playlist playlist) {
+        PlaylistInputFields fields = new PlaylistInputFields();
+        fields.setVideoIds(playlist.getVideoIds());
+        fields.setDescription(playlist.getDescription());
+        fields.setType(PlaylistInputFields.TypeEnum.EXPLICIT);
+        fields.setName(playlist.getName());
+        return playListApi.updatePlaylist(apiProperties.getAccountId(), playlist.getId(), MediaType.APPLICATION_JSON_VALUE, getToken(), fields);
+    }
+
+    public Playlist createPlaylist(PlaylistInputFields fields) {
+        return playListApi.createPlaylist(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE, getToken(), fields);
+    }
+
+    public List<Playlist> getPlaylists(int offset, int limit) throws RestClientException {
         String q = null;
         String sort = null;
         return playListApi.getPlaylists(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE, getToken(), limit, offset, q, sort);
     }
 
-    public List<Video> getVideos(int offset, int limit) throws RestClientException {
+    public int getPlaylistCount(String query) {
+        int result = 0;
+        PlaylistCount playlistCount = playListApi.getPlaylistCount(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE, getToken(), query);
+        if (Objects.nonNull(playlistCount) && Objects.nonNull(playlistCount.getCount())) {
+            result = playlistCount.getCount();
+        }
+        return result;
+    }
+
+    public boolean getPlaylistsPaged(PagedSearch<Playlist> page) throws RestClientException {
+        if (page.getCount() == 0) {
+            int count = getPlaylistCount(page.getQuery());
+            page.setCount(count);
+            if (count > 0) {
+                page.setPages((int) Math.ceil((float) count / page.getLimit()));
+            } else {
+                return false;
+            }
+        }
+        page.setPage(page.getPage() + 1);
+        if (page.getPage() > page.getPages()) {
+            return false;
+        }
+        List<Playlist> playlists = playListApi.getPlaylists(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE,
+                getToken(), page.getLimit(), (page.getPage() - 1) * page.getLimit(), page.getQuery(), page.getSort());
+        if (playlists.isEmpty()) {
+            return false;
+        }
+        page.setData(playlists);
+        return true;
+    }
+
+    public int getVideosCount(String query) {
+        int result = 0;
+        VideoCount videoCount = videosApi.getVideoCount(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE, getToken(), query);
+        if (Objects.nonNull(videoCount) && Objects.nonNull(videoCount.getCount())) {
+            result = videoCount.getCount();
+        }
+        return result;
+    }
+
+
+    public List<Video> getVideos(int offset, int limit, String query) throws RestClientException {
         String sort = null;
-        String query = null;
         return videosApi.getVideos(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE,
                 getToken(), limit, offset, sort, query);
     }
 
+
+    public boolean getVideosPaged(PagedSearch<Video> page) throws RestClientException {
+        if (page.getCount() == 0) {
+            int count = getVideosCount(page.getQuery());
+            page.setCount(count);
+            if (count > 0) {
+                page.setPages((int) Math.ceil((float) count / page.getLimit()));
+            } else {
+                return false;
+            }
+        }
+        page.setPage(page.getPage() + 1);
+        if (page.getPage() > page.getPages()) {
+            return false;
+        }
+        List<Video> videos = videosApi.getVideos(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE,
+                getToken(), page.getLimit(), (page.getPage() - 1) * page.getLimit(), page.getSort(), page.getQuery());
+        if (videos.isEmpty()) {
+            return false;
+        }
+        page.setData(videos);
+        return true;
+    }
+
+
+    public Video getVideoByReferenceId(String referenceId) throws RestClientException {
+        return videosApi.getVideoByIdOrReferenceId(apiProperties.getAccountId(), "/ref:" + referenceId, MediaType.APPLICATION_JSON_VALUE,
+                getToken(), true);
+    }
+
     public Video getVideoById(String id) throws RestClientException {
         return videosApi.getVideoByIdOrReferenceId(apiProperties.getAccountId(), "/" + id, MediaType.APPLICATION_JSON_VALUE,
                 getToken(), true);
@@ -91,10 +180,24 @@ public class BrightCoveClient {
         return videosApi.createVideo(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE, getToken(), fields);
     }
 
+    public Video createVideo(Video video) {
+        CreateVideoRequestBodyFields fields = new CreateVideoRequestBodyFields();
+        fields.setName(video.getName());
+        fields.setReferenceId(video.getReferenceId());
+        fields.setCustomFields(video.getCustomFields());
+        fields.setTags(video.getTags());
+        return createVideo(fields);
+    }
+
+    public Video updateVideo(String videoId, Video video) {
+        return videosApi.updateVideo(apiProperties.getAccountId(), videoId, MediaType.APPLICATION_JSON_VALUE, getToken(), video);
+    }
+
     public void deleteVideo(String id) {
         videosApi.deleteVideo(apiProperties.getAccountId(), "/" + id, MediaType.APPLICATION_JSON_VALUE, getToken());
     }
 
+    //generated VideosApi returns Video entity not a List
     private ResponseEntity<List<Video>> getVideoByIdOrReferenceIdWithHttpInfo(String accountId, String videoIds, String contentType, String authorization, Boolean includeVariants) throws RestClientException {
         Object postBody = null;
 
diff --git a/mc-vod-sync/mc-vod-sync-brightcove/src/main/java/hu/user/mcvodsync/brightcove/ExtendedApiClient.java b/mc-vod-sync/mc-vod-sync-brightcove/src/main/java/hu/user/mcvodsync/brightcove/ExtendedApiClient.java
new file mode 100644 (file)
index 0000000..23e597c
--- /dev/null
@@ -0,0 +1,46 @@
+package hu.user.mcvodsync.brightcove;
+
+import com.brightcove.cms.client.ApiClient;
+import com.brightcove.cms.client.CustomInstantDeserializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.threetenbp.ThreeTenModule;
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.openapitools.jackson.nullable.JsonNullableModule;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
+import org.springframework.web.client.RestTemplate;
+import org.threeten.bp.Instant;
+import org.threeten.bp.OffsetDateTime;
+import org.threeten.bp.ZonedDateTime;
+
+public class ExtendedApiClient extends ApiClient {
+    @Override
+    protected RestTemplate buildRestTemplate() {
+        RestTemplateBuilder builder = new RestTemplateBuilder();
+//        RestTemplate restTemplate = builder.errorHandler(new RestTemplateResponseErrorHandler()).build();
+        RestTemplate restTemplate = builder.build();
+        for (HttpMessageConverter<?> converter : restTemplate.getMessageConverters()) {
+            if (converter instanceof AbstractJackson2HttpMessageConverter) {
+                ObjectMapper mapper = ((AbstractJackson2HttpMessageConverter) converter).getObjectMapper();
+                ThreeTenModule module = new ThreeTenModule();
+                module.addDeserializer(Instant.class, CustomInstantDeserializer.INSTANT);
+                module.addDeserializer(OffsetDateTime.class, CustomInstantDeserializer.OFFSET_DATE_TIME);
+                module.addDeserializer(ZonedDateTime.class, CustomInstantDeserializer.ZONED_DATE_TIME);
+                mapper.registerModule(module);
+                mapper.registerModule(new JsonNullableModule());
+            }
+        }
+
+        HttpClient httpClient = HttpClientBuilder.create().build();
+        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
+        restTemplate.setRequestFactory(requestFactory);
+//        // This allows us to read the response more than once - Necessary for debugging.
+//        restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(restTemplate.getRequestFactory()));
+        return restTemplate;
+    }
+
+
+}
diff --git a/mc-vod-sync/mc-vod-sync-brightcove/src/main/java/hu/user/mcvodsync/brightcove/PagedSearch.java b/mc-vod-sync/mc-vod-sync-brightcove/src/main/java/hu/user/mcvodsync/brightcove/PagedSearch.java
new file mode 100644 (file)
index 0000000..c75021e
--- /dev/null
@@ -0,0 +1,30 @@
+package hu.user.mcvodsync.brightcove;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+@Builder
+public class PagedSearch<T> {
+    private static final int DEFAULT_LIMIT = 10;
+
+    private int count;
+
+    private int pages;
+
+    private int page;
+
+    @Builder.Default
+    private int limit = DEFAULT_LIMIT;
+
+    private String query;
+
+    private String sort;
+
+
+    private List<T> data;
+}
diff --git a/mc-vod-sync/mc-vod-sync-brightcove/src/main/java/hu/user/mcvodsync/brightcove/RestTemplateResponseErrorHandler.java b/mc-vod-sync/mc-vod-sync-brightcove/src/main/java/hu/user/mcvodsync/brightcove/RestTemplateResponseErrorHandler.java
new file mode 100644 (file)
index 0000000..3033a1f
--- /dev/null
@@ -0,0 +1,38 @@
+package hu.user.mcvodsync.brightcove;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.ResourceAccessException;
+import org.springframework.web.client.ResponseErrorHandler;
+
+import java.io.IOException;
+
+import static org.springframework.http.HttpStatus.Series.CLIENT_ERROR;
+import static org.springframework.http.HttpStatus.Series.SERVER_ERROR;
+
+@Component
+public class RestTemplateResponseErrorHandler implements ResponseErrorHandler {
+
+    @Override
+    public boolean hasError(ClientHttpResponse httpResponse)
+            throws IOException {
+
+        return (
+                httpResponse.getStatusCode().series() == CLIENT_ERROR
+                        || httpResponse.getStatusCode().series() == SERVER_ERROR);
+    }
+
+    @Override
+    public void handleError(ClientHttpResponse httpResponse) throws IOException {
+
+        if (httpResponse.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR) {
+            // handle SERVER_ERROR
+        } else if (httpResponse.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR) {
+            // handle CLIENT_ERROR
+            if (httpResponse.getStatusCode() == HttpStatus.NOT_FOUND) {
+                throw new ResourceAccessException(httpResponse.getStatusText());
+            }
+        }
+    }
+}
\ No newline at end of file
index 0fc120cbedce03699e64cba9f558cd9912f91fb9..5d5f45b13e6933d3aaa0ec736308bdfb34ef2fed 100644 (file)
@@ -5453,7 +5453,7 @@ components:
           account_name: BC - Samples
           approved: true
         - account_id: '301925175'
-          account_name: BC Home Page Player
+          account_name: BC Home PagedSearch Player
           approved: true
       properties:
         account_id:
index 0cbf11a8ae7f6993517d36aa7a4b2c88806604cc..fc77f20224486c860397c049d7d3a71920edf7ee 100644 (file)
@@ -12,6 +12,7 @@ CREATE TABLE upload_file (
 
 CREATE TABLE asset (
     catalog_id VARCHAR(20) NOT NULL,
+    reference_id VARCHAR(20),
     season_id BIGINT NOT NULL,
     series_id BIGINT NOT NULL,
     sunset DATE NOT NULL,
index 6af02d015fd53e68b60bd6a482ba03b2cce4aac2..88a6bc1baf648967d8fe7e4707bc96b3ea161558 100644 (file)
@@ -33,7 +33,7 @@
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>
-            <version>2.7.13</version>
+            <!--            <version>2.7.13</version>-->
         </dependency>
         <dependency>
             <groupId>com.ibm.db2</groupId>
index cf93512b3cb315e7e0e0003d37a5a4d49cd66e10..5290e0615d21201bdfd9584d17b8f62a72f10acc 100644 (file)
@@ -21,6 +21,8 @@ public class Asset implements Serializable {
 
     private Long seasonId;
 
+    private String referenceId;
+
     private Long seriesId;
 
     @Column(nullable = false)
index 96482d75fa14fe79ebcfed09a788cf0364a39d37..1790880366e7a65b2b3f7d3ed0efa54d9cd7eb48 100644 (file)
@@ -1,6 +1,7 @@
 package hu.user.mcvodsync.db;
 
 import lombok.*;
+import org.hibernate.annotations.CreationTimestamp;
 
 import javax.persistence.*;
 import java.io.Serializable;
@@ -20,7 +21,8 @@ public class AssetSync implements Serializable {
 
     private String catalogId;
 
-    @Column(nullable = false)
+    @CreationTimestamp
+    @Column(updatable = false)
     private Date created;
 
     @Enumerated(EnumType.STRING)
index df4efa6fce1123e6dab02214fd5609822086196f..d620552e423f44c7add752f8cd5412b52d66626b 100644 (file)
@@ -1,6 +1,7 @@
 package hu.user.mcvodsync.db;
 
 import lombok.*;
+import org.hibernate.annotations.CreationTimestamp;
 
 import javax.persistence.*;
 import java.io.Serializable;
@@ -20,7 +21,8 @@ public class PlaylistSync implements Serializable {
 
     private String playlist;
 
-    @Column(nullable = false)
+    @CreationTimestamp
+    @Column(updatable = false)
     private Date created;
 
     @Enumerated(EnumType.STRING)
index 1622e91ee5b5e1598e39a76c779b2ceff118c37f..8f2c8feb5af4f01e14444be67bc9f1a96444974d 100644 (file)
@@ -1,5 +1,5 @@
 package hu.user.mcvodsync.db;
 
 public enum SyncType {
-    INSERT, UPDATE, DELETE, ERROR
+    INSERT, UPDATE, DELETE
 }
index 0c372c1c72261885fcae1a87bbab0d70c279422e..dbf790a6c30f5d7391bc16322e673365672c958c 100644 (file)
@@ -2,10 +2,18 @@ package hu.user.mcvodsync.db.repository;
 
 import hu.user.mcvodsync.db.AssetSync;
 import hu.user.mcvodsync.db.SyncType;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
 
+import java.util.List;
+
 public interface AssetSyncRepository extends JpaRepository<AssetSync, String> {
 
     long countBySyncType(SyncType syncType);
 
+    Page<AssetSync> findAllByExportedSuccessIsNullOrderByCreated(Pageable page);
+
+    List<AssetSync> findFirst100ByExportedSuccessIsNullOrderByCreated();
+
 }
index 0dbfe32e87daf827ac21b825fbb5f9e4f6982789..d7576b59510b72c45f0ee3c8a01b6b573c32bec8 100644 (file)
             <artifactId>spring-context</artifactId>
             <version>5.3.24</version>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-mail</artifactId>
+        </dependency>
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
             <version>1.4.0</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>hu.user</groupId>
+            <artifactId>mc-vod-sync-brightcove</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/ServiceProperties.java b/mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/ServiceProperties.java
new file mode 100644 (file)
index 0000000..6a7717e
--- /dev/null
@@ -0,0 +1,17 @@
+package hu.user.mcvodsync.service;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Getter
+@Setter
+@Component
+@ConfigurationProperties(prefix = "mc-vod-sync.service")
+public class ServiceProperties {
+
+    private boolean targetVideoInsertEnabled;
+
+    private boolean targetPlaylistInsertEnabled;
+}
diff --git a/mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/export/AssetExportService.java b/mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/export/AssetExportService.java
new file mode 100644 (file)
index 0000000..3629b82
--- /dev/null
@@ -0,0 +1,124 @@
+package hu.user.mcvodsync.service.export;
+
+
+import com.brightcove.cms.client.model.Video;
+import hu.user.mcvodsync.brightcove.BrightCoveClient;
+import hu.user.mcvodsync.db.Asset;
+import hu.user.mcvodsync.db.AssetSync;
+import hu.user.mcvodsync.db.SyncType;
+import hu.user.mcvodsync.db.repository.AssetRepository;
+import hu.user.mcvodsync.db.repository.AssetSyncRepository;
+import hu.user.mcvodsync.db.repository.PlaylistSyncRepository;
+import hu.user.mcvodsync.service.ServiceProperties;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.persistence.EntityNotFoundException;
+import java.time.Instant;
+import java.util.Date;
+import java.util.List;
+
+@Log4j2
+@Service
+public class AssetExportService {
+    @Autowired
+    private BrightCoveClient bcClient;
+
+    @Autowired
+    private AssetRepository assetRepository;
+
+    @Autowired
+    private AssetSyncRepository assetSyncRepository;
+
+    @Autowired
+    private PlaylistSyncRepository playlistSyncRepository;
+
+    @Autowired
+    private VideoMapper videoMapper;
+
+    @Autowired
+    private ServiceProperties serviceProperties;
+
+    public void export() {
+        while (true) {
+            List<AssetSync> result = assetSyncRepository.findFirst100ByExportedSuccessIsNullOrderByCreated();
+            if (result.isEmpty()) {
+                break;
+            }
+
+            if (serviceProperties.isTargetVideoInsertEnabled()) {
+                result.forEach(this::processAssetSync);
+            } else {
+                result.forEach(this::processAssetSyncWithoutInsert);
+            }
+        }
+
+    }
+
+    @Transactional
+    public void processAssetSyncWithoutInsert(AssetSync assetSync) {
+        try {
+            if (SyncType.DELETE.equals(assetSync.getSyncType())) {
+                //delete not necessary, remove only from all playlists
+                assetSync.setExportedSuccess(Date.from(Instant.now()));
+            } else {
+                Asset asset = assetRepository.findById(assetSync.getCatalogId()).orElseThrow(EntityNotFoundException::new);
+
+                Video video = bcClient.getVideoByReferenceId(asset.getCatalogId());
+
+                Video assetVideo = videoMapper.toVideo(asset);
+                if (SyncType.INSERT.equals(assetSync.getSyncType())) {
+                    Video createdVideo = bcClient.createVideo(assetVideo);
+                    asset.setReferenceId(createdVideo.getId());
+                    assetRepository.save(asset);
+                }
+                if (SyncType.UPDATE.equals(assetSync.getSyncType())) {
+                    if (StringUtils.isBlank(asset.getReferenceId())) {
+                        throw new IllegalArgumentException("Can not update Video when Asset entity reference ID is empty");
+                    }
+                    bcClient.updateVideo(asset.getReferenceId(), assetVideo);
+                }
+                assetSync.setExportedSuccess(Date.from(Instant.now()));
+            }
+        } catch (Exception e) {
+            log.error(e);
+            assetSync.setExportedError(Date.from(Instant.now()));
+        } finally {
+            assetSyncRepository.save(assetSync);
+        }
+    }
+
+    @Transactional
+    public void processAssetSync(AssetSync assetSync) {
+        try {
+            if (SyncType.DELETE.equals(assetSync.getSyncType())) {
+                //delete not necessary, remove only from all playlists
+                assetSync.setExportedSuccess(Date.from(Instant.now()));
+            } else {
+                Asset asset = assetRepository.findById(assetSync.getCatalogId()).orElseThrow(EntityNotFoundException::new);
+                Video assetVideo = videoMapper.toVideo(asset);
+                if (SyncType.INSERT.equals(assetSync.getSyncType())) {
+                    Video createdVideo = bcClient.createVideo(assetVideo);
+                    asset.setReferenceId(createdVideo.getId());
+                    assetRepository.save(asset);
+                }
+                if (SyncType.UPDATE.equals(assetSync.getSyncType())) {
+                    if (StringUtils.isBlank(asset.getReferenceId())) {
+                        throw new IllegalArgumentException("Can not update Video when Asset entity reference ID is empty");
+                    }
+                    bcClient.updateVideo(asset.getReferenceId(), assetVideo);
+                }
+                assetSync.setExportedSuccess(Date.from(Instant.now()));
+            }
+        } catch (Exception e) {
+            log.error(e);
+            assetSync.setExportedError(Date.from(Instant.now()));
+        } finally {
+            assetSyncRepository.save(assetSync);
+        }
+    }
+
+}
diff --git a/mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/export/CustomPropertiesTranslator.java b/mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/export/CustomPropertiesTranslator.java
new file mode 100644 (file)
index 0000000..91732fd
--- /dev/null
@@ -0,0 +1,9 @@
+package hu.user.mcvodsync.service.export;
+
+import org.mapstruct.Named;
+
+@Named("CustomPropertiesTranslator")
+public class CustomPropertiesTranslator {
+
+
+}
diff --git a/mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/export/VideoMapper.java b/mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/export/VideoMapper.java
new file mode 100644 (file)
index 0000000..431e5fc
--- /dev/null
@@ -0,0 +1,57 @@
+package hu.user.mcvodsync.service.export;
+
+import com.brightcove.cms.client.model.Video;
+import hu.user.mcvodsync.db.Asset;
+import org.mapstruct.Mapper;
+import org.mapstruct.ReportingPolicy;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
+public interface VideoMapper {
+
+    String NOTES = "Notes";
+    String SHOW = "Show";
+    String SEASON = "Season";
+    String EPISODE = "Episode";
+    String RATING_TV = "Rating TV";
+    String PRODUCTION_YEAR = "Production Year";
+
+    default Video toVideo(Asset asset) {
+        Video result = new Video();
+        result.setReferenceId(asset.getCatalogId());
+        result.setName(asset.getProgLocalTitle());
+        result.putCustomFieldsItem(NOTES, asset.getHubInfo());
+        result.putCustomFieldsItem(SHOW, asset.getSeasonLocalTitle());
+        if (Objects.nonNull(asset.getSeasonNr())) {
+            result.putCustomFieldsItem(SEASON, asset.getSeasonNr().toString());
+        }
+        if (Objects.nonNull(asset.getEpisodeNr())) {
+            result.putCustomFieldsItem(EPISODE, asset.getEpisodeNr().toString());
+        }
+        result.putCustomFieldsItem(RATING_TV, asset.getAgeRating());
+        if (Objects.nonNull(asset.getProductionYear())) {
+            result.putCustomFieldsItem(PRODUCTION_YEAR, asset.getProductionYear().toString());
+        }
+        return result;
+    }
+
+    default Asset toAsset(Video video) {
+        Asset result = Asset.builder()
+                .referenceId(video.getId())
+                .catalogId(video.getReferenceId())
+                .progLocalTitle(video.getName())
+                .build();
+        Optional<Map<String, String>> opCustomFields = Optional.ofNullable(video.getCustomFields());
+        opCustomFields.flatMap(fields -> Optional.ofNullable(fields.get(NOTES))).ifPresent(result::setHubInfo);
+        opCustomFields.flatMap(fields -> Optional.ofNullable(fields.get(SHOW))).ifPresent(result::setSeasonLocalTitle);
+        opCustomFields.flatMap(fields -> Optional.ofNullable(fields.get(SEASON))).ifPresent(val -> result.setSeasonNr(Integer.parseInt(val)));
+        opCustomFields.flatMap(fields -> Optional.ofNullable(fields.get(EPISODE))).ifPresent(val -> result.setEpisodeNr(Integer.parseInt(val)));
+        opCustomFields.flatMap(fields -> Optional.ofNullable(fields.get(RATING_TV))).ifPresent(result::setAgeRating);
+        opCustomFields.flatMap(fields -> Optional.ofNullable(fields.get(PRODUCTION_YEAR))).ifPresent(val -> result.setProductionYear(Integer.parseInt(val)));
+        return result;
+    }
+
+}
similarity index 96%
rename from mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/xls/AssetImportService.java
rename to mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/import/AssetImportService.java
index a33167c82b05a5c1e95284aab04c17352b12a446..c34dd3660723e6a6e82df613a7e4410f296c409e 100644 (file)
@@ -36,9 +36,9 @@ public class AssetImportService {
 
     private Map<String, List<String>> currentPlaylists;
 
-    private ImportSummary summary;
+    private hu.user.mcvodsync.service.xls.ImportSummary summary;
 
-    public void prepare(ImportSummary summary) {
+    public void prepare(hu.user.mcvodsync.service.xls.ImportSummary summary) {
         this.summary = summary;
         currentPlaylists = getPlayLists();
     }
@@ -57,7 +57,6 @@ public class AssetImportService {
         Optional<Asset> optionalEntity = assetRepository.findById(asset.getCatalogId());
 
         AssetSync assetSync = AssetSync.builder()
-                .created(Date.from(Instant.now()))
                 .catalogId(asset.getCatalogId())
                 .build();
 
@@ -88,7 +87,6 @@ public class AssetImportService {
         List<AssetSync> syncs = ids.stream().map(id -> AssetSync.builder()
                 .catalogId(id)
                 .syncType(SyncType.DELETE)
-                .created(Date.from(Instant.now()))
                 .build()).collect(Collectors.toList());
         assetSyncRepository.saveAll(syncs);
         assetRepository.deleteExpired(java.sql.Date.valueOf(currentDate));
diff --git a/mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/mail/EmailSendService.java b/mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/mail/EmailSendService.java
new file mode 100644 (file)
index 0000000..2eacce9
--- /dev/null
@@ -0,0 +1,23 @@
+package hu.user.mcvodsync.service.mail;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.stereotype.Service;
+
+@Service
+public class EmailSendService {
+    //    https://www.baeldung.com/spring-email
+    @Autowired
+    private JavaMailSender emailSender;
+
+    public void sendSimpleMessage() {
+        SimpleMailMessage message = new SimpleMailMessage();
+        message.setFrom("noreply@useribm.hu");
+        message.setTo("vasary@elgekko.net");
+        message.setSubject("Teszt");
+        message.setText("Teszt1");
+        emailSender.send(message);
+    }
+}
+
index 29435db4a18162c4734cf3dd29fe066537993dd8..912270cff8299367616e4daa6886d79927085aab 100644 (file)
@@ -54,9 +54,9 @@
                         </dependency>
                     </annotationProcessorPaths>
                     <compilerArgs>
-                        <compilerArg>
+                        <arg>
                             -Amapstruct.defaultComponentModel=spring
-                        </compilerArg>
+                        </arg>
                     </compilerArgs>
                 </configuration>
             </plugin>