Skip to content

Commit

Permalink
[IDP-1484] Add logging and retry for swagger OpenAPI spec generation (#…
Browse files Browse the repository at this point in the history
…55)

* [IDP-1484] Add logging and retry for swagger OpenAPI spec generation

* remove comment

* Remove other comments

* Retry twice for a total of 3 executions

* Adjusting retry

* Address retry logic and use shorter cancellationtoken

* break instead of using extra bool
  • Loading branch information
heqianwang authored May 24, 2024
1 parent d253628 commit 3b1d59a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 14 deletions.
3 changes: 3 additions & 0 deletions src/Workleap.OpenApi.MSBuild/GenerateContractProcess.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Microsoft.Build.Framework;

namespace Workleap.OpenApi.MSBuild;

/// <summary>
Expand Down Expand Up @@ -70,5 +72,6 @@ private async Task InstallDependencies(
}

await Task.WhenAll(installationTasks);
this._loggerWrapper.LogMessage("Finished installing OpenAPI dependencies.", MessageImportance.High);
}
}
44 changes: 30 additions & 14 deletions src/Workleap.OpenApi.MSBuild/SwaggerManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Workleap.OpenApi.MSBuild;
internal sealed class SwaggerManager : ISwaggerManager
{
private const string SwaggerVersion = "6.5.0";
private const int MaxRetryCount = 3;
private readonly IProcessWrapper _processWrapper;
private readonly ILoggerWrapper _loggerWrapper;
private readonly string _openApiWebApiAssemblyPath;
Expand Down Expand Up @@ -46,43 +47,58 @@ public async Task InstallSwaggerCliAsync(CancellationToken cancellationToken)
return;
}

var retryCount = 0;
while (retryCount < 2)
for (var retryCount = 0; retryCount < MaxRetryCount; retryCount++)
{
var result = await this._processWrapper.RunProcessAsync(
"dotnet",
["tool", "update", "Swashbuckle.AspNetCore.Cli", "--ignore-failed-sources", "--tool-path", this._swaggerDirectory, "--configfile", Path.Combine(this._openApiToolsDirectoryPath, "nuget.config"), "--version", SwaggerVersion],
cancellationToken);

if (result.ExitCode != 0 && retryCount != 1)
var isLastRetry = retryCount == MaxRetryCount - 1;
if (result.ExitCode != 0)
{
if (isLastRetry)
{
throw new OpenApiTaskFailedException("Swashbuckle CLI could not be installed.");
}

this._loggerWrapper.LogMessage(result.StandardOutput, MessageImportance.High);
this._loggerWrapper.LogWarning(result.StandardError);
this._loggerWrapper.LogWarning("Swashbuckle download failed. Retrying once more...");

retryCount++;
continue;
}

if (retryCount == 1 && result.ExitCode != 0)
{
throw new OpenApiTaskFailedException("Swashbuckle CLI could not be installed.");
}

break;
}
}

public async Task<string> GenerateOpenApiSpecAsync(string swaggerExePath, string outputOpenApiSpecPath, string documentName, CancellationToken cancellationToken)
{
var envVars = new Dictionary<string, string?>() { { "DOTNET_ROLL_FORWARD", "LatestMajor" } };
var result = await this._processWrapper.RunProcessAsync(swaggerExePath, ["tofile", "--output", outputOpenApiSpecPath, "--yaml", this._openApiWebApiAssemblyPath, documentName], cancellationToken: cancellationToken, envVars: envVars);
this._loggerWrapper.LogMessage(result.StandardOutput, MessageImportance.High);
var swaggerCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
swaggerCancellationToken.CancelAfter(TimeSpan.FromMinutes(1));

if (result.ExitCode != 0)
var willRetry = true;
for (var retryCount = 0; retryCount < MaxRetryCount; retryCount++)
{
this._loggerWrapper.LogWarning(result.StandardError);
throw new OpenApiTaskFailedException($"OpenApi file {outputOpenApiSpecPath} could not be created.");
var result = await this._processWrapper.RunProcessAsync(swaggerExePath, ["tofile", "--output", outputOpenApiSpecPath, "--yaml", this._openApiWebApiAssemblyPath, documentName], cancellationToken: swaggerCancellationToken.Token, envVars: envVars);

var isLastRetry = retryCount == MaxRetryCount - 1;
if (result.ExitCode != 0)
{
if (isLastRetry)
{
throw new OpenApiTaskFailedException($"OpenApi file for {outputOpenApiSpecPath} could not be generated.");
}

this._loggerWrapper.LogMessage(result.StandardOutput, MessageImportance.High);
this._loggerWrapper.LogWarning(result.StandardError);
this._loggerWrapper.LogWarning($"OpenAPI spec generation failed for {outputOpenApiSpecPath}. Retrying again...");
continue;
}

break;
}

return outputOpenApiSpecPath;
Expand Down

0 comments on commit 3b1d59a

Please sign in to comment.