11// Copyright (c) Microsoft Corporation.
22// Licensed under the MIT License.
33
4- using System . Text . RegularExpressions ;
54using Microsoft . Extensions . Configuration ;
6- using Microsoft . OpenApi . Models ;
7- using Microsoft . OpenApi . Readers ;
85using Microsoft365 . DeveloperProxy . Abstractions ;
96using Titanium . Web . Proxy . Http ;
107
@@ -13,94 +10,17 @@ namespace Microsoft365.DeveloperProxy.Plugins.Guidance;
1310public class GraphSelectGuidancePlugin : BaseProxyPlugin
1411{
1512 public override string Name => nameof ( GraphSelectGuidancePlugin ) ;
16- private readonly Dictionary < string , OpenApiDocument > _openApiDocuments = new ( ) ;
1713
1814 public override void Register ( IPluginEvents pluginEvents ,
1915 IProxyContext context ,
2016 ISet < UrlToWatch > urlsToWatch ,
2117 IConfigurationSection ? configSection = null )
2218 {
23- var proxyFolder = Path . GetDirectoryName ( context . Configuration . ConfigFile ) ;
24- var stopwatch = new System . Diagnostics . Stopwatch ( ) ;
25- stopwatch . Start ( ) ;
26- LoadOpenAPIFiles ( proxyFolder ! ) ;
27- stopwatch . Stop ( ) ;
28- UpdateOpenAPIGraphFilesIfNecessary ( proxyFolder ! ) ;
29-
3019 base . Register ( pluginEvents , context , urlsToWatch , configSection ) ;
3120
3221 pluginEvents . AfterResponse += AfterResponse ;
3322 }
3423
35- private async Task UpdateOpenAPIGraphFilesIfNecessary ( string proxyFolder )
36- {
37- _logger ? . LogDebug ( "Checking for updated OpenAPI files..." ) ;
38-
39- var modified = false ;
40- var versions = new [ ] { "v1.0" , "beta" } ;
41- foreach ( var version in versions )
42- {
43- try
44- {
45- var file = new FileInfo ( Path . Combine ( proxyFolder , "plugins" , $ "graph-{ version . Replace ( "." , "_" ) } -openapi.yaml") ) ;
46- _logger ? . LogDebug ( $ "Checking for updated OpenAPI file for { file } ...") ;
47- if ( file . LastWriteTime . Date == DateTime . Now . Date )
48- {
49- _logger ? . LogDebug ( $ "File { file } already updated today") ;
50- // file already updated today
51- continue ;
52- }
53-
54- var url = $ "https://raw.githubusercontent.com/microsoftgraph/msgraph-metadata/master/openapi/{ version } /openapi.yaml";
55- _logger ? . LogDebug ( $ "Downloading OpenAPI file from { url } ...") ;
56-
57- var client = new HttpClient ( ) ;
58- var response = await client . GetStringAsync ( url ) ;
59- File . WriteAllText ( file . FullName , response ) ;
60-
61- _logger ? . LogDebug ( $ "Downloaded OpenAPI file from { url } to { file } ") ;
62- modified = true ;
63- }
64- catch ( Exception ex )
65- {
66- _logger ? . LogError ( ex . Message ) ;
67- }
68- }
69-
70- if ( modified )
71- {
72- LoadOpenAPIFiles ( proxyFolder ) ;
73- }
74- }
75-
76- private async void LoadOpenAPIFiles ( string proxyFolder )
77- {
78- _logger ? . LogDebug ( "Loading OpenAPI files..." ) ;
79-
80- var versions = new [ ] { "v1.0" , "beta" } ;
81- foreach ( var version in versions )
82- {
83- var file = new FileInfo ( Path . Combine ( proxyFolder , "plugins" , $ "graph-{ version . Replace ( "." , "_" ) } -openapi.yaml") ) ;
84- _logger ? . LogDebug ( $ "Loading OpenAPI file for { file } ...") ;
85-
86- if ( ! file . Exists )
87- {
88- _logger ? . LogDebug ( $ "File { file } does not exist") ;
89- continue ;
90- }
91-
92- try {
93- var openApiDocument = await new OpenApiStreamReader ( ) . ReadAsync ( file . OpenRead ( ) ) ;
94- _openApiDocuments [ version ] = openApiDocument . OpenApiDocument ;
95-
96- _logger ? . LogDebug ( $ "Added OpenAPI file { file } for { version } ") ;
97- }
98- catch ( Exception ex ) {
99- _logger ? . LogDebug ( $ "Error loading OpenAPI file { file } : { ex . Message } ") ;
100- }
101- }
102- }
103-
10424 private async Task AfterResponse ( object ? sender , ProxyResponseArgs e )
10525 {
10626 Request request = e . Session . HttpClient . Request ;
@@ -134,25 +54,23 @@ private bool EndpointSupportsSelect(string graphVersion, string relativeUrl)
13454 {
13555 var fallback = relativeUrl . Contains ( "$value" , StringComparison . OrdinalIgnoreCase ) ;
13656
137- if ( ! _openApiDocuments . ContainsKey ( graphVersion ) )
57+ try
13858 {
139- return fallback ;
59+ var dbConnection = ProxyUtils . MsGraphDbConnection ;
60+ // lookup information from the database
61+ var selectEndpoint = dbConnection . CreateCommand ( ) ;
62+ selectEndpoint . CommandText = "SELECT hasSelect FROM endpoints WHERE path = @path AND graphVersion = @graphVersion" ;
63+ selectEndpoint . Parameters . AddWithValue ( "@path" , relativeUrl ) ;
64+ selectEndpoint . Parameters . AddWithValue ( "@graphVersion" , graphVersion ) ;
65+ var result = selectEndpoint . ExecuteScalar ( ) ;
66+ var hasSelect = result != null && Convert . ToInt32 ( result ) == 1 ;
67+ return hasSelect ;
14068 }
141-
142- var relativeUrlPattern = Regex . Replace ( relativeUrl , @"{[^}]+}" , @"{[a-zA-Z-]+}" ) ;
143- var relativeUrlRegex = new Regex ( $ "^{ relativeUrlPattern } $") ;
144-
145- var openApiDocument = _openApiDocuments [ graphVersion ] ;
146- var pathString = openApiDocument . Paths . Keys . FirstOrDefault ( k => relativeUrlRegex . IsMatch ( k ) ) ;
147- if ( pathString is null ||
148- ! openApiDocument . Paths [ pathString ] . Operations . ContainsKey ( OperationType . Get ) )
69+ catch ( Exception ex )
14970 {
71+ _logger ? . LogError ( ex . Message ) ;
15072 return fallback ;
15173 }
152-
153- var operation = openApiDocument . Paths [ pathString ] . Operations [ OperationType . Get ] ;
154- var parameters = operation . Parameters ;
155- return parameters . Any ( p => p . Name == "$select" ) ;
15674 }
15775
15876 private static string GetSelectParameterGuidanceUrl ( ) => "https://aka.ms/m365/proxy/guidance/select" ;
0 commit comments