Skip to content

Commit 2f9d7ee

Browse files
committed
refactor MSGraphDbUtils to use with DI
1 parent dd4ebb0 commit 2f9d7ee

File tree

4 files changed

+64
-48
lines changed

4 files changed

+64
-48
lines changed

DevProxy.Abstractions/Utils/MSGraphDbUtils.cs

Lines changed: 52 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@
99

1010
namespace DevProxy.Abstractions.Utils;
1111

12-
public static class MSGraphDbUtils
12+
public sealed class MSGraphDbUtils(HttpClient httpClient, ILogger<MSGraphDbUtils> logger) : IDisposable
1313
{
14-
private static readonly Dictionary<string, OpenApiDocument> _openApiDocuments = [];
1514
private static readonly string[] graphVersions = ["v1.0", "beta"];
16-
17-
private static SqliteConnection? _msGraphDbConnection;
15+
private readonly Dictionary<string, OpenApiDocument> _openApiDocuments = [];
16+
private readonly HttpClient _httpClient = httpClient;
17+
private readonly ILogger<MSGraphDbUtils> _logger = logger;
18+
private SqliteConnection? _msGraphDbConnection;
1819

1920
// v1 refers to v1 of the db schema, not the graph version
2021
public static string MSGraphDbFilePath => Path.Combine(ProxyUtils.AppFolder!, "msgraph-openapi-v1.db");
2122

22-
public static SqliteConnection MSGraphDbConnection
23+
public SqliteConnection MSGraphDbConnection
2324
{
2425
get
2526
{
@@ -33,12 +34,12 @@ public static SqliteConnection MSGraphDbConnection
3334
}
3435
}
3536

36-
public static async Task<int> GenerateMSGraphDbAsync(ILogger logger, bool skipIfUpdatedToday, CancellationToken cancellationToken)
37+
public async Task<int> GenerateMSGraphDbAsync(bool skipIfUpdatedToday, CancellationToken cancellationToken)
3738
{
3839
var appFolder = ProxyUtils.AppFolder;
3940
if (string.IsNullOrEmpty(appFolder))
4041
{
41-
logger.LogError("App folder {AppFolder} not found", appFolder);
42+
_logger.LogError("App folder {AppFolder} not found", appFolder);
4243
return 1;
4344
}
4445

@@ -48,61 +49,64 @@ public static async Task<int> GenerateMSGraphDbAsync(ILogger logger, bool skipIf
4849
var modifiedToday = dbFileInfo.Exists && dbFileInfo.LastWriteTime.Date == DateTime.Now.Date;
4950
if (modifiedToday && skipIfUpdatedToday)
5051
{
51-
logger.LogInformation("Microsoft Graph database already updated today");
52+
_logger.LogInformation("Microsoft Graph database already updated today");
5253
return 1;
5354
}
5455

55-
await UpdateOpenAPIGraphFilesIfNecessaryAsync(appFolder, logger, cancellationToken);
56-
await LoadOpenAPIFilesAsync(appFolder, logger, cancellationToken);
56+
await UpdateOpenAPIGraphFilesIfNecessaryAsync(appFolder, cancellationToken);
57+
await LoadOpenAPIFilesAsync(appFolder, cancellationToken);
5758
if (_openApiDocuments.Count < 1)
5859
{
59-
logger.LogDebug("No OpenAPI files found or couldn't load them");
60+
_logger.LogDebug("No OpenAPI files found or couldn't load them");
6061
return 1;
6162
}
6263

63-
var dbConnection = MSGraphDbConnection;
64-
await CreateDbAsync(dbConnection, logger, cancellationToken);
65-
await FillDataAsync(dbConnection, logger, cancellationToken);
64+
await CreateDbAsync(cancellationToken);
65+
await FillDataAsync(cancellationToken);
6666

67-
logger.LogInformation("Microsoft Graph database successfully updated");
67+
_logger.LogInformation("Microsoft Graph database successfully updated");
6868

6969
return 0;
7070
}
7171
catch (Exception ex)
7272
{
73-
logger.LogError(ex, "Error generating Microsoft Graph database");
73+
_logger.LogError(ex, "Error generating Microsoft Graph database");
7474
return 1;
7575
}
7676

7777
}
7878

7979
private static string GetGraphOpenApiYamlFileName(string version) => $"graph-{version.Replace(".", "_", StringComparison.OrdinalIgnoreCase)}-openapi.yaml";
8080

81-
private static async Task CreateDbAsync(SqliteConnection dbConnection, ILogger logger, CancellationToken cancellationToken)
81+
private async Task CreateDbAsync(CancellationToken cancellationToken)
8282
{
83-
logger.LogInformation("Creating database...");
83+
_logger.LogInformation("Creating database...");
84+
85+
var dbConnection = MSGraphDbConnection;
8486

85-
logger.LogDebug("Dropping endpoints table...");
87+
_logger.LogDebug("Dropping endpoints table...");
8688
var dropTable = dbConnection.CreateCommand();
8789
dropTable.CommandText = "DROP TABLE IF EXISTS endpoints";
8890
_ = await dropTable.ExecuteNonQueryAsync(cancellationToken);
8991

90-
logger.LogDebug("Creating endpoints table...");
92+
_logger.LogDebug("Creating endpoints table...");
9193
var createTable = dbConnection.CreateCommand();
9294
// when you change the schema, increase the db version number in ProxyUtils
9395
createTable.CommandText = "CREATE TABLE IF NOT EXISTS endpoints (path TEXT, graphVersion TEXT, hasSelect BOOLEAN)";
9496
_ = await createTable.ExecuteNonQueryAsync(cancellationToken);
9597

96-
logger.LogDebug("Creating index on endpoints and version...");
98+
_logger.LogDebug("Creating index on endpoints and version...");
9799
// Add an index on the path and graphVersion columns
98100
var createIndex = dbConnection.CreateCommand();
99101
createIndex.CommandText = "CREATE INDEX IF NOT EXISTS idx_endpoints_path_version ON endpoints (path, graphVersion)";
100102
_ = await createIndex.ExecuteNonQueryAsync(cancellationToken);
101103
}
102104

103-
private static async Task FillDataAsync(SqliteConnection dbConnection, ILogger logger, CancellationToken cancellationToken)
105+
private async Task FillDataAsync(CancellationToken cancellationToken)
104106
{
105-
logger.LogInformation("Filling database...");
107+
_logger.LogInformation("Filling database...");
108+
109+
var dbConnection = MSGraphDbConnection;
106110

107111
var i = 0;
108112

@@ -113,7 +117,7 @@ private static async Task FillDataAsync(SqliteConnection dbConnection, ILogger l
113117
var graphVersion = openApiDocument.Key;
114118
var document = openApiDocument.Value;
115119

116-
logger.LogDebug("Filling database for {GraphVersion}...", graphVersion);
120+
_logger.LogDebug("Filling database for {GraphVersion}...", graphVersion);
117121

118122
var insertEndpoint = dbConnection.CreateCommand();
119123
insertEndpoint.CommandText = "INSERT INTO endpoints (path, graphVersion, hasSelect) VALUES (@path, @graphVersion, @hasSelect)";
@@ -125,20 +129,20 @@ private static async Task FillDataAsync(SqliteConnection dbConnection, ILogger l
125129
{
126130
cancellationToken.ThrowIfCancellationRequested();
127131

128-
logger.LogTrace("Endpoint {GraphVersion}{Key}...", graphVersion, path.Key);
132+
_logger.LogTrace("Endpoint {GraphVersion}{Key}...", graphVersion, path.Key);
129133

130134
// Get the GET operation for this path
131135
var getOperation = path.Value.Operations.FirstOrDefault(o => o.Key == OperationType.Get).Value;
132136
if (getOperation == null)
133137
{
134-
logger.LogTrace("No GET operation found for {GraphVersion}{Key}", graphVersion, path.Key);
138+
_logger.LogTrace("No GET operation found for {GraphVersion}{Key}", graphVersion, path.Key);
135139
continue;
136140
}
137141

138142
// Check if the GET operation has a $select parameter
139143
var hasSelect = getOperation.Parameters.Any(p => p.Name == "$select");
140144

141-
logger.LogTrace("Inserting endpoint {GraphVersion}{Key} with hasSelect={HasSelect}...", graphVersion, path.Key, hasSelect);
145+
_logger.LogTrace("Inserting endpoint {GraphVersion}{Key} with hasSelect={HasSelect}...", graphVersion, path.Key, hasSelect);
142146
insertEndpoint.Parameters["@path"].Value = path.Key;
143147
insertEndpoint.Parameters["@graphVersion"].Value = graphVersion;
144148
insertEndpoint.Parameters["@hasSelect"].Value = hasSelect;
@@ -147,54 +151,53 @@ private static async Task FillDataAsync(SqliteConnection dbConnection, ILogger l
147151
}
148152
}
149153

150-
logger.LogInformation("Inserted {EndpointCount} endpoints in the database", i);
154+
_logger.LogInformation("Inserted {EndpointCount} endpoints in the database", i);
151155
}
152156

153-
private static async Task UpdateOpenAPIGraphFilesIfNecessaryAsync(string folder, ILogger logger, CancellationToken cancellationToken)
157+
private async Task UpdateOpenAPIGraphFilesIfNecessaryAsync(string folder, CancellationToken cancellationToken)
154158
{
155-
logger.LogInformation("Checking for updated OpenAPI files...");
159+
_logger.LogInformation("Checking for updated OpenAPI files...");
156160

157161
foreach (var version in graphVersions)
158162
{
159163
try
160164
{
161165
var file = new FileInfo(Path.Combine(folder, GetGraphOpenApiYamlFileName(version)));
162-
logger.LogDebug("Checking for updated OpenAPI file {File}...", file);
166+
_logger.LogDebug("Checking for updated OpenAPI file {File}...", file);
163167
if (file.Exists && file.LastWriteTime.Date == DateTime.Now.Date)
164168
{
165-
logger.LogInformation("File {File} already updated today", file);
169+
_logger.LogInformation("File {File} already updated today", file);
166170
continue;
167171
}
168172

169173
var url = $"https://raw.githubusercontent.com/microsoftgraph/msgraph-metadata/master/openapi/{version}/openapi.yaml";
170-
logger.LogInformation("Downloading OpenAPI file from {Url}...", url);
174+
_logger.LogInformation("Downloading OpenAPI file from {Url}...", url);
171175

172-
using var client = new HttpClient();
173-
var response = await client.GetStringAsync(url, cancellationToken);
176+
var response = await _httpClient.GetStringAsync(url, cancellationToken);
174177
await File.WriteAllTextAsync(file.FullName, response, cancellationToken);
175178

176-
logger.LogDebug("Downloaded OpenAPI file from {Url} to {File}", url, file);
179+
_logger.LogDebug("Downloaded OpenAPI file from {Url} to {File}", url, file);
177180
}
178181
catch (Exception ex)
179182
{
180-
logger.LogError(ex, "Error updating OpenAPI files");
183+
_logger.LogError(ex, "Error updating OpenAPI files");
181184
}
182185
}
183186
}
184187

185-
private static async Task LoadOpenAPIFilesAsync(string folder, ILogger logger, CancellationToken cancellationToken)
188+
private async Task LoadOpenAPIFilesAsync(string folder, CancellationToken cancellationToken)
186189
{
187-
logger.LogInformation("Loading OpenAPI files...");
190+
_logger.LogInformation("Loading OpenAPI files...");
188191

189192
foreach (var version in graphVersions)
190193
{
191194
var filePath = Path.Combine(folder, GetGraphOpenApiYamlFileName(version));
192195
var file = new FileInfo(filePath);
193-
logger.LogDebug("Loading OpenAPI file for {FilePath}...", filePath);
196+
_logger.LogDebug("Loading OpenAPI file for {FilePath}...", filePath);
194197

195198
if (!file.Exists)
196199
{
197-
logger.LogDebug("File {FilePath} does not exist", filePath);
200+
_logger.LogDebug("File {FilePath} does not exist", filePath);
198201
continue;
199202
}
200203

@@ -203,12 +206,18 @@ private static async Task LoadOpenAPIFilesAsync(string folder, ILogger logger, C
203206
var openApiDocument = await new OpenApiStreamReader().ReadAsync(file.OpenRead(), cancellationToken);
204207
_openApiDocuments[version] = openApiDocument.OpenApiDocument;
205208

206-
logger.LogDebug("Added OpenAPI file {FilePath} for {Version}", filePath, version);
209+
_logger.LogDebug("Added OpenAPI file {FilePath} for {Version}", filePath, version);
207210
}
208211
catch (Exception ex)
209212
{
210-
logger.LogError(ex, "Error loading OpenAPI file {FilePath}", filePath);
213+
_logger.LogError(ex, "Error loading OpenAPI file {FilePath}", filePath);
211214
}
212215
}
213216
}
217+
218+
public void Dispose()
219+
{
220+
_msGraphDbConnection?.Dispose();
221+
_httpClient?.Dispose();
222+
}
214223
}

DevProxy.Plugins/Guidance/GraphSelectGuidancePlugin.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,19 @@ namespace DevProxy.Plugins.Guidance;
1313

1414
public sealed class GraphSelectGuidancePlugin(
1515
ILogger<GraphSelectGuidancePlugin> logger,
16-
ISet<UrlToWatch> urlsToWatch) : BasePlugin(logger, urlsToWatch)
16+
ISet<UrlToWatch> urlsToWatch,
17+
MSGraphDbUtils msGraphDbUtils) : BasePlugin(logger, urlsToWatch)
1718
{
19+
private readonly MSGraphDbUtils _msGraphDbUtils = msGraphDbUtils;
20+
1821
public override string Name => nameof(GraphSelectGuidancePlugin);
1922

2023
public override async Task InitializeAsync(InitArgs e, CancellationToken cancellationToken)
2124
{
2225
await base.InitializeAsync(e, cancellationToken);
2326

2427
// let's not await so that it doesn't block the proxy startup
25-
_ = MSGraphDbUtils.GenerateMSGraphDbAsync(Logger, true, cancellationToken);
28+
_ = _msGraphDbUtils.GenerateMSGraphDbAsync(true, cancellationToken);
2629
}
2730

2831
public override Task AfterResponseAsync(ProxyResponseArgs e, CancellationToken cancellationToken)
@@ -82,7 +85,7 @@ private bool EndpointSupportsSelect(string graphVersion, string relativeUrl)
8285

8386
try
8487
{
85-
var dbConnection = MSGraphDbUtils.MSGraphDbConnection;
88+
var dbConnection = _msGraphDbUtils.MSGraphDbConnection;
8689
// lookup information from the database
8790
var selectEndpoint = dbConnection.CreateCommand();
8891
selectEndpoint.CommandText = "SELECT hasSelect FROM endpoints WHERE path = @path AND graphVersion = @graphVersion";

DevProxy/Commands/MsGraphDbCommand.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ namespace DevProxy.Commands;
1010
sealed class MsGraphDbCommand : Command
1111
{
1212
private readonly ILogger _logger;
13+
private readonly MSGraphDbUtils _msGraphDbUtils;
1314

14-
public MsGraphDbCommand(ILogger<MsGraphDbCommand> logger) :
15+
public MsGraphDbCommand(ILogger<MsGraphDbCommand> logger, MSGraphDbUtils msGraphDbUtils) :
1516
base("msgraphdb", "Generate a local SQLite database with Microsoft Graph API metadata")
1617
{
1718
_logger = logger;
19+
_msGraphDbUtils = msGraphDbUtils;
1820
ConfigureCommand();
1921
}
2022

@@ -25,6 +27,6 @@ private void ConfigureCommand()
2527

2628
private async Task GenerateMsGraphDbAsync(ParseResult parseResult, CancellationToken cancellationToken)
2729
{
28-
_ = await MSGraphDbUtils.GenerateMSGraphDbAsync(_logger, false, cancellationToken);
30+
_ = await _msGraphDbUtils.GenerateMSGraphDbAsync(false, cancellationToken);
2931
}
3032
}

DevProxy/Extensions/IServiceCollectionExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using DevProxy;
66
using DevProxy.Abstractions.LanguageModel;
77
using DevProxy.Abstractions.Proxy;
8+
using DevProxy.Abstractions.Utils;
89
using DevProxy.Commands;
910
using DevProxy.Proxy;
1011

@@ -46,6 +47,7 @@ static IServiceCollection AddApplicationServices(
4647
.AddSingleton<ProxyEngine>()
4748
.AddSingleton<DevProxyCommand>()
4849
.AddSingleton<Announcement>()
50+
.AddSingleton<MSGraphDbUtils>()
4951
.AddHttpClient();
5052

5153
_ = services.AddPlugins(configuration, options);

0 commit comments

Comments
 (0)