public static async Task <List <SiteExtensionInfo> > GetPackagesFromNugetAPI(string filter = null, string feedUrl = null) { var extensions = new List <SiteExtensionInfo>(); var key = string.Format("{0}:{1}", filter, feedUrl); PackageCacheInfo info; if (PackageCaches.TryGetValue(key, out info) && DateTime.UtcNow < info.ExpiredUtc) { return(info.Extensions); } if (string.IsNullOrEmpty(feedUrl)) { feedUrl = FeedExtensionsV2.GetFeedUrl(filter); } using (var client = new HttpClient { Timeout = HttpClientTimeout }) { var response = await client.GetAsync(feedUrl); var content = await response.Content.ReadAsStringAsync(); using (var reader = XmlReader.Create(new System.IO.StringReader(content))) { reader.ReadStartElement("feed"); while (reader.Read()) { if (reader.Name == "entry" && reader.IsStartElement()) { reader.ReadToDescendant("m:properties"); extensions.Add(new SiteExtensionInfo((XElement)XNode.ReadFrom(reader))); } } } } info = new PackageCacheInfo { ExpiredUtc = DateTime.UtcNow.AddMinutes(10), Extensions = extensions }; PackageCaches.AddOrUpdate(key, info, (k, i) => info); if (PackageCaches.Count > 10) { var toRemove = PackageCaches.OrderBy(p => p.Value.ExpiredUtc).FirstOrDefault(); if (!string.IsNullOrWhiteSpace(toRemove.Key)) { PackageCaches.TryRemove(toRemove.Key, out _); } } return(info.Extensions); }
/// <summary> /// <para>Query source repository for a package base on given package id and version</para> /// <para>Will also query pre-release and unlisted packages</para> /// </summary> /// <param name="packageId">Package id, must not be null</param> /// <param name="version">Package version, must not be null</param> /// <returns>Package metadata</returns> internal static async Task <SiteExtensionInfo> GetPackageByIdentity(string packageId, string version) { return((await PackageCacheInfo.GetPackagesFromNugetAPI()).FirstOrDefault(a => a.Id != null && a.Version != null && a.Id == packageId && a.Version == version)); }
/// <summary> /// Query source repository for latest package base given package id /// </summary> internal static async Task <SiteExtensionInfo> GetLatestPackageByIdFromSrcRepo(string packageId) { return((await PackageCacheInfo.GetPackagesFromNugetAPI()).FirstOrDefault(a => a.Id != null && a.Id == packageId)); }
/// <summary> /// <para>Query source repository for a package base on given package id and version</para> /// <para>Will also query pre-release and unlisted packages</para> /// </summary> /// <param name="packageId">Package id, must not be null</param> /// <param name="version">Package version, must not be null</param> /// <returns>Package metadata</returns> public static async Task <SiteExtensionInfo> GetPackageByIdentity(string packageId, string version = null) { if (string.IsNullOrEmpty(version)) { return((await PackageCacheInfo.GetPackagesFromNugetAPI()).FirstOrDefault(a => a.Id != null && a.Id == packageId)); } else { string address = null; try { JObject json = null; using (var client = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }) { Timeout = HttpClientTimeout }) { address = $"https://azuresearch-usnc.nuget.org/query?q=tags:AzureSiteExtension%20packageid:{packageId}&prerelease=true&semVerLevel=2.0.0"; using (var response = await client.GetAsync(address)) { response.EnsureSuccessStatusCode(); json = JObject.Parse(await response.Content.ReadAsStringAsync()); } json = (JObject)json.Value <JArray>("data").FirstOrDefault(); if (json == null) { return(null); } json = (JObject)json.Value <JArray>("versions").FirstOrDefault(j => j.Value <string>("version") == version); if (json == null) { return(null); } address = json.Value <string>("@id"); using (var response = await client.GetAsync(address)) { response.EnsureSuccessStatusCode(); json = JObject.Parse(await response.Content.ReadAsStringAsync()); } address = json.Value <string>("catalogEntry"); using (var response = await client.GetAsync(address)) { response.EnsureSuccessStatusCode(); json = JObject.Parse(await response.Content.ReadAsStringAsync()); } return(new SiteExtensionInfo(json)); } } catch (Exception ex) { if (!string.IsNullOrEmpty(address)) { throw; } throw new InvalidOperationException($"Http request to {address} failed with {ex.Message}", ex); } } }