Commit 61b3f418 authored by Riabokon Stanislav(EPAM)[GCP]'s avatar Riabokon Stanislav(EPAM)[GCP]
Browse files

Merge branch 'feature/GONRG-1638-remove_obsolete_logic' into 'integration-master'

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

Closes GONRG-1638

See merge request go3-nrg/platform/deployment-and-operations/backup-service!15
parents 0105fe08 8fa4ea8d
......@@ -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);
......
......@@ -16,13 +16,18 @@
*/
package org.opengroup.osdu.backup.exception;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
@Slf4j
......@@ -33,6 +38,19 @@ public class AppExceptionHandler {
return this.getErrorResponse(e);
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, String> handleValidationExceptions(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
return errors;
}
private ResponseEntity<Object> getErrorResponse(AppException e) {
String exceptionMsg = Objects.nonNull(e.getOriginalException())
......
......@@ -25,8 +25,6 @@ public interface AssetBackupManager {
BackupStamp exportBackupWithResult(BackupSchedule backupSchedule);
void exportBackup(BackupSchedule backupSchedule);
BackupStamp importBackup(String backupId);
void deleteBackups(List<BackupStamp> backupStamps);
......
......@@ -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 interval;
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);
}
......@@ -31,7 +31,7 @@ public interface BackupStampRepository {
EnumMap<Asset, List<BackupStamp>> listAvailableBackupStamps();
void deleteBackupStamps(List<BackupStamp> currentDate);
List<BackupStamp> deleteBackupStamps(List<BackupStamp> currentDate);
BackupStamp findBackupByStampId(String backupStampId);
}
/*
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;
......@@ -52,7 +50,9 @@ public class BackupCollectionServiceImpl implements BackupCollectionService {
@Override
public BackupCollection saveCollection(BackupCollection collection) {
BackupCollection savedCollection = collectionRepository.submitCollection(collection);
schedulerService.addCollectionToScheduler(savedCollection);
if (Boolean.TRUE.equals(collection.isActive())) {
schedulerService.addCollectionToScheduler(collection);
}
return savedCollection;
}
......@@ -66,14 +66,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