public async Task <CachedObjectResult> GetObjectFromCache(CdnFileObject fileObject) { var fileName = $"{BaseCacheFolder}\\{fileObject.Id}.{fileObject.VersionId}"; var result = new CachedObjectResult(); //Get fileObject in current server var currentServerfileObject = await _fileObjectRepository.GetObjectByKeyAsync(fileObject.Id, 0, _cdnOptions.Server.Id); if (currentServerfileObject != null) { currentServerfileObject.LastAccess = DateTime.Now; await _fileObjectRepository.UpdateObjectAsync(currentServerfileObject); result.IsSuccess = true; result.FileStream = File.OpenRead(fileName); return(result); } //if object was not previously cached and no space for downloading... if (Startup.CdnServer.FreeSpace < fileObject.Size) { result.IsSuccess = false; result.Exception = new NoFreeSpaceException(); return(result); } //Get nearest origin server var server = await _cdnServerService.GetNearestServerAsync(_cdnOptions.Server.Longitude, _cdnOptions.Server.Latitude, CdnServerRole.OriginServer); var fileUrl = $@"{server.Host.Trim()}/api/download/{fileObject.Id}/{fileObject.VersionId}"; //Download file object and save it locally... using (var client = new HttpClient()) { //Hard code auth token... client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "49ec97b507cc21806861817f2f0564d4"); using (var response = await client.GetAsync(fileUrl)) using (var fileStream = File.Create(fileName)) { await response.Content.CopyToAsync(fileStream); } } fileObject.ServerId = _cdnOptions.Server.Id; fileObject.LastAccess = DateTime.Now; await _fileObjectRepository.AddObjectAsync(fileObject); result.IsSuccess = true; result.FileStream = File.OpenRead(fileName); return(result); }
public async Task <IActionResult> LoadObject([FromQuery(Name = "lg")] double longitude, [FromQuery(Name = "lt")] double latitude) { var objectKey = Request.Path.ToString().TrimStart('/'); //Check if object exists at all var fileObject = await _fileObjectRepository.GetObjectByKeyAsync(objectKey); if (fileObject == null) { return(NotFound()); } var result = await _objectCacheService.GetObjectFromCache(fileObject); if (!result.IsSuccess) { switch (result.Exception) { //If no space, just redirect to another nearest Cache server case NoFreeSpaceException _: var server = await _cdnServerService.GetNearestServerAsync(longitude, latitude, CdnServerRole.CacheServer, new List <int> { _cdnOptions.Server.Id }); return(Redirect($"{server.Host.Trim()}{Request.Path}?lg={longitude}<={latitude}")); default: //Rethrow all other errors throw result.Exception; } } return(File(result.FileStream, "application/octet-stream", objectKey)); }
public Task <CdnServer> SelectNearestServerAsync(double longitude, double latitude) { return(_cdnServerService.GetNearestServerAsync(longitude, latitude, CdnServerRole.CacheServer)); }