fix to address issue 275 without modifying common/http.cs

This commit is contained in:
anotherRedbeard 2023-08-31 11:20:22 -05:00
Родитель b87b1885f1
Коммит cedcf7f1ae
5 изменённых файлов: 98 добавлений и 14 удалений

Просмотреть файл

@ -17,7 +17,7 @@ namespace publisher;
internal static class Api
{
public static async ValueTask ProcessDeletedArtifacts(IReadOnlyCollection<FileInfo> files, JsonObject configurationJson, ServiceDirectory serviceDirectory, ServiceUri serviceUri, PutRestResource putRestResource, DeleteRestResource deleteRestResource, ILogger logger, CancellationToken cancellationToken)
public static async ValueTask ProcessDeletedArtifacts(IReadOnlyCollection<FileInfo> files, JsonObject configurationJson, ServiceDirectory serviceDirectory, ServiceUri serviceUri, GetRestResource getRestResource, PutRestResource putRestResource, DeleteRestResource deleteRestResource, ILogger logger, CancellationToken cancellationToken)
{
var configurationApis = GetConfigurationApis(configurationJson);
@ -27,7 +27,7 @@ internal static class Api
secondKeySelector: configurationArtifact => configurationArtifact.ApiName,
firstSelector: api => (api.ApiName, api.InformationFile, api.SpecificationFile, ConfigurationApiJson: (JsonObject?)null),
bothSelector: (file, configurationArtifact) => (file.ApiName, file.InformationFile, file.SpecificationFile, ConfigurationApiJson: configurationArtifact.Json))
.ForEachParallel(async artifact => await ProcessDeletedApi(artifact.ApiName, artifact.InformationFile, artifact.SpecificationFile, artifact.ConfigurationApiJson, serviceDirectory, serviceUri, putRestResource, deleteRestResource, logger, cancellationToken),
.ForEachParallel(async artifact => await ProcessDeletedApi(artifact.ApiName, artifact.InformationFile, artifact.SpecificationFile, artifact.ConfigurationApiJson, serviceDirectory, serviceUri, getRestResource, putRestResource, deleteRestResource, logger, cancellationToken),
cancellationToken);
}
@ -192,7 +192,7 @@ internal static class Api
return new(specificationFile.ApiDirectory.GetName());
}
private static async ValueTask ProcessDeletedApi(ApiName apiName, ApiInformationFile? deletedApiInformationFile, ApiSpecificationFile? deletedSpecificationFile, JsonObject? configurationApiJson, ServiceDirectory serviceDirectory, ServiceUri serviceUri, PutRestResource putRestResource, DeleteRestResource deleteRestResource, ILogger logger, CancellationToken cancellationToken)
private static async ValueTask ProcessDeletedApi(ApiName apiName, ApiInformationFile? deletedApiInformationFile, ApiSpecificationFile? deletedSpecificationFile, JsonObject? configurationApiJson, ServiceDirectory serviceDirectory, ServiceUri serviceUri, GetRestResource getRestResource, PutRestResource putRestResource, DeleteRestResource deleteRestResource, ILogger logger, CancellationToken cancellationToken)
{
switch (deletedApiInformationFile, deletedSpecificationFile)
{
@ -208,7 +208,7 @@ internal static class Api
}
else
{
await PutApi(apiName, existingInformationFile, specificationFile: null, configurationApiJson, serviceUri, putRestResource, logger, cancellationToken);
await PutApi(apiName, existingInformationFile, specificationFile: null, configurationApiJson, serviceUri, getRestResource, putRestResource, logger, cancellationToken);
}
return;
@ -221,7 +221,7 @@ internal static class Api
}
else
{
await PutApi(apiName, apiInformationFile: null, existingSpecificationFile, configurationApiJson, serviceUri, putRestResource, logger, cancellationToken);
await PutApi(apiName, apiInformationFile: null, existingSpecificationFile, configurationApiJson, serviceUri, getRestResource, putRestResource, logger, cancellationToken);
}
return;
@ -260,7 +260,7 @@ internal static class Api
.FirstOrDefault() : null;
}
private static async ValueTask PutApi(ApiName apiName, ApiInformationFile? apiInformationFile, ApiSpecificationFile? specificationFile, JsonObject? configurationApiJson, ServiceUri serviceUri, PutRestResource putRestResource, ILogger logger, CancellationToken cancellationToken)
private static async ValueTask PutApi(ApiName apiName, ApiInformationFile? apiInformationFile, ApiSpecificationFile? specificationFile, JsonObject? configurationApiJson, ServiceUri serviceUri, GetRestResource getRestResource, PutRestResource putRestResource, ILogger logger, CancellationToken cancellationToken)
{
if (apiInformationFile is null && specificationFile is null && configurationApiJson is null)
{
@ -278,7 +278,7 @@ internal static class Api
putUri = putUri.SetQueryParam("import", "true").ToUri();
}
var apiJson = await GetApiJson(apiName, apiInformationFile, specificationFile, configurationApiJson, cancellationToken);
var apiJson = await GetApiJson(apiName, apiInformationFile, specificationFile, configurationApiJson, serviceUri, getRestResource, cancellationToken);
await putRestResource(putUri, apiJson, cancellationToken);
// Handle GraphQL specification
@ -288,7 +288,7 @@ internal static class Api
}
}
private static async ValueTask<JsonObject> GetApiJson(ApiName apiName, ApiInformationFile? apiInformationFile, ApiSpecificationFile? specificationFile, JsonObject? configurationApiJson, CancellationToken cancellationToken)
private static async ValueTask<JsonObject> GetApiJson(ApiName apiName, ApiInformationFile? apiInformationFile, ApiSpecificationFile? specificationFile, JsonObject? configurationApiJson, ServiceUri serviceUri, GetRestResource getRestResource, CancellationToken cancellationToken)
{
var apiJson = new JsonObject();
@ -301,6 +301,13 @@ internal static class Api
if (specificationFile is not null and (ApiSpecificationFile.Wadl or ApiSpecificationFile.Wsdl or ApiSpecificationFile.OpenApi))
{
var specificationJson = await GetApiSpecificationJson(specificationFile, cancellationToken);
//If there is not apiInformationFile, retrieve the serviceUrl from the API's service.
if (apiInformationFile is null)
{
// Temporary work around to address the fact the management API will update the serviceURL to the management API's URL.
var propertyName = "serviceUrl";
apiJson = await GetPropertiesPropertyFronJson(apiName, propertyName, serviceUri, getRestResource, cancellationToken);
}
apiJson = apiJson.Merge(specificationJson);
}
@ -317,6 +324,52 @@ internal static class Api
return apiJson;
}
/// <summary>
/// This method will call the REST endpoint for the passed in API Name. It then will take that response, parse the properties object
/// and return the propertyName property.
/// </summary>
/// <param name="apiName">Name of the api</param>
/// <param name="propertyName">Name of the property you want to get the value of from the properties object</param>
/// <param name="serviceUri">URI of the endpoint you need to get the json from</param>
/// <param name="getRestResource">Delegate to call the REST endpoint based on the apiName</param>
/// <param name="cancellationToken">Cancellation Token</param>
/// <returns></returns>
static async Task<JsonObject> GetPropertiesPropertyFronJson(ApiName apiName, String propertyName, ServiceUri serviceUri, GetRestResource getRestResource, CancellationToken cancellationToken)
{
// If the API does not have an information file, retrieve the serviceUrl from the API's service.
var apiUri = GetApiUri(apiName, serviceUri);
var tagJsonObject = await getRestResource(apiUri.Uri, cancellationToken);
var propertiesNode = tagJsonObject.GetNullableProperty("properties");
if (propertiesNode != null && propertiesNode is JsonObject propertiesObject)
{
var apiServiceUrlNode = propertiesObject.GetNullableProperty(propertyName);
if (apiServiceUrlNode != null && apiServiceUrlNode is JsonValue apiServiceUrlValue)
{
var apiServiceUrl = apiServiceUrlValue.ToString();
JsonObject apiJson = new JsonObject
{
["properties"] = new JsonObject
{
["serviceUrl"] = apiServiceUrl
}
};
return apiJson;
}
else
{
throw new InvalidOperationException($"Could not find property '{propertyName}' in the properties object of the JSON object.");
}
}
else
{
throw new InvalidOperationException($"Could not find the properties object in JSON object.");
}
}
private static async ValueTask<JsonObject> GetApiSpecificationJson(ApiSpecificationFile specificationFile, CancellationToken cancellationToken)
{
var json = new JsonObject
@ -374,7 +427,7 @@ internal static class Api
await putRestResource(schemaUri.Uri, json, cancellationToken);
}
public static async ValueTask ProcessArtifactsToPut(IReadOnlyCollection<FileInfo> files, JsonObject configurationJson, ServiceDirectory serviceDirectory, ServiceUri serviceUri, PutRestResource putRestResource, ILogger logger, CancellationToken cancellationToken)
public static async ValueTask ProcessArtifactsToPut(IReadOnlyCollection<FileInfo> files, JsonObject configurationJson, ServiceDirectory serviceDirectory, ServiceUri serviceUri, GetRestResource getRestResource, PutRestResource putRestResource, ILogger logger, CancellationToken cancellationToken)
{
var configurationApis = GetConfigurationApis(configurationJson);
@ -384,7 +437,7 @@ internal static class Api
secondKeySelector: configurationArtifact => configurationArtifact.ApiName,
firstSelector: api => (api.ApiName, api.InformationFile, api.SpecificationFile, ConfigurationApiJson: (JsonObject?)null),
bothSelector: (fileApi, configurationArtifact) => (fileApi.ApiName, fileApi.InformationFile, fileApi.SpecificationFile, ConfigurationApiJson: configurationArtifact.Json))
.ForEachParallel(async api => await PutApi(api.ApiName, api.InformationFile, api.SpecificationFile, api.ConfigurationApiJson, serviceUri, putRestResource, logger, cancellationToken),
.ForEachParallel(async api => await PutApi(api.ApiName, api.InformationFile, api.SpecificationFile, api.ConfigurationApiJson, serviceUri, getRestResource, putRestResource, logger, cancellationToken),
cancellationToken);
}
}

Просмотреть файл

@ -7,6 +7,7 @@ using System.Threading.Tasks;
namespace publisher;
internal delegate IAsyncEnumerable<JsonObject> ListRestResources(Uri uri, CancellationToken cancellationToken);
internal delegate ValueTask<JsonObject> GetRestResource(Uri uri, CancellationToken cancellationToken);
internal delegate ValueTask PutRestResource(Uri uri, JsonObject jsonObject, CancellationToken cancellationToken);

Просмотреть файл

@ -51,6 +51,7 @@ public static class Program
.AddSingleton(GetHttpPipeline)
.AddSingleton(GetDeleteRestResource)
.AddSingleton(GetListRestResources)
.AddSingleton(GetGetRestResource)
.AddSingleton(GetPutRestResource)
.AddSingleton(GetPublisherParameters)
.AddHostedService<Publisher>();
@ -149,6 +150,30 @@ public static class Program
};
}
private static GetRestResource GetGetRestResource(IServiceProvider provider)
{
var pipeline = provider.GetRequiredService<HttpPipeline>();
var logger = provider.GetRequiredService<ILoggerFactory>().CreateLogger(nameof(GetRestResource));
return async (uri, cancellationToken) =>
{
logger.LogDebug("Beginning request to get REST resource at URI {uri}...", uri);
var json = await pipeline.GetJsonObject(uri, cancellationToken);
if (logger.IsEnabled(LogLevel.Trace))
{
logger.LogTrace("Successfully retrieved REST resource {json} at URI {uri}.", json.ToJsonString(), uri);
}
else
{
logger.LogDebug("Successfully retrieved REST resource at URI {uri}.", uri);
}
return json;
};
}
private static PutRestResource GetPutRestResource(IServiceProvider provider)
{
var pipeline = provider.GetRequiredService<HttpPipeline>();
@ -184,6 +209,7 @@ public static class Program
ConfigurationJson = GetConfigurationJson(configuration),
DeleteRestResource = provider.GetRequiredService<DeleteRestResource>(),
ListRestResources = provider.GetRequiredService<ListRestResources>(),
GetRestResource = provider.GetRequiredService<GetRestResource>(),
Logger = provider.GetRequiredService<ILoggerFactory>().CreateLogger(nameof(Publisher)),
PutRestResource = provider.GetRequiredService<PutRestResource>(),
ServiceDirectory = GetServiceDirectory(configuration),

Просмотреть файл

@ -24,6 +24,7 @@ internal class Publisher : BackgroundService
public required DeleteRestResource DeleteRestResource { get; init; }
public required ILogger Logger { get; init; }
public required ListRestResources ListRestResources { get; init; }
public required GetRestResource GetRestResource { get; init; }
public required PutRestResource PutRestResource { get; init; }
public required ServiceDirectory ServiceDirectory { get; init; }
public required ServiceUri ServiceUri { get; init; }
@ -86,6 +87,7 @@ internal class Publisher : BackgroundService
publisherParameters.ServiceDirectory,
publisherParameters.ServiceUri,
publisherParameters.ListRestResources,
publisherParameters.GetRestResource,
publisherParameters.PutRestResource,
publisherParameters.DeleteRestResource,
logger,
@ -141,6 +143,7 @@ internal class Publisher : BackgroundService
publisherParameters.ServiceDirectory,
publisherParameters.ServiceUri,
publisherParameters.ListRestResources,
publisherParameters.GetRestResource,
publisherParameters.PutRestResource,
publisherParameters.DeleteRestResource,
publisherParameters.Logger,
@ -154,6 +157,7 @@ internal class Publisher : BackgroundService
publisherParameters.ServiceDirectory,
publisherParameters.ServiceUri,
publisherParameters.ListRestResources,
publisherParameters.GetRestResource,
publisherParameters.PutRestResource,
publisherParameters.DeleteRestResource,
publisherParameters.Logger,

Просмотреть файл

@ -10,7 +10,7 @@ namespace publisher;
internal static class Service
{
public static async ValueTask ProcessDeletedArtifacts(IReadOnlyCollection<FileInfo> files, JsonObject configurationJson, ServiceDirectory serviceDirectory, ServiceUri serviceUri, ListRestResources listRestResources, PutRestResource putRestResource, DeleteRestResource deleteRestResource, ILogger logger, CancellationToken cancellationToken)
public static async ValueTask ProcessDeletedArtifacts(IReadOnlyCollection<FileInfo> files, JsonObject configurationJson, ServiceDirectory serviceDirectory, ServiceUri serviceUri, ListRestResources listRestResources, GetRestResource getRestResource, PutRestResource putRestResource, DeleteRestResource deleteRestResource, ILogger logger, CancellationToken cancellationToken)
{
await GatewayApi.ProcessDeletedArtifacts(files, configurationJson, serviceDirectory, serviceUri, listRestResources, putRestResource, deleteRestResource, logger, cancellationToken);
await ProductApi.ProcessDeletedArtifacts(files, configurationJson, serviceDirectory, serviceUri, listRestResources, putRestResource, deleteRestResource, logger, cancellationToken);
@ -18,7 +18,7 @@ internal static class Service
await ApiTag.ProcessDeletedArtifacts(files, configurationJson, serviceDirectory, serviceUri, listRestResources, putRestResource, deleteRestResource, logger, cancellationToken);
await ApiDiagnostic.ProcessDeletedArtifacts(files, serviceDirectory, serviceUri, deleteRestResource, logger, cancellationToken);
await ApiPolicy.ProcessDeletedArtifacts(files, serviceDirectory, serviceUri, deleteRestResource, logger, cancellationToken);
await Api.ProcessDeletedArtifacts(files, configurationJson, serviceDirectory, serviceUri, putRestResource, deleteRestResource, logger, cancellationToken);
await Api.ProcessDeletedArtifacts(files, configurationJson, serviceDirectory, serviceUri, getRestResource, putRestResource, deleteRestResource, logger, cancellationToken);
await Subscription.ProcessDeletedArtifacts(files, serviceDirectory, serviceUri, deleteRestResource, logger, cancellationToken);
await ProductTag.ProcessDeletedArtifacts(files, configurationJson, serviceDirectory, serviceUri, listRestResources, putRestResource, deleteRestResource, logger, cancellationToken);
await ProductGroup.ProcessDeletedArtifacts(files, configurationJson, serviceDirectory, serviceUri, listRestResources, putRestResource, deleteRestResource, logger, cancellationToken);
@ -35,7 +35,7 @@ internal static class Service
await NamedValue.ProcessDeletedArtifacts(files, serviceDirectory, serviceUri, deleteRestResource, logger, cancellationToken);
}
public static async ValueTask ProcessArtifactsToPut(IReadOnlyCollection<FileInfo> files, JsonObject configurationJson, ServiceDirectory serviceDirectory, ServiceUri serviceUri, ListRestResources listRestResources, PutRestResource putRestResource, DeleteRestResource deleteRestResource, ILogger logger, CancellationToken cancellationToken)
public static async ValueTask ProcessArtifactsToPut(IReadOnlyCollection<FileInfo> files, JsonObject configurationJson, ServiceDirectory serviceDirectory, ServiceUri serviceUri, ListRestResources listRestResources, GetRestResource getRestResource, PutRestResource putRestResource, DeleteRestResource deleteRestResource, ILogger logger, CancellationToken cancellationToken)
{
await NamedValue.ProcessArtifactsToPut(files, configurationJson, serviceDirectory, serviceUri, putRestResource, logger, cancellationToken);
await Tag.ProcessArtifactsToPut(files, configurationJson, serviceDirectory, serviceUri, putRestResource, logger, cancellationToken);
@ -50,7 +50,7 @@ internal static class Service
await ProductPolicy.ProcessArtifactsToPut(files, configurationJson, serviceDirectory, serviceUri, putRestResource, logger, cancellationToken);
await ProductGroup.ProcessArtifactsToPut(files, configurationJson, serviceDirectory, serviceUri, listRestResources, putRestResource, deleteRestResource, logger, cancellationToken);
await ProductTag.ProcessArtifactsToPut(files, configurationJson, serviceDirectory, serviceUri, listRestResources, putRestResource, deleteRestResource, logger, cancellationToken);
await Api.ProcessArtifactsToPut(files, configurationJson, serviceDirectory, serviceUri, putRestResource, logger, cancellationToken);
await Api.ProcessArtifactsToPut(files, configurationJson, serviceDirectory, serviceUri, getRestResource, putRestResource, logger, cancellationToken);
await ApiPolicy.ProcessArtifactsToPut(files, configurationJson, serviceDirectory, serviceUri, putRestResource, logger, cancellationToken);
await ApiDiagnostic.ProcessArtifactsToPut(files, configurationJson, serviceDirectory, serviceUri, putRestResource, logger, cancellationToken);
await ApiTag.ProcessArtifactsToPut(files, configurationJson, serviceDirectory, serviceUri, listRestResources, putRestResource, deleteRestResource, logger, cancellationToken);