@ -1,16 +1,10 @@
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.Auth ;
using Volo.Abp.Cli.Http ;
using Volo.Abp.Cli.Licensing ;
@ -29,6 +23,8 @@ namespace Volo.Abp.Cli.NuGet
protected ICancellationTokenProvider CancellationTokenProvider { get ; }
protected IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get ; }
private readonly IApiKeyService _ apiKeyService ;
private List < string > _ proPackageList ;
private DeveloperApiKeyResult _ apiKeyResult ;
public NuGetService (
IJsonSerializer jsonSerializer ,
@ -45,20 +41,20 @@ namespace Volo.Abp.Cli.NuGet
public async Task < SemanticVersion > GetLatestVersionOrNullAsync ( string packageId , bool includePreviews = false , bool includeNightly = false )
{
List < string > proPackageList = null ;
if ( AuthService . IsLoggedIn ( ) )
{
proPackageList = await GetProPackageListAsync ( ) ;
if ( _ proPackageList = = null )
{
_ proPackageList = await GetProPackageListAsync ( ) ;
}
}
string url ;
if ( includeNightly )
{
url =
$"https://www.myget.org/F/abp-nightly/api/v3/flatcontainer/{packageId.ToLowerInvariant()}/index.json" ;
url = $"https://www.myget.org/F/abp-nightly/api/v3/flatcontainer/{packageId.ToLowerInvariant()}/index.json" ;
}
else if ( proPackageList ? . Contains ( packageId ) ? ? false )
else if ( _ proPackageList ? . Contains ( packageId ) ? ? false )
{
url = await GetNuGetUrlForCommercialPackage ( packageId ) ;
}
@ -67,15 +63,13 @@ namespace Volo.Abp.Cli.NuGet
url = $"https://api.nuget.org/v3-flatcontainer/{packageId.ToLowerInvariant()}/index.json" ;
}
using ( var client = new CliHttpClient ( setBearerToken : false ) )
{
var responseMessage = await GetHttpResponseMessageWithRetryAsync ( client , url ) ;
if ( ! responseMessage . IsSuccessStatusCode )
{
throw new Exception ( $"ERROR: Remote server returns '{responseMessage.StatusCode}'" ) ;
}
var responseMessage = await client . GetHttpResponseMessageWithRetryAsync (
url ,
cancellationToken : CancellationTokenProvider . Token ,
logger : Logger
) ;
await RemoteServiceExceptionHandler . EnsureSuccessfulHttpResponseAsync ( responseMessage ) ;
@ -98,62 +92,41 @@ namespace Volo.Abp.Cli.NuGet
private async Task < string > GetNuGetUrlForCommercialPackage ( string packageId )
{
var apiKeyResult = await _ apiKeyService . GetApiKeyOrNullAsync ( ) ;
return CliUrls . GetNuGetPackageInfoUrl ( apiKeyResult . ApiKey , packageId ) ;
}
if ( _ apiKeyResult = = null )
{
_ apiKeyResult = await _ apiKeyService . GetApiKeyOrNullAsync ( ) ;
}
private async Task < HttpResponseMessage > GetHttpResponseMessageWithRetryAsync ( HttpClient client , string url )
{
return await HttpPolicyExtensions
. HandleTransientHttpError ( )
. OrResult ( msg = > ! msg . IsSuccessStatusCode )
. WaitAndRetryAsync ( new [ ]
{
TimeSpan . FromSeconds ( 2 ) ,
TimeSpan . FromSeconds ( 4 ) ,
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 ) ) ;
return CliUrls . GetNuGetPackageInfoUrl ( _ apiKeyResult . ApiKey , packageId ) ;
}
private async Task < List < string > > GetProPackageListAsync ( )
{
using var client = new CliHttpClient ( ) ;
var responseMessage = await client . GetAsync (
$"{CliUrls.WwwAbpIo}api/app/nugetPackage/proPackageNames" ,
CancellationTokenProvider . Token
var url = $"{CliUrls.WwwAbpIo}api/app/nugetPackage/proPackageNames" ;
var responseMessage = await client . GetHttpResponseMessageWithRetryAsync (
url : url ,
cancellationToken : CancellationTokenProvider . Token ,
logger : Logger
) ;
if ( ! responseMessage . IsSuccessStatusCode )
if ( responseMessage . IsSuccessStatusCode )
{
var exceptionMessage = "Remote server returns '" + ( int ) responseMessage . StatusCode + "-" + responseMessage . ReasonPhrase + "'. " ;
var remoteServiceErrorMessage = await RemoteServiceExceptionHandler . GetAbpRemoteServiceErrorAsync ( responseMessage ) ;
return JsonSerializer . Deserialize < List < string > > ( await responseMessage . Content . ReadAsStringAsync ( ) ) ;
}
if ( remoteServiceErrorMessage ! = null )
{
exceptionMessage + = remoteServiceErrorMessage ;
}
Logger . LogInformation ( exceptionMessage ) ;
return null ;
var exceptionMessage = "Remote server returns '" + ( int ) responseMessage . StatusCode + "-" + responseMessage . ReasonPhrase + "'. " ;
var remoteServiceErrorMessage = await RemoteServiceExceptionHandler . GetAbpRemoteServiceErrorAsync ( responseMessage ) ;
if ( remoteServiceErrorMessage ! = null )
{
exceptionMessage + = remoteServiceErrorMessage ;
}
return JsonSerializer . Deserialize < List < string > > ( await responseMessage . Content . ReadAsStringAsync ( ) ) ;
Logger . LogError ( exceptionMessage ) ;
return null ;
}
public class NuGetVersionResultDto