# 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
- job-executor-acquire-by-priority: true
- job-execution:
- core-pool-size: 10
- #lock-time-in-millis: 600000
- database:
- type: db2
- schema-update: false
- table-prefix: CAMUNDA.
- schema-name: CAMUNDA
- webapp:
- enabled: true
- index-redirect-enabled: false
- admin-user:
- id: kermit
- password: password
- firstName: Kermit
- filter:
- create: All tasks
- job-execution.enabled: true
logging:
level:
org.hibernate.engine.jdbc.spi.SqlExceptionHelper: ERROR
mc-vod-sync:
+ scheduler:
+ import: true
+ export: true
+ sunrise-checker: true
application:
user-name: user
password: password
--- /dev/null
+/*
+ * Copyright (c) $today.year-$today.month-24.
+ * By elGekko
+ */
+
+package hu.user.mcvodsync;
+
+import hu.user.mcvodsync.db.PlaylistSync;
+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.in.ImportSummary;
+import hu.user.mcvodsync.service.in.VodXlsProcessor;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+
+@Log4j2
+public class AssetImportExportBase {
+ @Autowired
+ private VodXlsProcessor vodXlsProcessor;
+
+ @Autowired
+ private AssetRepository assetRepository;
+
+ @Autowired
+ private AssetSyncRepository assetSyncRepository;
+
+ @Autowired
+ private PlaylistSyncRepository playlistSyncRepository;
+
+ protected String getPlaylistSyncIds(String name) {
+ List<PlaylistSync> playlists = playlistSyncRepository.findAllByName(name);
+ assertEquals(1, playlists.size());
+ return StringUtils.join(playlists.get(0).getIds(), ",");
+ }
+
+ protected void cleanup() {
+ cleanupSync();
+ assetRepository.deleteAllInBatch();
+ }
+
+ protected void cleanupSync() {
+ playlistSyncRepository.deleteAllInBatch();
+ assetSyncRepository.deleteAllInBatch();
+ }
+
+ protected ImportSummary process(String xlsFile) {
+ ImportSummary summary = null;
+ try {
+ Path input = Paths.get(xlsFile);
+ summary = vodXlsProcessor.process(input.getFileName().toString(), Files.readAllBytes(input));
+ } catch (IOException e) {
+ log.error(e);
+ throw new RuntimeException(e);
+ }
+ return summary;
+ }
+
+ protected void checkSummary(ImportSummary summary, long expectedAll, long expectedInsert, long expectedUpdate, long expectedDelete) {
+ assertEquals(expectedAll, summary.getAll());
+ assertEquals(expectedAll, summary.getSuccess());
+ assertEquals(expectedInsert, summary.getInserted());
+ assertEquals(expectedUpdate, summary.getUpdated());
+ assertEquals(expectedDelete, summary.getDeleted());
+ }
+
+ protected void checkAsset(long expected, SyncType syncType, long expectedAllCount) {
+ assertEquals(expected, assetSyncRepository.countBySyncType(syncType));
+ assertEquals(expectedAllCount, assetSyncRepository.count());
+ }
+
+ protected void checkPlaylist(long expected, SyncType syncType, long expectedAllCount) {
+ assertEquals(expected, playlistSyncRepository.countBySyncType(syncType));
+ assertEquals(expectedAllCount, playlistSyncRepository.count());
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) $today.year-$today.month-24.
+ * By elGekko
+ */
+
+package hu.user.mcvodsync;
+
+import hu.user.mcvodsync.db.SyncType;
+import hu.user.mcvodsync.service.in.ImportSummary;
+import lombok.extern.log4j.Log4j2;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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;
+
+import javax.annotation.PostConstruct;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+
+@Log4j2
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@ActiveProfiles("dev")
+@TestPropertySource("classpath:application-dev.yaml")
+public class AssetImportExportIT extends AssetImportExportBase {
+
+ @BeforeClass
+ public static void beforeClass() {
+ }
+
+ @AfterClass
+ public static void afterClass() {
+ }
+
+ @PostConstruct
+ public void init() {
+ }
+
+ @Test
+ public void initialLoadTest() throws IOException {
+// Path xlsFile = Paths.get("src/test/resources/testdata-big.xlsx");
+ log.info("initialLoadTest");
+ cleanup();
+ ImportSummary summary = process("src/test/resources/testdata.xlsx");
+ checkSummary(summary, 9, 9, 0, 0);
+ checkAsset(9, SyncType.INSERT, 9);
+ checkPlaylist(3, SyncType.INSERT, 3);
+ assertEquals("CCEM110180,CCEM110183,CCEM110068", getPlaylistSyncIds("Playlist1"));
+ assertEquals("CCEM128963,CCEM128965,CCEM128967", getPlaylistSyncIds("Playlist2"));
+ assertEquals("CCEF008678,CCEM001148,CCEM072086", getPlaylistSyncIds("Playlist3"));
+ }
+
+ @Test
+ public void changeVideoTest() throws IOException {
+ log.info("changeVideoTest");
+ ImportSummary summary = process("src/test/resources/testdata.xlsx");
+ cleanupSync();
+ summary = process("src/test/resources/testdata-change-video.xlsx");
+ checkSummary(summary, 9, 0, 1, 0);
+ checkAsset(1, SyncType.UPDATE, 1);
+ checkPlaylist(0, null, 0);
+ }
+
+ @Test
+ public void deleteVideoTest() {
+ log.info("deleteVideoTest");
+ ImportSummary summary = process("src/test/resources/testdata.xlsx");
+ cleanupSync();
+ summary = process("src/test/resources/testdata-delete-video.xlsx");
+ checkSummary(summary, 9, 0, 1, 1);
+ checkAsset(1, SyncType.UPDATE, 2);
+ checkAsset(1, SyncType.DELETE, 2);
+ checkPlaylist(1, SyncType.UPDATE, 1);
+ assertEquals("CCEM110180,CCEM110183", getPlaylistSyncIds("Playlist1"));
+ }
+
+ @Test
+ public void changePlaylistOrderTest() {
+ log.info("changePlaylistOrderTest");
+ ImportSummary summary = process("src/test/resources/testdata.xlsx");
+ cleanupSync();
+ summary = process("src/test/resources/testdata-change-playlist-order.xlsx");
+ checkSummary(summary, 8, 0, 1, 0);
+ checkAsset(1, SyncType.UPDATE, 1);
+ checkPlaylist(1, SyncType.UPDATE, 1);
+ assertEquals("CCEM001148,CCEM072086,CCEF008678", getPlaylistSyncIds("Playlist3"));
+ }
+
+
+}
import com.brightcove.cms.client.model.Video;
import hu.user.mcvodsync.db.Asset;
-import hu.user.mcvodsync.service.export.VideoMapper;
+import hu.user.mcvodsync.service.out.VideoMapper;
import lombok.extern.log4j.Log4j2;
import org.junit.Test;
import org.junit.runner.RunWith;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
+import org.springframework.http.HttpStatus;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import java.util.stream.Collectors;
+import static org.junit.Assert.assertNotNull;
+
@Log4j2
@RunWith(SpringRunner.class)
@ComponentScan("hu.user.mcvodsync")
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);
+ Playlist playlist = new Playlist();
+ playlist.setName("Playlist 0000" + i);
+ playlist.setVideoIds(ids);
+ playlist.setDescription("mc-vod-sync");
+ Playlist playList = bcClient.createPlaylist(playlist);
logPlaylist(playList);
}
}
}
+ @Test
+ public void testDeleteTestPlayLists() {
+ try {
+ PagedSearch<Playlist> page = PagedSearch.<Playlist>builder()
+ .query("description:mc-vod-sync")
+ .sort("name")
+ .build();
+ while (bcClient.getPlaylistsPaged(page)) {
+ page.getData().forEach(this::deletePlayList);
+ }
+
+ } catch (Exception e) {
+ log.error(e);
+ }
+ }
+
+ private void deletePlayList(Playlist playlist) {
+ try {
+ logPlaylist(playlist);
+ bcClient.deletePlaylist(playlist.getId());
+ } catch (Exception e) {
+ log.error(e);
+ }
+ }
+
@Test
public void updatePlayLists() {
try {
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);
+ 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);
Playlist playList = bcClient.updatePlaylist(playlist);
@Test
public void testCreateVideo() {
try {
- CreateVideoRequestBodyFields fields = new CreateVideoRequestBodyFields();
- fields.setName("TEST video 00001");
- 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);
- logVideo(video);
-
+ Video video = new Video();
+ video.setName("TEST video 00001");
+ video.setReferenceId("MCVODSYNC10001");
+ video.setTags(Collections.singletonList("mc-vod-sync"));
+ video.setCustomFields(ImmutableMap.of("Notes", "notes"));
+ Video createdVideo = bcClient.createVideo(video);
+ logVideo(createdVideo);
log.info("Search result");
List<Video> videos = bcClient.getVideos(0, 10, "tags:mc-vod-sync");
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);
+ Video video = new Video();
+ video.setName("TEST video 0000" + i);
+ video.setReferenceId("MCVODSYNC0000" + i);
+ video.setTags(Collections.singletonList("mc-vod-sync"));
+ Video createdVideo = bcClient.createVideo(video);
+ logVideo(createdVideo);
i--;
}
} catch (Exception e) {
logVideo(video);
} catch (HttpClientErrorException e) {
+ if (HttpStatus.NOT_FOUND.equals(e.getStatusCode())) {
+
+ }
log.warn(e);
} catch (HttpServerErrorException e) {
log.error("Server error", e);
--- /dev/null
+/*
+ * Copyright (c) $today.year-$today.month-24.
+ * By elGekko
+ */
+
+package hu.user.mcvodsync;
+
+import hu.user.mcvodsync.service.schedule.ScheduledSunriseChacker;
+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.scheduling.TaskScheduler;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.time.Instant;
+
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@ActiveProfiles("dev")
+@TestPropertySource("classpath:application-dev.yaml")
+//@EnableScheduling
+@Log4j2
+public class ExecutionLockIT {
+ @Autowired
+ private TaskScheduler taskScheduler;
+
+ @Autowired
+ private ScheduledSunriseChacker scheduledSunriseChacker;
+
+ @Test
+ public void testSemaphore() throws InterruptedException {
+ log.info("Test start");
+ Thread.sleep(1000);
+
+ taskScheduler.schedule(scheduledSunriseChacker, Instant.now());
+ Thread.sleep(5000);
+ log.info("Test finish");
+ }
+
+}
\ No newline at end of file
package hu.user.mcvodsync;
import hu.user.mcvodsync.db.AssetSync;
+import hu.user.mcvodsync.db.PlaylistSync;
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;
-import hu.user.mcvodsync.service.xls.ImportSummary;
+import hu.user.mcvodsync.db.repository.PlaylistSyncRepository;
+import hu.user.mcvodsync.service.in.AssetImportService;
+import hu.user.mcvodsync.service.in.ImportSummary;
import lombok.extern.log4j.Log4j2;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.*;
@Autowired
private AssetSyncRepository assetSyncRepository;
+ @Autowired
+ private PlaylistSyncRepository playlistSyncRepository;
+
@Autowired
private AssetImportService assetImportService;
}
+ @Test
+ public void savePlaylistSync() {
+ PlaylistSync sync = PlaylistSync.builder()
+ .name("Playlist1")
+ .syncType(SyncType.INSERT)
+ .ids(Arrays.asList("AAA", "BBB", "CCC"))
+ .build();
+ playlistSyncRepository.saveAndFlush(sync);
+ playlistSyncRepository.deleteById(sync.getId());
+ }
+
@Test
public void queryForExport() {
List<AssetSync> assetSyncs = new ArrayList<>();
-
for (int i = 0; i < 3; i++) {
assetSyncs.add(AssetSync.builder()
.syncType(SyncType.INSERT)
+++ /dev/null
-/*
- * Copyright (c) $today.year-$today.month-24.
- * By elGekko
- */
-
-package hu.user.mcvodsync;
-
-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.xls.AssetImportService;
-import hu.user.mcvodsync.service.xls.ImportSummary;
-import hu.user.mcvodsync.service.xls.VodXlsProcessor;
-import lombok.extern.log4j.Log4j2;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-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.test.context.ActiveProfiles;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import javax.annotation.PostConstruct;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import static org.junit.Assert.assertEquals;
-
-
-@Log4j2
-@RunWith(SpringRunner.class)
-@SpringBootTest
-@ActiveProfiles("dev")
-@TestPropertySource("classpath:application-dev.yaml")
-public class VodXlsProcessorIT {
-
- @Autowired
- private VodXlsProcessor vodXlsProcessor;
-
- @Autowired
- private AssetImportService assetImportService;
-
- @Autowired
- private AssetRepository assetRepository;
-
- @Autowired
- private AssetSyncRepository assetSyncRepository;
-
- @Autowired
- private PlaylistSyncRepository playlistSyncRepository;
-
- @BeforeClass
- public static void beforeClass() {
- }
-
- @AfterClass
- public static void afterClass() {
- }
-
- @PostConstruct
- public void init() {
- }
-
- @Test
- public void initialLoadTest() throws IOException {
-// Path xlsFile = Paths.get("src/test/resources/testdata-big.xlsx");
- log.info("initialLoadTest");
- cleanup();
- ImportSummary summary = process("src/test/resources/testdata.xlsx");
- checkSummary(summary, 9, 9, 0, 0);
- checkAsset(9, SyncType.INSERT, 9);
- checkPlaylist(3, SyncType.INSERT, 3);
- }
-
- @Test
- public void changeVideoTest() throws IOException {
- log.info("changeVideoTest");
- ImportSummary summary = process("src/test/resources/testdata.xlsx");
- cleanupSync();
- summary = process("src/test/resources/testdata-change-video.xlsx");
- checkSummary(summary, 9, 0, 1, 0);
- checkAsset(1, SyncType.UPDATE, 1);
- }
-
- @Test
- public void deleteVideoTest() {
- log.info("deleteVideoTest");
- ImportSummary summary = process("src/test/resources/testdata.xlsx");
- cleanupSync();
- summary = process("src/test/resources/testdata-delete-video.xlsx");
- checkSummary(summary, 9, 0, 1, 1);
- checkAsset(1, SyncType.UPDATE, 2);
- checkAsset(1, SyncType.DELETE, 2);
- checkPlaylist(1, SyncType.UPDATE, 1);
- }
-
- @Test
- public void changePlaylistOrderTest() {
- log.info("changePlaylistOrderTest");
- ImportSummary summary = process("src/test/resources/testdata.xlsx");
- cleanupSync();
- summary = process("src/test/resources/testdata-change-playlist-order.xlsx");
- checkSummary(summary, 8, 0, 1, 0);
- checkAsset(1, SyncType.UPDATE, 1);
- checkPlaylist(1, SyncType.UPDATE, 1);
- }
-
- @Test
- public void changePlaylistAddAssetTest() {
- log.info("changePlaylistAddAssetTest");
-// "src/test/resources/testdata-playlist-add-asset.xlsx"
- }
-
- @Test
- public void changePlaylistRemoveAssetTest() {
- log.info("changePlaylistRemoveAssetTest");
-// "src/test/resources/testdata-playlist-remove-asset.xlsx"
- }
-
- public void cleanup() {
- cleanupSync();
- assetRepository.deleteAllInBatch();
- }
-
- public void cleanupSync() {
- playlistSyncRepository.deleteAllInBatch();
- assetSyncRepository.deleteAllInBatch();
- }
-
- private ImportSummary process(String xlsFile) {
- ImportSummary summary = null;
- try {
- Path input = Paths.get(xlsFile);
- summary = vodXlsProcessor.process(input.getFileName().toString(), Files.readAllBytes(input));
- } catch (IOException e) {
- log.error(e);
- throw new RuntimeException(e);
- }
- return summary;
- }
-
- private void checkSummary(ImportSummary summary, long expectedAll, long expectedInsert, long expectedUpdate, long expectedDelete) {
- assertEquals(expectedAll, summary.getAll());
- assertEquals(expectedAll, summary.getSuccess());
- assertEquals(expectedInsert, summary.getInserted());
- assertEquals(expectedUpdate, summary.getUpdated());
- assertEquals(expectedDelete, summary.getDeleted());
- }
-
- private void checkAsset(long expected, SyncType syncType, long expectedAllCount) {
- assertEquals(expected, assetSyncRepository.countBySyncType(syncType));
- assertEquals(expectedAllCount, assetSyncRepository.count());
- }
-
- private void checkPlaylist(long expected, SyncType syncType, long expectedAllCount) {
- assertEquals(expected, playlistSyncRepository.countBySyncType(syncType));
- assertEquals(expectedAllCount, playlistSyncRepository.count());
- }
-
-
-}
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClientException;
import java.util.HashMap;
videosApi.setApiClient(apiClient);
}
- public String createToken() {
+ private String createToken() {
String token = null;
try {
OAuthClient client = new OAuthClient(new URLConnectionClient());
return playListApi.updatePlaylist(apiProperties.getAccountId(), playlist.getId(), MediaType.APPLICATION_JSON_VALUE, getToken(), fields);
}
- public Playlist createPlaylist(PlaylistInputFields fields) {
+ public Playlist createPlaylist(Playlist playlist) {
+ PlaylistInputFields fields = new PlaylistInputFields();
+ fields.setType(PlaylistInputFields.TypeEnum.EXPLICIT);
+ fields.setName(playlist.getName());
+ fields.setVideoIds(playlist.getVideoIds());
+ fields.setDescription(playlist.getDescription());
return playListApi.createPlaylist(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE, getToken(), fields);
}
public Video getVideoByReferenceId(String referenceId) throws RestClientException {
- return videosApi.getVideoByIdOrReferenceId(apiProperties.getAccountId(), "/ref:" + referenceId, MediaType.APPLICATION_JSON_VALUE,
- getToken(), true);
+ Video result = null;
+ try {
+ result = videosApi.getVideoByIdOrReferenceId(apiProperties.getAccountId(), "/ref:" + referenceId, MediaType.APPLICATION_JSON_VALUE,
+ getToken(), true);
+
+ } catch (HttpClientErrorException e) {
+ if (!HttpStatus.NOT_FOUND.equals(e.getStatusCode())) {
+ throw e;
+ }
+ } catch (HttpServerErrorException e) {
+ throw e;
+ } catch (Exception e) {
+ throw e;
+ }
+ return result;
}
public Video getVideoById(String id) throws RestClientException {
getToken(), true).getBody();
}
-
- public Video createVideo(CreateVideoRequestBodyFields fields) {
- 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);
+ fields.setState(CreateVideoRequestBodyFields.StateEnum.INACTIVE);
+ fields.setEconomics(CreateVideoRequestBodyFields.EconomicsEnum.FREE);
+ return videosApi.createVideo(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE, getToken(), fields);
}
public Video updateVideo(String videoId, Video video) {
return videosApi.getApiClient().invokeAPI("/v1/accounts/{account_id}/videos{video_ids}", HttpMethod.GET, uriVariables, queryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, authNames, returnType);
}
+ public void deletePlaylist(String id) {
+ playListApi.deletePlaylists(apiProperties.getAccountId(), "/" + id, MediaType.APPLICATION_JSON_VALUE, getToken());
+ }
}
CREATE TABLE playlist_sync (
id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
- playlist VARCHAR(100) NOT NULL,
+ name VARCHAR(100) NOT NULL,
created TIMESTAMP NOT NULL,
sync_type VARCHAR(6) NOT NULL,
exported_success TIMESTAMP,
exported_error TIMESTAMP,
+ ids BLOB,
CONSTRAINT pk_playlist_sync PRIMARY KEY (id)
);
CREATE INDEX idx_playlist_sync_exported_success ON asset_sync(exported_success);
package hu.user.mcvodsync.db;
+import hu.user.mcvodsync.db.converter.StringListConverter;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
+import java.util.List;
@Getter
@Setter
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
- private String playlist;
+ private String name;
@CreationTimestamp
@Column(updatable = false)
private Date exportedSuccess;
private Date exportedError;
+
+ @Convert(converter = StringListConverter.class)
+ private List<String> ids;
}
--- /dev/null
+package hu.user.mcvodsync.db.converter;
+
+import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+@Converter
+public class StringListConverter implements AttributeConverter<List<String>, byte[]> {
+ private static final String SPLIT_CHAR = ",";
+
+ @Override
+ public byte[] convertToDatabaseColumn(List<String> dataList) {
+ return Objects.isNull(dataList) ? null : String.join(SPLIT_CHAR, dataList).getBytes();
+ }
+
+ @Override
+ public List<String> convertToEntityAttribute(byte[] data) {
+ String stringData = new String(data);
+ return Arrays.asList(stringData.split(SPLIT_CHAR));
+ }
+}
\ No newline at end of file
package hu.user.mcvodsync.db.repository;
import hu.user.mcvodsync.db.AssetSync;
+import hu.user.mcvodsync.db.PlaylistSync;
import hu.user.mcvodsync.db.SyncType;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
List<AssetSync> findFirst100ByExportedSuccessIsNullOrderByCreated();
+ List<PlaylistSync> findAllByOrderByCreated();
}
import hu.user.mcvodsync.db.SyncType;
import org.springframework.data.jpa.repository.JpaRepository;
-public interface PlaylistSyncRepository extends JpaRepository<PlaylistSync, String> {
+import java.util.List;
+
+public interface PlaylistSyncRepository extends JpaRepository<PlaylistSync, Long> {
long countBySyncType(SyncType syncType);
+ List<PlaylistSync> findAllByName(String name);
}
--- /dev/null
+package hu.user.mcvodsync.service.config;
+
+import hu.user.mcvodsync.service.schedule.ScheduledExport;
+import hu.user.mcvodsync.service.schedule.ScheduledImport;
+import hu.user.mcvodsync.service.schedule.ScheduledSunriseChacker;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.TaskScheduler;
+import org.springframework.scheduling.support.PeriodicTrigger;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class ScheduledTasks {
+ @Autowired
+ private TaskScheduler taskScheduler;
+
+ @Autowired
+ private ScheduledExport scheduledExport;
+
+ @Autowired
+ private ScheduledImport scheduledImport;
+
+ @Autowired
+ private ScheduledSunriseChacker scheduledSunriseChacker;
+
+ @PostConstruct
+ public void scheduleTasks() {
+ //new CronTrigger("0 0 4 1/1 * ? *")
+// https://www.baeldung.com/spring-task-scheduler
+ taskScheduler.schedule(scheduledExport, new PeriodicTrigger(1, TimeUnit.SECONDS));
+ taskScheduler.schedule(scheduledImport, new PeriodicTrigger(1, TimeUnit.SECONDS));
+ //taskScheduler.schedule(scheduledSunriseChacker, new PeriodicTrigger(1, TimeUnit.SECONDS));
+ }
+
+
+}
--- /dev/null
+package hu.user.mcvodsync.service.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.TaskScheduler;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+
+@Configuration
+public class TaskSchedulerConfig {
+
+ @Bean
+ public TaskScheduler taskScheduler() {
+ ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
+ threadPoolTaskScheduler.setPoolSize(1);
+ threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
+ return threadPoolTaskScheduler;
+ }
+}
\ No newline at end of file
-package hu.user.mcvodsync.service.xls;
+package hu.user.mcvodsync.service.in;
import hu.user.mcvodsync.db.Asset;
private Map<String, List<String>> currentPlaylists;
- private hu.user.mcvodsync.service.xls.ImportSummary summary;
+ private ImportSummary summary;
- public void prepare(hu.user.mcvodsync.service.xls.ImportSummary summary) {
+ public void prepare(ImportSummary summary) {
this.summary = summary;
currentPlaylists = getPlayLists();
}
}
if (Objects.nonNull(assetSync.getSyncType())) {
- assetRepository.save(asset);
- assetSyncRepository.save(assetSync);
+ assetRepository.saveAndFlush(asset);
+ assetSyncRepository.saveAndFlush(assetSync);
}
if (assetSync.getSyncType() == SyncType.UPDATE) {
public void removeExpired(LocalDate currentDate) {
List<String> ids = assetRepository.queryExpired(java.sql.Date.valueOf(currentDate));
+ assetRepository.deleteExpired(java.sql.Date.valueOf(currentDate));
List<AssetSync> syncs = ids.stream().map(id -> AssetSync.builder()
.catalogId(id)
.syncType(SyncType.DELETE)
.build()).collect(Collectors.toList());
- assetSyncRepository.saveAll(syncs);
- assetRepository.deleteExpired(java.sql.Date.valueOf(currentDate));
+ assetSyncRepository.saveAllAndFlush(syncs);
summary.setDeleted(summary.getDeleted() + ids.size());
}
Collection<String> playlistNamesDifference = CollectionUtils.subtract(currentPlaylistNames, newPlaylistNames);
if (!playlistNamesDifference.isEmpty()) {
- playlistNamesDifference.forEach(playlist -> {
+ playlistNamesDifference.forEach(name -> {
PlaylistSync sync = PlaylistSync.builder()
- .playlist(playlist)
+ .name(name)
.syncType(SyncType.DELETE)
.created(Date.from(Instant.now()))
.build();
playlistNamesDifference = CollectionUtils.subtract(newPlaylistNames, currentPlaylistNames);
if (!playlistNamesDifference.isEmpty()) {
- playlistNamesDifference.forEach(playlist -> {
+ playlistNamesDifference.forEach(name -> {
PlaylistSync sync = PlaylistSync.builder()
- .playlist(playlist)
+ .name(name)
.syncType(SyncType.INSERT)
.created(Date.from(Instant.now()))
+ .ids(newPlaylists.get(name))
.build();
playlistSyncRepository.save(sync);
summary.incInsertedPlaylist();
});
}
- currentPlaylistNames.forEach(playlist -> {
- List<String> currentContent = currentPlaylists.get(playlist);
- List<String> newContent = newPlaylists.get(playlist);
+ currentPlaylistNames.forEach(name -> {
+ List<String> currentContent = currentPlaylists.get(name);
+ List<String> newContent = newPlaylists.get(name);
if (isContentChanged(currentContent, newContent)) {
PlaylistSync sync = PlaylistSync.builder()
- .playlist(playlist)
+ .name(name)
.syncType(SyncType.UPDATE)
+ .ids(newPlaylists.get(name))
.created(Date.from(Instant.now()))
.build();
playlistSyncRepository.save(sync);
-package hu.user.mcvodsync.service.xls;
+package hu.user.mcvodsync.service.in;
import hu.user.mcvodsync.db.Asset;
import org.apache.commons.lang3.StringUtils;
-package hu.user.mcvodsync.service.xls;
+package hu.user.mcvodsync.service.in;
import lombok.Builder;
import lombok.Getter;
-package hu.user.mcvodsync.service.xls;
+package hu.user.mcvodsync.service.in;
import hu.user.mcvodsync.db.Asset;
import lombok.extern.log4j.Log4j2;
-package hu.user.mcvodsync.service.export;
+package hu.user.mcvodsync.service.out;
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.PlaylistSync;
import hu.user.mcvodsync.db.SyncType;
import hu.user.mcvodsync.db.repository.AssetRepository;
import hu.user.mcvodsync.db.repository.AssetSyncRepository;
private ServiceProperties serviceProperties;
public void export() {
+ exportAssets();
+ exportPlaylists();
+ }
+
+ private void exportAssets() {
while (true) {
List<AssetSync> result = assetSyncRepository.findFirst100ByExportedSuccessIsNullOrderByCreated();
if (result.isEmpty()) {
+ log.info("There are no video changes to export");
break;
}
result.forEach(this::processAssetSyncWithoutInsert);
}
}
-
}
@Transactional
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());
+ String videoId = asset.getReferenceId();
+ if (StringUtils.isBlank(videoId)) {
+ Video video = bcClient.getVideoByReferenceId(asset.getCatalogId());
+ videoId = video.getId();
+ asset.setReferenceId(videoId);
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);
- }
+ bcClient.updateVideo(videoId, assetVideo);
assetSync.setExportedSuccess(Date.from(Instant.now()));
}
} catch (Exception e) {
}
}
+ private void exportPlaylists() {
+ while (true) {
+ List<PlaylistSync> result = assetSyncRepository.findAllByOrderByCreated();
+ if (result.isEmpty()) {
+ log.info("There are no playlist changes to export");
+ break;
+ }
+
+ if (serviceProperties.isTargetPlaylistInsertEnabled()) {
+ result.forEach(this::processPlaylistSync);
+ } else {
+ result.forEach(this::processPlaylistSyncWithoutInsert);
+ }
+ }
+ }
+
+ @Transactional
+ public void processPlaylistSync(PlaylistSync playlistSync) {
+ try {
+ if (SyncType.DELETE.equals(playlistSync.getSyncType())) {
+ playlistSync.setExportedSuccess(Date.from(Instant.now()));
+ } else {
+
+// Playlist playlist = playlistRepository.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()));
+ }
+ }
+
+ @Transactional
+ public void processPlaylistSyncWithoutInsert(PlaylistSync playlistSync) {
+ }
}
-package hu.user.mcvodsync.service.export;
+package hu.user.mcvodsync.service.out;
import org.mapstruct.Named;
-package hu.user.mcvodsync.service.export;
+package hu.user.mcvodsync.service.out;
import com.brightcove.cms.client.model.Video;
import hu.user.mcvodsync.db.Asset;
--- /dev/null
+package hu.user.mcvodsync.service.schedule;
+
+import lombok.SneakyThrows;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.ThreadLocalRandom;
+
+@Log4j2
+@Component
+//@ConditionalOnExpression("'${mc-vod-sync.scheduler.export}'=='true'")
+public class ScheduledExport implements Runnable {
+ // @Scheduled(initialDelay = 2000, fixedDelay = 200)
+ @SneakyThrows
+ @Override
+ public void run() {
+ try {
+ log.info("Start 1");
+ log.info("Execute 1");
+ int randomNum = ThreadLocalRandom.current().nextInt(100, 2000);
+ Thread.sleep(randomNum);
+ log.info("Finish 1");
+
+ } catch (Exception e) {
+ log.error(e);
+ }
+
+ }
+
+}
--- /dev/null
+package hu.user.mcvodsync.service.schedule;
+
+import lombok.SneakyThrows;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.ThreadLocalRandom;
+
+@Log4j2
+@Component
+//@ConditionalOnExpression("'${mc-vod-sync.scheduler.import}'=='true'")
+public class ScheduledImport implements Runnable {
+ @SneakyThrows
+ @Override
+ public void run() {
+ try {
+ log.info("Start 2");
+ log.info("Execute 2");
+ int randomNum = ThreadLocalRandom.current().nextInt(100, 2000);
+ Thread.sleep(randomNum);
+ log.info("Finish 2");
+
+ } catch (Exception e) {
+ log.error(e);
+ }
+
+ }
+}
--- /dev/null
+package hu.user.mcvodsync.service.schedule;
+
+import lombok.SneakyThrows;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.ThreadLocalRandom;
+
+@Log4j2
+@Component
+//@ConditionalOnExpression("'${mc-vod-sync.scheduler.sunrise-checker}'=='true'")
+public class ScheduledSunriseChacker implements Runnable {
+
+ @SneakyThrows
+ @Override
+ public void run() {
+ try {
+ log.info("Start 3");
+ log.info("Execute 3");
+ int randomNum = ThreadLocalRandom.current().nextInt(100, 2000);
+ Thread.sleep(randomNum);
+ log.info("Finish 3");
+
+ } catch (Exception e) {
+ log.error(e);
+ }
+
+ }
+}
+++ /dev/null
-package hu.user.mcvodsync.service.schedule;
-
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Service;
-
-@Service
-public class TaskSchedules {
-
- @Scheduled(fixedDelay = 50000)
- public void scheduleFixedDelayTask() {
-// System.out.println(
-// "Fixed delay task - " + System.currentTimeMillis() / 1000);
- }
-}