Commit 0abad538 authored by Rustam Lotsmanenko (EPAM)'s avatar Rustam Lotsmanenko (EPAM)
Browse files

GONRG-1638 Remove obsolete logic from BackupService, extend api to work with collections

parent 0105fe08
......@@ -35,6 +35,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
......
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.backup.api;
import java.util.EnumMap;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.opengroup.osdu.backup.locator.Asset;
import org.opengroup.osdu.backup.model.BackupImportRequest;
import org.opengroup.osdu.backup.model.BackupRole;
import org.opengroup.osdu.backup.model.BackupSchedule;
import org.opengroup.osdu.backup.model.BackupStamp;
import org.opengroup.osdu.backup.service.BackupService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.annotation.RequestScope;
@Slf4j
@RestController
@RequestScope
@RequiredArgsConstructor
@PreAuthorize("@authorizationFilter.hasPermission('" + BackupRole.BACKUP + "')")
public class BackupApi {
private final BackupService backupService;
@PostMapping("/schedule")
public ResponseEntity<BackupSchedule> submitBackupSchedule(
@RequestBody BackupSchedule backupSchedule) {
BackupSchedule savedBackupSchedule = backupService.submitBackupSchedule(backupSchedule);
return new ResponseEntity<>(savedBackupSchedule, HttpStatus.CREATED);
}
@PutMapping("/schedule")
public ResponseEntity<BackupSchedule> updateBackupSchedule(
@RequestBody BackupSchedule backupSchedule) {
BackupSchedule savedBackupSchedule = backupService.updateBackupSchedule(backupSchedule);
return new ResponseEntity<>(savedBackupSchedule, HttpStatus.ACCEPTED);
}
@GetMapping("/schedule")
public ResponseEntity<BackupSchedule> getScheduleById(@RequestParam String id) {
return new ResponseEntity<>(backupService.getBackupSchedule(id), HttpStatus.OK);
}
@PostMapping("/backup_import")
public ResponseEntity<BackupStamp> submitImport(@RequestBody BackupImportRequest backupId) {
BackupStamp stamp = backupService.submitBackupImportRequest(backupId);
return new ResponseEntity<>(stamp, HttpStatus.OK);
}
@GetMapping("/list_schedules")
public ResponseEntity<List<BackupSchedule>> listSchedules() {
return new ResponseEntity<>(backupService.listSchedules(), HttpStatus.OK);
}
@GetMapping("/list_backups")
public ResponseEntity<EnumMap<Asset, List<BackupStamp>>> listBackups() {
return new ResponseEntity<>(backupService.listBackups(), HttpStatus.OK);
}
}
......@@ -24,46 +24,76 @@ import org.opengroup.osdu.backup.model.BackupCollection;
import org.opengroup.osdu.backup.model.BackupRole;
import org.opengroup.osdu.backup.model.CollectionState;
import org.opengroup.osdu.backup.service.BackupCollectionService;
import org.opengroup.osdu.backup.validation.CreateCollection;
import org.opengroup.osdu.backup.validation.UpdateCollection;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.annotation.RequestScope;
@Slf4j
@RestController
@RequestMapping(value = "/collection")
@RequestScope
@RequiredArgsConstructor
@PreAuthorize("@authorizationFilter.hasPermission('" + BackupRole.BACKUP + "')")
@Validated
public class BackupCollectionApi {
private final BackupCollectionService collectionService;
@PostMapping("/collection")
public ResponseEntity<BackupCollection> createCollection(@RequestBody BackupCollection collection) {
@PostMapping
public ResponseEntity<BackupCollection> createCollection(
@Validated(CreateCollection.class) @RequestBody BackupCollection collection) {
BackupCollection backupCollection = collectionService.saveCollection(collection);
return new ResponseEntity<>(backupCollection, HttpStatus.CREATED);
}
@PutMapping("/collection/{name}")
public ResponseEntity<BackupCollection> updateCollection(@PathVariable String name,
@RequestBody BackupCollection collection) {
BackupCollection backupCollection = collectionService.update(collection);
@PutMapping("/{collectionName}")
public ResponseEntity<BackupCollection> updateCollection(
@PathVariable String collectionName,
@Validated(UpdateCollection.class) @RequestBody BackupCollection collection) {
BackupCollection backupCollection = collectionService.update(collection, collectionName);
return new ResponseEntity<>(backupCollection, HttpStatus.CREATED);
}
@GetMapping("/collection/{name}")
public ResponseEntity<List<CollectionState>> getCollectionStates(@PathVariable String name) {
List<CollectionState> collectionStates = collectionService.getCollectionStates(name);
@GetMapping("/{collectionName}")
public ResponseEntity<BackupCollection> getCollectionConfig(@PathVariable String collectionName) {
BackupCollection collection = collectionService.getCollectionConfiguration(collectionName);
return new ResponseEntity<>(collection, HttpStatus.OK);
}
@DeleteMapping("/{collectionName}")
public ResponseEntity deleteCollection(@PathVariable String collectionName) {
collectionService.deleteCollectionConfiguration(collectionName);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@GetMapping("/list")
public ResponseEntity<List<BackupCollection>> listCollections() {
List<BackupCollection> collectionList = collectionService.listCollectionsConfigurations();
return new ResponseEntity<>(collectionList, HttpStatus.OK);
}
@GetMapping("/states/{collectionName}")
public ResponseEntity<List<CollectionState>> getCollectionStates(@PathVariable String collectionName,
@RequestParam(required = false) String success) {
List<CollectionState> collectionStates = collectionService.getCollectionStates(collectionName);
return new ResponseEntity<>(collectionStates, HttpStatus.OK);
}
@GetMapping("/collection/restore/{stateId}")
@PatchMapping("/restore/{stateId}")
public ResponseEntity<CollectionState> restoreCollection(@PathVariable String stateId) {
CollectionState collectionState = collectionService.restoreCollection(stateId);
return new ResponseEntity<>(collectionState, HttpStatus.OK);
......
......@@ -18,29 +18,54 @@
package org.opengroup.osdu.backup.model;
import java.util.Set;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.constraints.Positive;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.opengroup.osdu.backup.validation.CreateCollection;
import org.opengroup.osdu.backup.validation.UpdateCollection;
@Data
@EqualsAndHashCode(of = "collectionId")
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class BackupCollection {
@Null(groups = {CreateCollection.class, UpdateCollection.class})
private String collectionId;
@NotBlank(groups = CreateCollection.class)
private String collectionName;
private boolean active;
@Getter(AccessLevel.NONE)
@NotNull(groups = CreateCollection.class)
private Boolean active;
private int backupPeriod;
@NotNull(groups = CreateCollection.class)
@Positive(groups = {CreateCollection.class, UpdateCollection.class})
private Integer backupPeriod;
private int lifetime;
@NotNull(groups = CreateCollection.class)
@Positive(groups = {CreateCollection.class, UpdateCollection.class})
private Integer lifetime;
@NotEmpty(groups = CreateCollection.class)
@Null(groups = UpdateCollection.class)
private Set<BackupSchedule> scheduleSet;
public Boolean isActive() {
return active;
}
}
/*
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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.opengroup.osdu.backup.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.opengroup.osdu.backup.locator.Asset;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class BackupImportRequest {
private String backupStampId;
private Asset asset;
}
......@@ -24,7 +24,11 @@ public interface BackupCollectionRepository {
BackupCollection submitCollection(BackupCollection collection);
BackupCollection updateCollection(BackupCollection collection);
BackupCollection updateCollection(BackupCollection collection, String collectionName);
List<BackupCollection> listBackupCollections();
BackupCollection getCollectionByName(String collectionName);
BackupCollection deleteCollectionByName(String collectionName);
}
/*
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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.opengroup.osdu.backup.repository;
import java.util.List;
import java.util.Map;
import org.opengroup.osdu.backup.locator.Asset;
import org.opengroup.osdu.backup.model.BackupSchedule;
public interface ScheduleRepository {
List<BackupSchedule> listBackupSchedules();
BackupSchedule submitSchedule(BackupSchedule backupSchedule);
BackupSchedule updateSchedule(BackupSchedule backupSchedule);
BackupSchedule findByAssetContext(Asset asset, Map<String, String> assetContext);
BackupSchedule save(BackupSchedule backupSchedule);
BackupSchedule findById(String scheduleId);
}
......@@ -29,5 +29,12 @@ public interface BackupCollectionService {
CollectionState restoreCollection(String stateId);
BackupCollection update(BackupCollection collection);
BackupCollection update(BackupCollection collection, String collectionName);
BackupCollection getCollectionConfiguration(String collectionName);
void deleteCollectionConfiguration(String collectionName);
List<BackupCollection> listCollectionsConfigurations();
}
/*
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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.opengroup.osdu.backup.service;
import java.util.EnumMap;
import java.util.List;
import org.opengroup.osdu.backup.locator.Asset;
import org.opengroup.osdu.backup.model.BackupImportRequest;
import org.opengroup.osdu.backup.model.BackupSchedule;
import org.opengroup.osdu.backup.model.BackupStamp;
public interface BackupService {
BackupSchedule submitBackupSchedule(BackupSchedule backupSchedule);
BackupSchedule updateBackupSchedule(BackupSchedule backupSchedule);
BackupSchedule getBackupSchedule(String id);
BackupStamp submitBackupImportRequest(BackupImportRequest importRequest);
List<BackupSchedule> listSchedules();
EnumMap<Asset, List<BackupStamp>> listBackups();
}
......@@ -27,7 +27,6 @@ import org.opengroup.osdu.backup.model.CollectionState;
import org.opengroup.osdu.backup.repository.BackupCollectionRepository;
import org.opengroup.osdu.backup.repository.CollectionStateRepository;
import org.opengroup.osdu.backup.service.BackupCollectionService;
import org.opengroup.osdu.backup.service.BackupService;
import org.opengroup.osdu.backup.shedulers.SchedulerService;
import org.springframework.stereotype.Service;
......@@ -38,7 +37,6 @@ public class BackupCollectionServiceImpl implements BackupCollectionService {
private final BackupCollectionRepository collectionRepository;
private final CollectionStateRepository collectionStateRepository;
private final BackupService backupService;
private final AssetManagerFactory assetManagerFactory;
private final SchedulerService schedulerService;
......@@ -66,14 +64,30 @@ public class BackupCollectionServiceImpl implements BackupCollectionService {
CollectionState state = collectionStateRepository.getStateById(stateId);
state.getBackupStamps().forEach(backupStamp ->
assetManagerFactory.getAssetManager(backupStamp.getAssetType())
.importBackup(backupStamp.getStampId()));
.importBackup(backupStamp.getStampId()));
return state;
}
@Override
public BackupCollection update(BackupCollection collection) {
BackupCollection backupCollection = collectionRepository.updateCollection(collection);
public BackupCollection update(BackupCollection collection, String collectionName) {
BackupCollection backupCollection = collectionRepository.updateCollection(collection, collectionName);
schedulerService.updateCollectionTask(backupCollection);
return backupCollection;
}
@Override
public BackupCollection getCollectionConfiguration(String collectionName) {
return collectionRepository.getCollectionByName(collectionName);
}
@Override
public void deleteCollectionConfiguration(String collectionName) {
BackupCollection collection = collectionRepository.deleteCollectionByName(collectionName);
schedulerService.cancelCollectionTask(collection);
}
@Override
public List<BackupCollection> listCollectionsConfigurations() {
return collectionRepository.listBackupCollections();
}
}
/*
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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.opengroup.osdu.backup.service.impl;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.opengroup.osdu.backup.locator.Asset;
import org.opengroup.osdu.backup.locator.AssetManagerFactory;
import org.opengroup.osdu.backup.model.BackupImportRequest;
import org.opengroup.osdu.backup.model.BackupSchedule;
import org.opengroup.osdu.backup.model.BackupStamp;
import org.opengroup.osdu.backup.repository.BackupStampRepository;
import org.opengroup.osdu.backup.repository.ScheduleRepository;
import org.opengroup.osdu.backup.service.BackupService;
import org.opengroup.osdu.backup.shedulers.SchedulerService;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class BackupServiceImpl implements BackupService {
private final SchedulerService schedulerService;
private final BackupStampRepository backupStampRepository;
private final ScheduleRepository scheduleRepository;
private final AssetManagerFactory factory;
//TODO currently schedules startup changed to BackupCollectionServiceImpl.startUpSchedulers()
// @PostConstruct
public void startUpSchedulers() {
List<BackupSchedule> backupScheduleList = scheduleRepository.listBackupSchedules();
backupScheduleList.stream()/*.filter(BackupSchedule::isActive)*/
.forEach(schedulerService::addTaskToScheduler);
}
@Override
public BackupSchedule submitBackupSchedule(BackupSchedule backupSchedule) {
Map<String, String> assetContext = backupSchedule.getAssetContext();
BackupSchedule byAssetContext = scheduleRepository
.findByAssetContext(backupSchedule.getAssetType(), assetContext);
if (Objects.nonNull(byAssetContext)) {
throw new AppException(HttpStatus.CONFLICT.value(), "Conflict"
, String.format("Schedule with context %s already exist", assetContext));
} else {
BackupSchedule savedSchedule = scheduleRepository.save(backupSchedule);
schedulerService.addTaskToScheduler(backupSchedule);
return savedSchedule;
}
}
@Override
public BackupSchedule updateBackupSchedule(BackupSchedule backupSchedule) {
if (Objects.isNull(backupSchedule.getScheduleId())) {
throw new AppException(HttpStatus.BAD_REQUEST.value(), "Bad request", "Schedule id required");
}
BackupSchedule updatedSchedule = scheduleRepository.updateSchedule(backupSchedule);
schedulerService.updateTask(updatedSchedule);
return updatedSchedule;
}
@Override
public BackupSchedule getBackupSchedule(String scheduleId) {
return scheduleRepository.findById(scheduleId);
}
@Override
public BackupStamp submitBackupImportRequest(BackupImportRequest importRequest) {
return factory.getAssetManager(importRequest.getAsset()).importBackup(importRequest.getBackupStampId());
}
@Override
public List<BackupSchedule> listSchedules() {
return scheduleRepository.listBackupSchedules();
}
@Override
public EnumMap<Asset, List<BackupStamp>> listBackups() {
return backupStampRepository
.listAvailableBackupStamps();
}
}
......@@ -18,28 +18,9 @@
package org.opengroup.osdu.backup.shedulers;
import org.opengroup.osdu.backup.model.BackupCollection;
import org.opengroup.osdu.backup.model.BackupSchedule;
public interface SchedulerService {
/**
* @deprecated currently backup tasks managing goes through collections
*/
@Deprecated
void addTaskToScheduler(BackupSchedule backupSchedule);
/**
* @deprecated currently backup tasks managing go through collections
*/
@Deprecated
boolean cancelScheduledTask(BackupSchedule backupSchedule);
/**
* @deprecated currently backup tasks managing go through collections