Commit 00682b06 authored by Rustam Lotsmanenko (EPAM)'s avatar Rustam Lotsmanenko (EPAM) Committed by Riabokon Stanislav(EPAM)[GCP]
Browse files

GONRG-693 POC

Removed redundant dependencies
Added Main class
Changed maven plugin build & run config
parent 8b9e07c3
......@@ -4,6 +4,7 @@ target/
!**/src/main/**
!**/src/test/**
.DS_Store
### STS ###
.apt_generated
......@@ -32,7 +33,6 @@ build/
.vscode/
### Other ###
.mvn
target/*
*/target
/mvn
......
<!--
~ Copyright 2020 Google LLC
~ Copyright 2020 EPAM Systems, Inc
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<settings>
<profiles>
<profile>
<!-- This profile uses the CI-Token to authenticate with the server, and is the default case -->
<id>GitLab-Authenticate-With-Job-Token</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<repo.releases.id>community-maven-repo</repo.releases.id>
<publish.snapshots.id>community-maven-via-job-token</publish.snapshots.id>
<publish.releases.id>community-maven-via-job-token</publish.releases.id>
<repo.releases.url>https://community.opengroup.org/api/v4/groups/17/-/packages/maven</repo.releases.url>
<publish.snapshots.url>https://community.opengroup.org/api/v4/projects/118/packages/maven</publish.snapshots.url>
<publish.releases.url>https://community.opengroup.org/api/v4/projects/118/packages/maven</publish.releases.url>
</properties>
</profile>
<profile>
<!-- This profile uses a personal token to authenticate, which is useful for local or manual runs. The
presence of the COMMUNITY_MAVEN_TOKEN variable triggers this and overrides the CI Token
based authentication -->
<id>GitLab-Authenticate-With-Private-Token</id>
<activation>
<property>
<name>env.COMMUNITY_MAVEN_TOKEN</name>
</property>
</activation>
<properties>
<repo.releases.id>community-maven-repo</repo.releases.id>
<publish.snapshots.id>community-maven-via-private-token</publish.snapshots.id>
<publish.releases.id>community-maven-via-private-token</publish.releases.id>
<repo.releases.url>https://community.opengroup.org/api/v4/groups/17/-/packages/maven</repo.releases.url>
<publish.snapshots.url>https://community.opengroup.org/api/v4/projects/118/packages/maven</publish.snapshots.url>
<publish.releases.url>https://community.opengroup.org/api/v4/projects/118/packages/maven</publish.releases.url>
</properties>
</profile>
</profiles>
<servers>
<server>
<id>community-maven-via-job-token</id>
<configuration>
<httpHeaders>
<property>
<name>Job-Token</name>
<value>${env.CI_JOB_TOKEN}</value>
</property>
</httpHeaders>
</configuration>
</server>
<server>
<id>community-maven-via-private-token</id>
<configuration>
<httpHeaders>
<property>
<name>Private-Token</name>
<value>${env.COMMUNITY_MAVEN_TOKEN}</value>
</property>
</httpHeaders>
</configuration>
</server>
</servers>
</settings>
......@@ -2,44 +2,59 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>backup-service</artifactId>
<groupId>org.opengroup.osdu</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>backup-core</artifactId>
<description>Backup service Core on GCP</description>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.opengroup.osdu</groupId>
<artifactId>os-core-common</artifactId>
<version>0.3.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
</dependencies>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>backup-service</artifactId>
<groupId>org.opengroup.osdu</groupId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>backup-core</artifactId>
<description>Backup service Core on GCP</description>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.opengroup.osdu</groupId>
<artifactId>os-core-common</artifactId>
<version>0.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.7.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package org.opengroup.osdu.backup;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "org.opengroup")
public class BackupApplication {
public static void main(String[] args) {
SpringApplication.run(BackupApplication.class, args);
}
}
package org.opengroup.osdu.backup.api;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.opengroup.osdu.backup.model.SubmitRequest;
import org.opengroup.osdu.backup.model.BackupImportRequest;
import org.opengroup.osdu.backup.model.BackupsResponse;
import org.opengroup.osdu.backup.model.SubmitTaskRequest;
import org.opengroup.osdu.backup.provider.interfaces.BackupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
......@@ -14,16 +18,31 @@ import org.springframework.web.context.annotation.RequestScope;
@Slf4j
@RestController
@RequestScope
@RequiredArgsConstructor
public class BackupApi {
@Autowired
private BackupService backupService;
private final BackupService backupService;
@PostMapping("/submitScheduledTask")
public ResponseEntity<String> submitScheduledTask(@RequestBody SubmitTaskRequest submitTaskRequest) {
backupService.submitScheduledTask(submitTaskRequest);
return new ResponseEntity<String>("Task submitted", HttpStatus.OK);
}
@PostMapping("/submitTask/")
public ResponseEntity<String> submitTask(@RequestBody SubmitRequest submitRequest) {
backupService.submitTask(submitRequest);
return new ResponseEntity<String>("Backup service is alive", HttpStatus.OK);
}
@PostMapping("/submitImport")
public ResponseEntity<String> submitImport(@RequestBody BackupImportRequest backup) {
backupService.submitImportRequest(backup);
return new ResponseEntity<String>("Import request submitted", HttpStatus.OK);
}
@GetMapping("/listSchedules")
public ResponseEntity<List<SubmitTaskRequest>> listSchedules() {
return new ResponseEntity<List<SubmitTaskRequest>>(backupService.listSchedules(), HttpStatus.OK);
}
@GetMapping("/listBackups")
public ResponseEntity<BackupsResponse> listBackups() {
return new ResponseEntity<BackupsResponse>(backupService.listBackups(), HttpStatus.OK);
}
}
......@@ -11,15 +11,15 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/health")
public class HealthCheckApi {
@PermitAll
@GetMapping("/liveness_check")
public ResponseEntity<String> livenessCheck() {
return new ResponseEntity<String>("Backup service is alive", HttpStatus.OK);
}
@PermitAll
@GetMapping("/liveness_check")
public ResponseEntity<String> livenessCheck() {
return new ResponseEntity<String>("Backup service is alive", HttpStatus.OK);
}
@PermitAll
@GetMapping("/readiness_check")
public ResponseEntity<String> readinessCheck() {
return new ResponseEntity<String>("Backup service is ready", HttpStatus.OK);
}
@PermitAll
@GetMapping("/readiness_check")
public ResponseEntity<String> readinessCheck() {
return new ResponseEntity<String>("Backup service is ready", HttpStatus.OK);
}
}
package org.opengroup.osdu.backup.model;
public enum AssetType {
}
package org.opengroup.osdu.backup.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class SubmitRequest {
@JsonProperty("AssetType")
String dataType;
@AllArgsConstructor
@Builder
public class BackupImportRequest {
@JsonProperty("Context")
Map<String, Object> context;
private String backupPath;
}
package org.opengroup.osdu.backup.model;
import java.util.HashMap;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BackupsResponse {
HashMap<String, HashMap<String, List<String>>> backupsMap;
}
package org.opengroup.osdu.backup.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(of = {"namespace", "kind"})
public class SubmitTaskRequest {
private String assetType;
private String namespace;
private String kind;
private String backupPath;
private int backupPeriod;
private boolean active;
}
package org.opengroup.osdu.backup.provider.interfaces;
import java.util.List;
import org.opengroup.osdu.backup.model.BackupImportRequest;
import org.opengroup.osdu.backup.model.BackupsResponse;
import org.opengroup.osdu.backup.model.SubmitTaskRequest;
public interface BackupRepository {
void get(String namespace, String kind);
void exportBackup(SubmitTaskRequest submitTaskRequest);
void importBackup(BackupImportRequest backup);
List<SubmitTaskRequest> listBackupSchedules();
BackupsResponse listAvailableBackups();
}
package org.opengroup.osdu.backup.provider.interfaces;
import org.opengroup.osdu.backup.model.SubmitRequest;
import java.util.List;
import org.opengroup.osdu.backup.model.BackupImportRequest;
import org.opengroup.osdu.backup.model.BackupsResponse;
import org.opengroup.osdu.backup.model.SubmitTaskRequest;
public interface BackupService {
void submitTask(SubmitRequest submitRequest);
void submitScheduledTask(SubmitTaskRequest submitTaskRequest);
void submitImportRequest(BackupImportRequest backup);
List<SubmitTaskRequest> listSchedules();
BackupsResponse listBackups();
}
package org.opengroup.osdu.backup.shedulers;
import lombok.RequiredArgsConstructor;
import org.opengroup.osdu.backup.model.SubmitTaskRequest;
import org.opengroup.osdu.backup.provider.interfaces.BackupRepository;
@RequiredArgsConstructor
public class BackupScheduledTask implements Runnable {
private final BackupRepository backupRepository;
private final SubmitTaskRequest submitTaskRequest;
@Override
public void run() {
backupRepository.exportBackup(submitTaskRequest);
}
}
package org.opengroup.osdu.backup.shedulers;
import org.opengroup.osdu.backup.model.SubmitTaskRequest;
public interface SchedulerService {
void addTaskToScheduler(SubmitTaskRequest submitTaskRequest);
boolean cancelScheduledTask(SubmitTaskRequest submitTaskRequest);
void taskStatusChanged(SubmitTaskRequest submitTaskRequest);
}
package org.opengroup.osdu.backup.shedulers.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.opengroup.osdu.backup.model.SubmitTaskRequest;
import org.opengroup.osdu.backup.provider.interfaces.BackupRepository;
import org.opengroup.osdu.backup.shedulers.BackupScheduledTask;
import org.opengroup.osdu.backup.shedulers.SchedulerService;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class SchedulerServiceImpl implements SchedulerService {
private final Map<SubmitTaskRequest, ScheduledFuture> taskMap = new HashMap<>();
private final TimeUnit timeUnit = TimeUnit.MINUTES;
private final BackupRepository backupRepository;
private ThreadPoolTaskScheduler poolTaskScheduler;
@PostConstruct
public void initThreadPool() {
poolTaskScheduler = new ThreadPoolTaskScheduler();
poolTaskScheduler.setPoolSize(5);
poolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
poolTaskScheduler.setRemoveOnCancelPolicy(true);
poolTaskScheduler.initialize();
}
@Override
public void addTaskToScheduler(SubmitTaskRequest submitTaskRequest) {
PeriodicTrigger periodicTrigger
= new PeriodicTrigger(submitTaskRequest.getBackupPeriod(), timeUnit);
periodicTrigger.setFixedRate(true);
BackupScheduledTask backupScheduledTask = new BackupScheduledTask(backupRepository, submitTaskRequest);
ScheduledFuture<?> schedule = poolTaskScheduler.schedule(backupScheduledTask, periodicTrigger);
taskMap.put(submitTaskRequest, schedule);
}
@Override
public boolean cancelScheduledTask(SubmitTaskRequest submitTaskRequest) {
return taskMap.get(submitTaskRequest).cancel(false);
}
@Override
public void taskStatusChanged(SubmitTaskRequest submitTaskRequest) {
if (!submitTaskRequest.isActive()) {
taskMap.get(submitTaskRequest).cancel(false);
} else {
addTaskToScheduler(submitTaskRequest);
}
}
}
package org.opengroup.osdu.backup.shedulers.impl;
import static java.lang.Thread.sleep;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import java.util.concurrent.TimeUnit;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.opengroup.osdu.backup.model.SubmitTaskRequest;
import org.opengroup.osdu.backup.provider.interfaces.BackupRepository;
import org.springframework.test.util.ReflectionTestUtils;
@RunWith(MockitoJUnitRunner.class)
public class SchedulerServiceImplTest {
@Mock
private BackupRepository backupRepository;
@InjectMocks
private SchedulerServiceImpl schedulerService;
private SubmitTaskRequest submitTaskRequest;
private SubmitTaskRequest submitTaskRequest1;
private SubmitTaskRequest submitTaskRequest2;
@Before
public void setUp() throws Exception {
submitTaskRequest = SubmitTaskRequest.builder().namespace("test").kind("kind").backupPeriod(2).active(true)
.build();
submitTaskRequest1 = SubmitTaskRequest.builder().namespace("test1").kind("kind1").backupPeriod(2).active(true)
.build();
submitTaskRequest2 = SubmitTaskRequest.builder().namespace("test2").kind("kind2").backupPeriod(2).active(true)
.build();
ReflectionTestUtils.setField(schedulerService, "timeUnit", TimeUnit.SECONDS);
schedulerService.initThreadPool();
}
@Test
public void addTaskToScheduler() throws InterruptedException {
schedulerService.addTaskToScheduler(submitTaskRequest);
schedulerService.addTaskToScheduler(submitTaskRequest1);
schedulerService.addTaskToScheduler(submitTaskRequest2);
sleep(1000);
verify(backupRepository, times(3)).exportBackup(any());
schedulerService.cancelScheduledTask(submitTaskRequest);
schedulerService.cancelScheduledTask(submitTaskRequest1);
schedulerService.cancelScheduledTask(submitTaskRequest2);
verifyNoMoreInteractions(backupRepository);
}
@Test
public void removeTaskFromScheduler() throws InterruptedException {
schedulerService.addTaskToScheduler(submitTaskRequest);
sleep(1000);
verify(backupRepository, times(1)).exportBackup(any());