Browse Source

closes volosoft/volo#760

pull/2503/head
Alper Ebicoglu 7 years ago
parent
commit
a4e20048af
  1. 11
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliUrls.cs
  2. 11
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs
  3. 37
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Licensing/AbpIoApiKeyService.cs
  4. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Licensing/IApiKeyService.cs
  5. 80
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs
  6. 57
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs

11
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliUrls.cs

@ -4,9 +4,9 @@
{
#if DEBUG
public const string WwwAbpIo = "https://localhost:44328/";
public const string AccountAbpIo = "https://localhost:44333/";
public const string NuGetRootPath = "https://localhost:44373/";
#else
public const string WwwAbpIo = "https://abp.io/";
@ -18,7 +18,12 @@
public static string GetNuGetServiceIndexUrl(string apiKey)
{
return NuGetRootPath + apiKey + "/v3/index.json";
return $"{NuGetRootPath}{apiKey}/v3/index.json";
}
public static string GetNuGetPackageInfoUrl(string apiKey, string packageId)
{
return $"{NuGetRootPath}{apiKey}/v3/package/{packageId}/index.json";
}
}
}

11
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs

@ -107,17 +107,6 @@ namespace Volo.Abp.Cli.Commands
private async Task<string> GetNuGetIndexUrlAsync()
{
var apiKeyResult = await _apiKeyService.GetApiKeyOrNullAsync();
if (apiKeyResult == null || string.IsNullOrEmpty(apiKeyResult.ApiKey))
{
Logger.LogError("Couldn't retrieve your NuGet API key!");
Logger.LogWarning(File.Exists(CliPaths.AccessToken)
? "Make sure you have an active session and license on commercial.abp.io. To re-sign in you can use the CLI command \"abp login <username>\"."
: "You are not signed in to commercial.abp.io. Use the CLI command \"abp login <username>\" to sign in.");
return null;
}
return CliUrls.GetNuGetServiceIndexUrl(apiKeyResult.ApiKey);
}

37
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Licensing/AbpIoApiKeyService.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
@ -19,6 +20,7 @@ namespace Volo.Abp.Cli.Licensing
protected IJsonSerializer JsonSerializer { get; }
protected IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; }
private readonly ILogger<AbpIoApiKeyService> _logger;
private DeveloperApiKeyResult _apiKeyResult = null;
public AbpIoApiKeyService(IJsonSerializer jsonSerializer, IRemoteServiceExceptionHandler remoteServiceExceptionHandler, ILogger<AbpIoApiKeyService> logger)
{
@ -27,8 +29,20 @@ namespace Volo.Abp.Cli.Licensing
_logger = logger;
}
public async Task<DeveloperApiKeyResult> GetApiKeyOrNullAsync()
public async Task<DeveloperApiKeyResult> GetApiKeyOrNullAsync(bool invalidateCache = false)
{
if (invalidateCache)
{
_apiKeyResult = null;
}
if (_apiKeyResult != null)
{
return _apiKeyResult;
}
var url = $"{CliUrls.WwwAbpIo}api/license/api-key";
using (var client = new CliHttpClient())
{
var response = await HttpPolicyExtensions
@ -45,17 +59,17 @@ namespace Volo.Abp.Cli.Licensing
if (responseMessage.Exception != null)
{
_logger.LogWarning(
$"{retryCount}. request attempt failed with an error: \"{responseMessage.Exception.Message}\". " +
$"{retryCount}. request attempt failed to {url} with an error: \"{responseMessage.Exception.Message}\". " +
$"Waiting {timeSpan.TotalSeconds} secs for the next try...");
}
else if (responseMessage.Result != null)
{
_logger.LogWarning(
$"{retryCount}. request attempt failed with {responseMessage.Result.StatusCode}-{responseMessage.Result.ReasonPhrase}. " +
$"{retryCount}. request attempt failed {url} with {(int)responseMessage.Result.StatusCode}-{responseMessage.Result.ReasonPhrase}. " +
$"Waiting {timeSpan.TotalSeconds} secs for the next try...");
}
})
.ExecuteAsync(async () => await client.GetAsync($"{CliUrls.WwwAbpIo}api/license/api-key"));
.ExecuteAsync(async () => await client.GetAsync(url));
if (!response.IsSuccessStatusCode)
{
@ -65,7 +79,20 @@ namespace Volo.Abp.Cli.Licensing
await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(response);
var responseContent = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<DeveloperApiKeyResult>(responseContent);
var apiKeyResult = JsonSerializer.Deserialize<DeveloperApiKeyResult>(responseContent);
if (apiKeyResult == null ||
string.IsNullOrEmpty(apiKeyResult.ApiKey))
{
_logger.LogError("Couldn't retrieve your NuGet API key!");
_logger.LogWarning(File.Exists(CliPaths.AccessToken)
? "Make sure you have an active session and license on commercial.abp.io. To re-sign in you can use the CLI command \"abp login <username>\"."
: "You are not signed in to commercial.abp.io. Use the CLI command \"abp login <username>\" to sign in.");
return null;
}
return apiKeyResult;
}
}
}

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Licensing/IApiKeyService.cs

@ -4,6 +4,6 @@ namespace Volo.Abp.Cli.Licensing
{
public interface IApiKeyService
{
Task<DeveloperApiKeyResult> GetApiKeyOrNullAsync();
Task<DeveloperApiKeyResult> GetApiKeyOrNullAsync(bool invalidateCache = false);
}
}

80
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs

@ -2,10 +2,19 @@ using Newtonsoft.Json;
using NuGet.Versioning;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Polly;
using Polly.Extensions.Http;
using Volo.Abp.Cli.Http;
using Volo.Abp.Cli.Licensing;
using Volo.Abp.Cli.ProjectBuilding;
using Volo.Abp.Cli.ProjectModification;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Json;
using Volo.Abp.Threading;
@ -14,37 +23,54 @@ namespace Volo.Abp.Cli.NuGet
{
public class NuGetService : ITransientDependency
{
public ILogger<VoloNugetPackagesVersionUpdater> Logger { get; set; }
protected IJsonSerializer JsonSerializer { get; }
protected ICancellationTokenProvider CancellationTokenProvider { get; }
protected IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; }
private readonly IApiKeyService _apiKeyService;
public NuGetService(
IJsonSerializer jsonSerializer,
IRemoteServiceExceptionHandler remoteServiceExceptionHandler,
ICancellationTokenProvider cancellationTokenProvider)
ICancellationTokenProvider cancellationTokenProvider, IApiKeyService apiKeyService)
{
JsonSerializer = jsonSerializer;
RemoteServiceExceptionHandler = remoteServiceExceptionHandler;
CancellationTokenProvider = cancellationTokenProvider;
_apiKeyService = apiKeyService;
Logger = NullLogger<VoloNugetPackagesVersionUpdater>.Instance;
}
public async Task<SemanticVersion> GetLatestVersionOrNullAsync(string packageId, bool includePreviews = false, bool includeNightly = false)
{
var url = includeNightly ?
$"https://www.myget.org/F/abp-nightly/api/v3/flatcontainer/{packageId.ToLowerInvariant()}/index.json" :
$"https://api.nuget.org/v3-flatcontainer/{packageId.ToLowerInvariant()}/index.json";
using (var client = new CliHttpClient(setBearerToken: false))
{
var url = includeNightly ?
$"https://www.myget.org/F/abp-nightly/api/v3/flatcontainer/{packageId.ToLowerInvariant()}/index.json" :
$"https://api.nuget.org/v3-flatcontainer/{packageId.ToLowerInvariant()}/index.json";
var responseMessage = await GetHttpResponseMessageWithRetryAsync(client, url);
var responseMessage = await client.GetAsync(url, CancellationTokenProvider.Token);
if (responseMessage.StatusCode == HttpStatusCode.NotFound)
{
var commercialNuGetUrl = await GetNuGetUrlForCommercialPackage(packageId);
responseMessage = await GetHttpResponseMessageWithRetryAsync(client, commercialNuGetUrl);
}
if (!responseMessage.IsSuccessStatusCode)
{
throw new Exception($"ERROR: Remote server returns '{responseMessage.StatusCode}'");
}
await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(responseMessage);
var result = await responseMessage.Content.ReadAsStringAsync();
var responseContent = await responseMessage.Content.ReadAsStringAsync();
var versions = JsonSerializer.Deserialize<NuGetVersionResultDto>(result).Versions.Select(x => SemanticVersion.Parse(x));
var versions = JsonSerializer
.Deserialize<NuGetVersionResultDto>(responseContent)
.Versions
.Select(SemanticVersion.Parse);
if (!includePreviews && !includeNightly)
{
@ -56,6 +82,42 @@ namespace Volo.Abp.Cli.NuGet
}
}
private async Task<string> GetNuGetUrlForCommercialPackage(string packageId)
{
var apiKeyResult = await _apiKeyService.GetApiKeyOrNullAsync();
return CliUrls.GetNuGetPackageInfoUrl(apiKeyResult.ApiKey, packageId);
}
private async Task<HttpResponseMessage> GetHttpResponseMessageWithRetryAsync(HttpClient client, string url)
{
return await HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => !msg.IsSuccessStatusCode)
.WaitAndRetryAsync(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(3),
TimeSpan.FromSeconds(7)
},
(responseMessage, timeSpan, retryCount, context) =>
{
if (responseMessage.Exception != null)
{
Logger.LogWarning(
$"{retryCount}. HTTP request attempt failed to {url} with an error: HTTP {(int)responseMessage.Result.StatusCode}-{responseMessage.Exception.Message}. " +
$"Waiting {timeSpan.TotalSeconds} secs for the next try...");
}
else if (responseMessage.Result != null)
{
Logger.LogWarning(
$"{retryCount}. HTTP request attempt failed to {url} with an error: {(int)responseMessage.Result.StatusCode}-{responseMessage.Result.ReasonPhrase}. " +
$"Waiting {timeSpan.TotalSeconds} secs for the next try...");
}
})
.ExecuteAsync(async () => await client.GetAsync(url, CancellationTokenProvider.Token));
}
public class NuGetVersionResultDto
{
[JsonProperty("versions")]

57
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs

@ -1,19 +1,24 @@
using NuGet.Versioning;
using System;
using NuGet.Versioning;
using System.IO;
using System.Threading.Tasks;
using System.Xml;
using Volo.Abp.Cli.NuGet;
using Volo.Abp.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace Volo.Abp.Cli.ProjectModification
{
public class VoloNugetPackagesVersionUpdater : ITransientDependency
{
private readonly NuGetService _nuGetService;
public ILogger<VoloNugetPackagesVersionUpdater> Logger { get; set; }
public VoloNugetPackagesVersionUpdater(NuGetService nuGetService)
{
_nuGetService = nuGetService;
Logger = NullLogger<VoloNugetPackagesVersionUpdater>.Instance;
}
public async Task UpdateSolutionAsync(string solutionPath, bool includePreviews)
@ -40,24 +45,54 @@ namespace Volo.Abp.Cli.ProjectModification
private async Task<string> UpdateVoloPackagesAsync(string content, bool includePreviews)
{
var doc = new XmlDocument() { PreserveWhitespace = true };
doc.LoadXml(content);
string packageId = null;
foreach (XmlNode package in doc.SelectNodes("/Project/ItemGroup/PackageReference[starts-with(@Include, 'Volo.')]"))
try
{
var versionAttribute = package.Attributes["Version"];
var doc = new XmlDocument()
{
PreserveWhitespace = true
};
doc.LoadXml(content);
var packageId = package.Attributes["Include"].Value;
var packageVersion = SemanticVersion.Parse(versionAttribute.Value);
var latestVersion = await _nuGetService.GetLatestVersionOrNullAsync(packageId, includePreviews);
var packageNodeList = doc.SelectNodes("/Project/ItemGroup/PackageReference[starts-with(@Include, 'Volo.')]");
if (latestVersion != null && packageVersion < latestVersion)
if (packageNodeList != null)
{
versionAttribute.Value = latestVersion.ToString();
foreach (XmlNode package in packageNodeList)
{
if (package.Attributes == null)
{
continue;
}
var versionAttribute = package.Attributes["Version"];
packageId = package.Attributes["Include"].Value;
var packageVersion = SemanticVersion.Parse(versionAttribute.Value);
Logger.LogDebug("Checking package \"{0}\"...", packageId);
var latestVersion = await _nuGetService.GetLatestVersionOrNullAsync(packageId, includePreviews);
if (latestVersion != null && packageVersion < latestVersion)
{
Logger.LogInformation("Updating package \"{0}\" v{1} to v{2}", packageId, packageVersion.ToString(), latestVersion.ToString());
versionAttribute.Value = latestVersion.ToString();
}
}
return await Task.FromResult(doc.OuterXml);
}
}
catch (Exception ex)
{
Logger.LogError("Cannot update volo packages! An error occured while updating the package \"{0}\". Error: {1}", packageId, ex.Message);
Logger.LogException(ex);
}
return doc.OuterXml;
return await Task.FromResult(content);
}
}
}

Loading…
Cancel
Save