in tools/code/extractor/Api.cs [84:186]
private static ListApis GetListApis(IServiceProvider provider)
{
var findConfigurationNamesFactory = provider.GetRequiredService<FindConfigurationNamesFactory>();
var defaultApiSpecification = provider.GetRequiredService<DefaultApiSpecification>();
var serviceUri = provider.GetRequiredService<ManagementServiceUri>();
var pipeline = provider.GetRequiredService<HttpPipeline>();
var findConfigurationApis = findConfigurationNamesFactory.Create<ApiName>();
var findConfigurationVersionSets = findConfigurationNamesFactory.Create<VersionSetName>();
return cancellationToken =>
list(cancellationToken)
.Where(api => shouldExtractApiDto(api.Dto))
.SelectAwait(async api =>
{
var (name, dto) = api;
var specificationContentsOption = await tryGetSpecificationContents(name, dto, cancellationToken);
return (name, dto, specificationContentsOption);
});
IAsyncEnumerable<(ApiName Name, ApiDto Dto)> list(CancellationToken cancellationToken) =>
findConfigurationApis()
.Map(names => listFromSet(names, cancellationToken))
.IfNone(() => listAll(cancellationToken));
IAsyncEnumerable<(ApiName, ApiDto)> listFromSet(IEnumerable<ApiName> names, CancellationToken cancellationToken) =>
names.ToAsyncEnumerable()
// Ensure API exists
.WhereAwait(async name =>
{
var uri = ApiUri.From(name, serviceUri);
var dtoOption = await uri.TryGetDto(pipeline, cancellationToken);
return dtoOption.IsSome;
})
// Get all API revisions
.SelectMany(name => listAllRevisions(name, cancellationToken));
IAsyncEnumerable<(ApiName, ApiDto)> listAllRevisions(ApiName name, CancellationToken cancellationToken)
{
var rootName = ApiName.GetRootName(name);
var rootNameUri = ApiUri.From(name, serviceUri);
var revisionsUri = rootNameUri.ToUri().AppendPathSegment("revisions").ToUri();
return pipeline.ListJsonObjects(revisionsUri, cancellationToken)
// Get name for each revision. If the revision is current, use the root name.
.Select(jsonObject =>
{
var revisionNumberInt = jsonObject.GetIntProperty("apiRevision");
var revisionNumber = ApiRevisionNumber.From(revisionNumberInt);
var isCurrent = jsonObject.GetBoolProperty("isCurrent");
return isCurrent ? name : ApiName.GetRevisionedName(rootName, revisionNumber);
})
// Get DTO for each revision
.SelectAwait(async name =>
{
var uri = ApiUri.From(name, serviceUri);
var dto = await uri.GetDto(pipeline, cancellationToken);
return (name, dto);
});
}
IAsyncEnumerable<(ApiName, ApiDto)> listAll(CancellationToken cancellationToken) =>
ApisUri.From(serviceUri)
.List(pipeline, cancellationToken);
bool shouldExtractApiDto(ApiDto dto) =>
// Don't extract if its version set should not be extracted
common.ApiModule.TryGetVersionSetName(dto)
.Map(shouldExtractVersionSet)
.IfNone(true);
bool shouldExtractVersionSet(VersionSetName name) =>
findConfigurationVersionSets()
.Map(names => names.Contains(name))
.IfNone(true);
async ValueTask<Option<(ApiSpecification, BinaryData)>> tryGetSpecificationContents(ApiName name, ApiDto dto, CancellationToken cancellationToken)
{
var specificationOption = tryGetSpecification(dto);
return await specificationOption.BindTask(async specification =>
{
var uri = ApiUri.From(name, serviceUri);
var contentsOption = await uri.TryGetSpecificationContents(specification, pipeline, cancellationToken);
return from contents in contentsOption
select (specification, contents);
});
}
Option<ApiSpecification> tryGetSpecification(ApiDto dto) =>
(dto.Properties.Type ?? dto.Properties.ApiType) switch
{
"graphql" => new ApiSpecification.GraphQl(),
"soap" => new ApiSpecification.Wsdl(),
"http" => defaultApiSpecification.Value,
null => defaultApiSpecification.Value,
_ => Option<ApiSpecification>.None
};
}