using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL; using Tango.BL.DTO; using Tango.BL.Entities; using Tango.FSE.BL.CacheEntities; using Tango.FSE.Web.Messages; namespace Tango.FSE.BL.Services { public class TangoVersionsService : FSEServiceBase { private const string TANGO_VERSIONS_COLLECTION = "TangoVersions"; private MemoryCacheDoubleKeyDictionary _tangoVersionsCache; public TangoVersionsService() { _tangoVersionsCache = MemoryCache.GetOrCreateCache(TANGO_VERSIONS_COLLECTION); } /// /// Gets all the available PPC/Firmware versions history. /// /// public Task> GetAllTangoVersions() { return DataResolver>.Builder.New() .ConfigureCascade(DataResolverNode.InMemoryCache, DataResolverNode.Web, DataResolverNode.Online, DataResolverNode.DiskCache) .InMemoryCache((context) => { var tangoVersions = _tangoVersionsCache .ToList() .Where(x => x.EnvironmentID == Authentication.CurrentEnvironment.ID) .Select(x => x.TangoVersion.ToObservable()) .OrderByDescending(x => Version.Parse(x.Version)) .ToList(); if (tangoVersions.Count == 0) { throw new IndexOutOfRangeException("The memory cache did contain any Tango versions."); } return tangoVersions; }) .Web((context) => { var tangoVersions = WebClient.GetTangoVersions(new GetTangoVersionsRequest()).GetAwaiter().GetResult() .Versions .Select(x => x.ToObservable()) .ToList(); using (var cache = DiskCache.CreateContext()) { var collection = cache.Database.GetCollection(TANGO_VERSIONS_COLLECTION); foreach (var tangoVersion in tangoVersions) { try { var tangoVersionDTO = TangoVersionDTO.FromObservable(tangoVersion); CachedTangoVersion cachedTangoVersion = new CachedTangoVersion(); cachedTangoVersion.EnvironmentID = Authentication.CurrentEnvironment.ID; cachedTangoVersion.TangoVersion = tangoVersionDTO; _tangoVersionsCache.Put(tangoVersion.Version, Authentication.CurrentEnvironment.ID, cachedTangoVersion); collection.Upsert(cachedTangoVersion); } catch (Exception ex) { LogManager.Log(ex, $"Error caching Tango version '{tangoVersion.Version}' on disk."); } } } return tangoVersions; }) .Online((context) => { using (ObservablesContext db = ObservablesContext.CreateDefault()) { var tangoVersions = db.TangoVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).ToList(); using (var cache = DiskCache.CreateContext()) { var collection = cache.Database.GetCollection(TANGO_VERSIONS_COLLECTION); foreach (var tangoVersion in tangoVersions) { try { var tangoVersionDTO = TangoVersionDTO.FromObservable(tangoVersion); CachedTangoVersion cachedTangoVersion = new CachedTangoVersion(); cachedTangoVersion.EnvironmentID = Authentication.CurrentEnvironment.ID; cachedTangoVersion.TangoVersion = tangoVersionDTO; _tangoVersionsCache.Put(tangoVersion.Version, Authentication.CurrentEnvironment.ID, cachedTangoVersion); collection.Upsert(cachedTangoVersion); } catch (Exception ex) { LogManager.Log(ex, $"Error caching Tango version '{tangoVersion.Version}' on disk."); } } } return tangoVersions; } }) .DiskCache((context) => { using (var cache = DiskCache.CreateContext()) { var collection = cache.Database.GetCollection(TANGO_VERSIONS_COLLECTION); return collection .Find(x => x.EnvironmentID == Authentication.CurrentEnvironment.ID) .ToList() .Select(x => x.TangoVersion.ToObservable()) .ToList() .OrderByDescending(x => Version.Parse(x.Version)) .ToList(); } }) .BuildExecuteAsync(); } public Task UploadCachedTupFile(TangoVersion version, String tupFilePath) { return Task.Factory.StartNew(() => { using (var cache = DiskCache.CreateContext()) { cache.Database.FileStorage.Upload(CreateCachedTangoVersionFileName(version), tupFilePath); } }); } public Task UploadCachedTfpFile(TangoVersion version, String tfpFilePath) { return Task.Factory.StartNew(() => { using (var cache = DiskCache.CreateContext()) { cache.Database.FileStorage.Upload(CreateCachedFirmwareVersionFileName(version), tfpFilePath); } }); } public Task DownloadCachedTupFile(TangoVersion version, String outputFilePath) { return Task.Factory.StartNew(() => { using (var cache = DiskCache.CreateContext()) { var file = cache.Database.FileStorage.FindById(CreateCachedTangoVersionFileName(version)); if (file == null) { throw new KeyNotFoundException("The specified version cache could not be found."); } file.SaveAs(outputFilePath, true); } }); } public Task DownloadCachedTfpFile(TangoVersion version, String outputFilePath) { return Task.Factory.StartNew(() => { using (var cache = DiskCache.CreateContext()) { var file = cache.Database.FileStorage.FindById(CreateCachedFirmwareVersionFileName(version)); if (file == null) { throw new KeyNotFoundException("The specified version cache could not be found."); } file.SaveAs(outputFilePath, true); } }); } public bool IsCachedTupFileExists(TangoVersion version) { using (var cache = DiskCache.CreateContext()) { return cache.Database.FileStorage.FindById(CreateCachedTangoVersionFileName(version)) != null; } } public bool IsCachedTfpFileExists(TangoVersion version) { using (var cache = DiskCache.CreateContext()) { return cache.Database.FileStorage.FindById(CreateCachedFirmwareVersionFileName(version)) != null; } } private String CreateCachedTangoVersionFileName(TangoVersion version) { return $"$/TangoVersions/application_package_v{version.VersionAndTag}.tup"; } private String CreateCachedFirmwareVersionFileName(TangoVersion version) { return $"$/TangoVersions/firmware_package_v{version.FirmwareVersion}.tfp"; } } }