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);
        }
Esempio n. 2
0
        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}&lt={latitude}"));

                default:
                    //Rethrow all other errors
                    throw result.Exception;
                }
            }

            return(File(result.FileStream, "application/octet-stream", objectKey));
        }
Esempio n. 3
0
 public Task <CdnServer> SelectNearestServerAsync(double longitude, double latitude)
 {
     return(_cdnServerService.GetNearestServerAsync(longitude, latitude, CdnServerRole.CacheServer));
 }