Skip to content
This repository was archived by the owner on Feb 23, 2024. It is now read-only.

Commit 834617a

Browse files
GRichards05Gareth Richards
andauthored
Added support for when extracting single API to only extract backends used by the API (#556)
Co-authored-by: Gareth Richards <G2958@uniper.energy>
1 parent 18af6e2 commit 834617a

File tree

3 files changed

+92
-59
lines changed

3 files changed

+92
-59
lines changed

src/APIM_ARMTemplate/apimtemplate/Extractor/EntityExtractors/BackendExtractor.cs

Lines changed: 49 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -84,58 +84,61 @@ public async Task<Tuple<Template,Dictionary<string,BackendApiParameters> > > Gen
8484
backendTemplateResource.name = $"[concat(parameters('{ParameterNames.ApimServiceName}'), '/{backendName}')]";
8585
backendTemplateResource.apiVersion = GlobalConstants.APIVersion;
8686

87-
if(exc.paramBackend)
87+
bool includeBackend = false;
88+
////only extract the backend if this is a full extraction, or in the case of a single api, if it is referenced by one of the policies
89+
if (singleApiName == null)
90+
{
91+
// if the user is extracting all apis, extract all the backends
92+
includeBackend = true;
93+
}
94+
else
8895
{
89-
var apiToken = new BackendApiParameters();
90-
string validApiParamName = ExtractorUtils.GenValidParamName(backendName, ParameterPrefix.Diagnostic).ToLower();
91-
92-
93-
if (!string.IsNullOrEmpty(backendTemplateResource.properties.resourceId))
96+
// check extracted policies to see if the backend is referenced.
97+
foreach (PolicyTemplateResource policyTemplateResource in policyResources)
9498
{
95-
apiToken.resourceId = backendTemplateResource.properties.resourceId;
96-
backendTemplateResource.properties.resourceId = $"[parameters('{ParameterNames.BackendSettings}').{validApiParamName}.resourceId]";
97-
}
99+
string policyContent = ExtractorUtils.GetPolicyContent(exc, policyTemplateResource);
98100

99-
if (!string.IsNullOrEmpty(backendTemplateResource.properties.url))
100-
{
101-
apiToken.url = backendTemplateResource.properties.url;
102-
backendTemplateResource.properties.url = $"[parameters('{ParameterNames.BackendSettings}').{validApiParamName}.url]";
101+
if (DoesPolicyReferenceBackend(policyContent, namedValueResources, backendName, backendTemplateResource))
102+
{
103+
// backend was used in policy, extract it
104+
includeBackend = true;
105+
106+
// dont need to go through all policies if the back end has already been found
107+
break;
108+
}
103109
}
110+
}
104111

105-
if (!string.IsNullOrEmpty(backendTemplateResource.properties.protocol))
112+
if (includeBackend)
113+
{
114+
if (exc.paramBackend)
106115
{
107-
apiToken.protocol = backendTemplateResource.properties.protocol;
108-
backendTemplateResource.properties.protocol = $"[parameters('{ParameterNames.BackendSettings}').{validApiParamName}.protocol]";
116+
var apiToken = new BackendApiParameters();
117+
string validApiParamName = ExtractorUtils.GenValidParamName(backendName, ParameterPrefix.Diagnostic).ToLower();
118+
119+
if (!string.IsNullOrEmpty(backendTemplateResource.properties.resourceId))
120+
{
121+
apiToken.resourceId = backendTemplateResource.properties.resourceId;
122+
backendTemplateResource.properties.resourceId = $"[parameters('{ParameterNames.BackendSettings}').{validApiParamName}.resourceId]";
123+
}
124+
125+
if (!string.IsNullOrEmpty(backendTemplateResource.properties.url))
126+
{
127+
apiToken.url = backendTemplateResource.properties.url;
128+
backendTemplateResource.properties.url = $"[parameters('{ParameterNames.BackendSettings}').{validApiParamName}.url]";
129+
}
130+
131+
if (!string.IsNullOrEmpty(backendTemplateResource.properties.protocol))
132+
{
133+
apiToken.protocol = backendTemplateResource.properties.protocol;
134+
backendTemplateResource.properties.protocol = $"[parameters('{ParameterNames.BackendSettings}').{validApiParamName}.protocol]";
135+
}
136+
oBackendParameters.Add(validApiParamName, apiToken);
109137
}
110-
oBackendParameters.Add(validApiParamName, apiToken);
111-
}
112138

113-
////only extract the backend if this is a full extraction, or in the case of a single api, if it is referenced by one of the policies
114-
//if (singleApiName == null)
115-
//{
116-
// // if the user is extracting all apis, extract all the backends
117-
// Console.WriteLine("'{0}' Backend found", backendName);
118-
// templateResources.Add(backendTemplateResource);
119-
//}
120-
//else
121-
//{
122-
// bool isReferencedInPolicy = false;
123-
// foreach (PolicyTemplateResource policyTemplateResource in policyResources)
124-
// {
125-
// // the backend is used in a policy if the xml contains a set-backend-service policy, which will reference the backend's url or id
126-
// string policyContent = policyTemplateResource.properties.policyContent;
127-
// isReferencedInPolicy = DoesPolicyReferenceBackend(policyContent, namedValueResources, backendName, backendTemplateResource);
128-
// }
129-
// if (isReferencedInPolicy == true)
130-
// {
131-
// // backend was used in policy, extract it
132-
// Console.WriteLine("'{0}' Backend found", backendName);
133-
// templateResources.Add(backendTemplateResource);
134-
// }
135-
//}
136-
137-
Console.WriteLine("'{0}' Backend found", backendName);
138-
templateResources.Add(backendTemplateResource);
139+
Console.WriteLine("'{0}' Backend found", backendName);
140+
templateResources.Add(backendTemplateResource);
141+
}
139142
}
140143

141144
skipNumberOfBackends += GlobalConstants.NumOfRecords;
@@ -159,7 +162,8 @@ public bool DoesPolicyReferenceBackend(string policyContent, IEnumerable<Templat
159162
}
160163
foreach (PropertyTemplateResource namedValueResource in namedValueResourcesUsedByBackend)
161164
{
162-
if (policyContent.Contains(namedValueResource.properties.displayName) || policyContent.Contains(namedValueResource.properties.value))
165+
if ((namedValueResource.properties.displayName != null && policyContent.Contains(namedValueResource.properties.displayName)) ||
166+
(namedValueResource.properties.value != null && policyContent.Contains(namedValueResource.properties.value)))
163167
{
164168
return true;
165169
}

src/APIM_ARMTemplate/apimtemplate/Extractor/EntityExtractors/EntityExtractor.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public class EntityExtractor
1414
public static string baseUrl = "https://management.azure.com";
1515
internal Authentication auth = new Authentication();
1616
private static readonly IMemoryCache _cache = new MemoryCache(new MemoryCacheOptions());
17+
private static HttpClient httpClient = new HttpClient();
1718

1819
public static async Task<string> CallApiManagementAsync(string azToken, string requestUrl)
1920
{
@@ -22,21 +23,18 @@ public static async Task<string> CallApiManagementAsync(string azToken, string r
2223
return cachedResponseBody;
2324
}
2425

25-
using (HttpClient httpClient = new HttpClient())
26-
{
27-
var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
26+
var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
2827

29-
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", azToken);
28+
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", azToken);
3029

31-
HttpResponseMessage response = await httpClient.SendAsync(request);
30+
HttpResponseMessage response = await httpClient.SendAsync(request);
3231

33-
response.EnsureSuccessStatusCode();
34-
string responseBody = await response.Content.ReadAsStringAsync();
32+
response.EnsureSuccessStatusCode();
33+
string responseBody = await response.Content.ReadAsStringAsync();
3534

36-
_cache.Set(requestUrl, responseBody);
35+
_cache.Set(requestUrl, responseBody);
3736

38-
return responseBody;
39-
}
37+
return responseBody;
4038
}
4139

4240
public Template GenerateEmptyTemplate()

src/APIM_ARMTemplate/apimtemplate/Extractor/Utilities/ExtractorUtils.cs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1-
using System.Collections.Generic;
1+
using apimtemplate.Common.TemplateModels;
22
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common;
3+
using Microsoft.Extensions.Caching.Memory;
4+
using Newtonsoft.Json.Linq;
35
using System;
6+
using System.Collections.Generic;
7+
using System.IO;
48
using System.Linq;
5-
using Newtonsoft.Json.Linq;
6-
using System.Threading.Tasks;
79
using System.Text.RegularExpressions;
8-
using apimtemplate.Common.TemplateModels;
10+
using System.Threading.Tasks;
911

1012
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates.Extract
1113
{
1214
static class ExtractorUtils
1315
{
16+
private static readonly IMemoryCache _policyCache = new MemoryCache(new MemoryCacheOptions());
17+
1418
public static List<TemplateResource> removeResourceType(string resourceType, List<TemplateResource> resources)
1519
{
1620
List<TemplateResource> newResourcesList = new List<TemplateResource>();
@@ -400,6 +404,33 @@ public static async Task<Dictionary<string, object>> GetAllReferencedLoggers(Lis
400404
}
401405

402406
return ApiLoggerId;
407+
}
408+
409+
public static string GetPolicyContent(Extractor exc, PolicyTemplateResource policyTemplateResource)
410+
{
411+
// the backend is used in a policy if the xml contains a set-backend-service policy, which will reference the backend's url or id
412+
string policyContent = policyTemplateResource.properties.value;
413+
414+
// check if this is a file or is it the raw policy content
415+
if (policyContent.Contains(".xml"))
416+
{
417+
var key = policyContent;
418+
//check cache
419+
if (_policyCache.TryGetValue(key, out string content))
420+
return content;
421+
422+
var filename = policyContent.Split(',')[1].Replace("'", string.Empty).Trim();
423+
var policyFolder = $@"{exc.fileFolder}/policies";
424+
var filepath = $@"{Directory.GetCurrentDirectory()}/{policyFolder}/{filename}";
425+
426+
if (File.Exists(filepath))
427+
{
428+
policyContent = File.ReadAllText(filepath);
429+
_policyCache.Set(key, policyContent);
430+
}
431+
}
432+
433+
return policyContent;
403434
}
404435
}
405436
}

0 commit comments

Comments
 (0)