Updated recovery logic to fall back on older version if no image-hash is valid

This commit is contained in:
Martin Schett
2021-01-09 21:47:03 +01:00
parent cd707226f6
commit 1ed0627853
7 changed files with 111 additions and 15 deletions
+36 -14
View File
@@ -1,5 +1,6 @@
import json
import logging
from datetime import datetime
from app_be.services.dropboxservice import DropboxService
from app_be.services.hashservice import create_sha512
@@ -36,10 +37,20 @@ class ImageEndpoint:
return JsonResponse({'Result': 'success1'}, safe=False)
@staticmethod
@api_view(['GET'])
def image_api_get_single_version(request, identifier, version):
logger.debug('Image GET single with version call: {}'.format(request))
return ImageEndpoint.get_image(identifier+'_'+version)
@staticmethod
@api_view(['GET'])
def image_api_get_single(request, identifier):
logger.debug('Image GET single call: {}'.format(request))
return ImageEndpoint.get_image(identifier)
@staticmethod
def get_image(identifier):
# get metadata from MongoDB
metadata = MongoDBService.getSingle(identifier)
@@ -58,7 +69,6 @@ class ImageEndpoint:
# check image existence and correctness for each service + retrieve valid image if possible
for service in ImageEndpoint.storageServiceList:
logger.debug('Checking recovery for service ' + service.name)
print('Checking recovery for service ' + service.name)
service_image_bytes = service.read_file(metadata['filename'])
if service_image_bytes is not None:
recovery_has_image[service.name] = True
@@ -73,27 +83,39 @@ class ImageEndpoint:
recovery_has_image[service.name] = False
recovery_hash_matches[service.name] = False
# TODO: after talking with tobias about updating => replace with older version if hash is wrong
# check if any service has the image saved
if not ImageEndpoint.combine_boolean_dict_or(recovery_has_image):
logger.debug('None of the storage services has the requested image saved')
MongoDBService.deleteSingle(identifier)
return JsonResponse({'Result': 'Error - image is not available on any storage service and was deleted',
return JsonResponse({'Result': 'Error - image is not available on any storage service',
'id': identifier}, status=404, safe=False)
# check if any service has a valid version of the image saved
if not ImageEndpoint.combine_boolean_dict_or(recovery_hash_matches) and valid_image_bytes is None:
logger.debug('None of the storage services has a valid image saved')
MongoDBService.deleteSingle(identifier)
return JsonResponse({'Result': 'Error - image is not available on any storage service and was deleted',
'id': identifier}, status=404, safe=False)
logger.debug('None of the storage services has a valid image saved - assume oldest image is valid')
service_with_oldest = None
oldest_last_modified = datetime.now()
for service in ImageEndpoint.storageServiceList:
modified = service.get_last_modified(metadata['filename'])
if modified is not None and modified < oldest_last_modified:
oldest_last_modified = modified
service_with_oldest = service
# at this point we know at least one valid image is available
for service in ImageEndpoint.storageServiceList:
if not recovery_has_image[service.name] or not recovery_hash_matches[service.name]:
if not service.create_file(metadata['filename'], valid_image_bytes):
logger.error('Error duplicating file in service ' + service.name)
if service_with_oldest is None: # failsave if no image is available
return JsonResponse({'Result': 'Error - image is not available on any storage service',
'id': identifier}, status=404, safe=False)
# replace image on every service with oldest available
valid_image_bytes = service_with_oldest.read_file(metadata['filename'])
MongoDBService.replaceHash(identifier, valid_image_bytes)
for service in ImageEndpoint.storageServiceList:
if service != service_with_oldest:
if not service.create_file(metadata['filename'], valid_image_bytes):
logger.error('Error recovering file in service ' + service.name)
else:
# at this point we know at least one valid image is available
for service in ImageEndpoint.storageServiceList:
if not recovery_has_image[service.name] or not recovery_hash_matches[service.name]:
if not service.create_file(metadata['filename'], valid_image_bytes):
logger.error('Error duplicating file in service ' + service.name)
payload = {
'id': identifier,