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

Commit 42c94e7

Browse files
f-alizadaFarhad Alizada
andauthored
Extract global-schema (#767)
* Add schema models, data processor, client, extractor * Add schemas to main template, add tests Co-authored-by: Farhad Alizada <falizada@microsoft.com>
1 parent bb99a62 commit 42c94e7

File tree

23 files changed

+471
-16
lines changed

23 files changed

+471
-16
lines changed

src/ArmTemplates/Commands/Executors/ExtractorExecutor.cs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Policy;
2626
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.ProductApis;
2727
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Products;
28+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Schemas;
2829
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.TagApi;
2930
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Tags;
3031
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Extractor.EntityExtractors.Abstractions;
@@ -64,6 +65,7 @@ public class ExtractorExecutor
6465
readonly IGatewayApiExtractor gatewayApiExtractor;
6566
readonly IIdentityProviderExtractor identityProviderExtractor;
6667
readonly IApiManagementServiceExtractor apiManagementServiceExtractor;
68+
readonly ISchemaExtractor schemaExtractor;
6769

6870
public ExtractorExecutor(
6971
ILogger<ExtractorExecutor> logger,
@@ -86,7 +88,8 @@ public ExtractorExecutor(
8688
IGatewayExtractor gatewayExtractor,
8789
IGatewayApiExtractor gatewayApiExtractor,
8890
IIdentityProviderExtractor identityProviderExtractor,
89-
IApiManagementServiceExtractor apiManagementServiceExtractor)
91+
IApiManagementServiceExtractor apiManagementServiceExtractor,
92+
ISchemaExtractor schemaExtractor)
9093
{
9194
this.logger = logger;
9295
this.apisClient = apisClient;
@@ -109,6 +112,7 @@ public ExtractorExecutor(
109112
this.gatewayApiExtractor = gatewayApiExtractor;
110113
this.identityProviderExtractor = identityProviderExtractor;
111114
this.apiManagementServiceExtractor = apiManagementServiceExtractor;
115+
this.schemaExtractor = schemaExtractor;
112116
}
113117

114118
/// <summary>
@@ -136,7 +140,8 @@ public static ExtractorExecutor BuildExtractorExecutor(
136140
IGatewayExtractor gatewayExtractor = null,
137141
IGatewayApiExtractor gatewayApiExtractor = null,
138142
IIdentityProviderExtractor identityProviderExtractor = null,
139-
IApiManagementServiceExtractor apiManagementServiceExtractor = null)
143+
IApiManagementServiceExtractor apiManagementServiceExtractor = null,
144+
ISchemaExtractor schemaExtractor = null)
140145
=> new ExtractorExecutor(
141146
logger,
142147
apisClient,
@@ -158,7 +163,8 @@ public static ExtractorExecutor BuildExtractorExecutor(
158163
gatewayExtractor,
159164
gatewayApiExtractor,
160165
identityProviderExtractor,
161-
apiManagementServiceExtractor);
166+
apiManagementServiceExtractor,
167+
schemaExtractor);
162168

163169
public void SetExtractorParameters(ExtractorParameters extractorParameters)
164170
{
@@ -453,7 +459,8 @@ public async Task<Template<MasterTemplateResources>> GenerateMasterTemplateAsync
453459
NamedValuesResources namedValuesTemplateResources = null,
454460
TagTemplateResources tagTemplateResources = null,
455461
GroupTemplateResources groupTemplateResources = null,
456-
IdentityProviderResources identityProviderTemplateResources = null)
462+
IdentityProviderResources identityProviderTemplateResources = null,
463+
SchemaTemplateResources schemaTemplateResources = null)
457464
{
458465
if (string.IsNullOrEmpty(this.extractorParameters.LinkedTemplatesBaseUrl))
459466
{
@@ -467,7 +474,7 @@ public async Task<Template<MasterTemplateResources>> GenerateMasterTemplateAsync
467474
this.extractorParameters, apiTemplateResources, policyTemplateResources, apiVersionSetTemplateResources,
468475
productsTemplateResources, productApisTemplateResources, apiTagsTemplateResources, loggersTemplateResources,
469476
backendsTemplateResources, authorizationServersTemplateResources, namedValuesTemplateResources, tagTemplateResources,
470-
groupTemplateResources, identityProviderTemplateResources);
477+
groupTemplateResources, identityProviderTemplateResources, schemaTemplateResources);
471478

472479
if (masterTemplate?.HasResources() == true)
473480
{
@@ -751,6 +758,29 @@ await FileWriter.SaveAsJsonAsync(
751758
return apiManagementServiceTemplate;
752759
}
753760

761+
/// <summary>
762+
/// Generates schema templates in the desired folder
763+
/// </summary>
764+
/// <param name="baseFilesGenerationDirectory">name of base folder where to save output files</param>
765+
/// <returns>generated schemas template</returns>
766+
public async Task<Template<SchemaTemplateResources>> GenerateSchemasTemplateAsync(string baseFilesGenerationDirectory)
767+
{
768+
this.logger.LogInformation("Started generation of schemas template...");
769+
770+
var schemasTemplate = await this.schemaExtractor.GenerateSchemasTemplateAsync(this.extractorParameters);
771+
772+
if (schemasTemplate?.HasResources() == true)
773+
{
774+
await FileWriter.SaveAsJsonAsync(
775+
schemasTemplate,
776+
directory: baseFilesGenerationDirectory,
777+
fileName: this.extractorParameters.FileNames.Schema);
778+
}
779+
780+
this.logger.LogInformation("Finished generation of schemas template...");
781+
return schemasTemplate;
782+
}
783+
754784
/// <summary>
755785
/// Generates split api templates / folders for each api in this sourceApim
756786
/// </summary>
@@ -931,6 +961,7 @@ async Task GenerateTemplates(
931961
var backendTemplate = await this.GenerateBackendTemplateAsync(singleApiName, apiTemplate.TypedResources.GetAllPolicies(), namedValueTemplate.TypedResources.NamedValues, baseFilesGenerationDirectory);
932962
var groupTemplate = await this.GenerateGroupsTemplateAsync(baseFilesGenerationDirectory);
933963
var identityProviderTemplate = await this.GenerateIdentityProviderTemplateAsync(baseFilesGenerationDirectory);
964+
var schemasTempate = await this.GenerateSchemasTemplateAsync(baseFilesGenerationDirectory);
934965
await this.GenerateGatewayTemplateAsync(singleApiName, baseFilesGenerationDirectory);
935966
await this.GenerateGatewayApiTemplateAsync(singleApiName, multipleApiNames, baseFilesGenerationDirectory);
936967
await this.GenerateApiManagementServiceTemplate(baseFilesGenerationDirectory);
@@ -950,7 +981,8 @@ await this.GenerateMasterTemplateAsync(
950981
namedValuesTemplateResources: namedValueTemplate.TypedResources,
951982
tagTemplateResources: tagTemplate.TypedResources,
952983
groupTemplateResources: groupTemplate.TypedResources,
953-
identityProviderTemplateResources: identityProviderTemplate.TypedResources);
984+
identityProviderTemplateResources: identityProviderTemplate.TypedResources,
985+
schemaTemplateResources: schemasTempate.TypedResources);
954986
}
955987

956988

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// --------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License.
4+
// --------------------------------------------------------------------------
5+
6+
using System.Collections.Generic;
7+
using System.Threading.Tasks;
8+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Schemas;
9+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Extractor.Models;
10+
11+
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.API.Clients.Abstractions
12+
{
13+
public interface ISchemasClient
14+
{
15+
Task<List<SchemaTemplateResource>> GetAllAsync(ExtractorParameters extractorParameters);
16+
}
17+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// --------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License.
4+
// --------------------------------------------------------------------------
5+
6+
using System.Collections.Generic;
7+
using System.Net.Http;
8+
using System.Threading.Tasks;
9+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.API.Clients.Abstractions;
10+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Constants;
11+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Schemas;
12+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Extractor.Models;
13+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Extractor.Utilities.DataProcessors.Absctraction;
14+
15+
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.API.Clients.Schemas
16+
{
17+
public class SchemasClient : ApiClientBase, ISchemasClient
18+
{
19+
const string GetAllRequest = "{0}/subscriptions/{1}/resourceGroups/{2}/providers/Microsoft.ApiManagement/service/{3}/schemas?api-version={4}";
20+
21+
readonly ISchemaDataProcessor schemaProcessor;
22+
23+
public SchemasClient(
24+
IHttpClientFactory httpClientFactory,
25+
ISchemaDataProcessor schemaDataProcessor): base(httpClientFactory)
26+
{
27+
this.schemaProcessor = schemaDataProcessor;
28+
}
29+
30+
public async Task<List<SchemaTemplateResource>> GetAllAsync(ExtractorParameters extractorParameters)
31+
{
32+
var (azToken, azSubId) = await this.Auth.GetAccessToken();
33+
34+
var requestUrl = string.Format(GetAllRequest,
35+
this.BaseUrl, azSubId, extractorParameters.ResourceGroup, extractorParameters.SourceApimName, GlobalConstants.ApiVersion);
36+
37+
var schemaTemplates = await this.GetPagedResponseAsync<SchemaTemplateResource>(azToken, requestUrl);
38+
this.schemaProcessor.ProcessData(schemaTemplates, extractorParameters);
39+
40+
return schemaTemplates;
41+
}
42+
}
43+
}

src/ArmTemplates/Common/Constants/ResourceTypeConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,6 @@ public static class ResourceTypeConstants
3636
public const string ArmDeployments = "Microsoft.Resources/deployments";
3737
public const string IdentityProviders = "Microsoft.ApiManagement/service/identityProviders";
3838
public const string ApiManagementService = "Microsoft.ApiManagement/service";
39+
public const string Schema = "Microsoft.ApiManagement/service/schemas";
3940
}
4041
}

src/ArmTemplates/Common/FileHandlers/FileNameGenerator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public static FileNames GenerateFileNames(string baseFileName)
3737
IdentityProviders = $@"{baseFileName}identity-providers.template.json",
3838
ApiManagementService = $@"{baseFileName}api-management-service.template.json",
3939
TagApi = $@"{baseFileName}apiTags.template.json",
40+
Schema = $@"{baseFileName}schemas.template.json",
4041
Parameters = $@"{baseFileName}parameters.json",
4142
LinkedMaster = $@"{baseFileName}master.template.json",
4243
Apis = "/Apis",

src/ArmTemplates/Common/FileHandlers/FileNames.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public class FileNames
3737

3838
public string ApiManagementService { get; set; }
3939

40+
public string Schema { get; set; }
41+
4042
public string Parameters { get; set; }
4143

4244
// linked property outputs 1 master template
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// --------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License.
4+
// --------------------------------------------------------------------------
5+
6+
using System;
7+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Abstractions;
8+
9+
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Schemas
10+
{
11+
public class SchemaProperties
12+
{
13+
public string Description { get; set; }
14+
15+
public string SchemaType { get; set; }
16+
17+
public string Value { get; set; }
18+
19+
public Object Document { get; set; }
20+
}
21+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// --------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License.
4+
// --------------------------------------------------------------------------
5+
6+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Abstractions;
7+
using Newtonsoft.Json;
8+
9+
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Schemas
10+
{
11+
public class SchemaTemplateResource: TemplateResource
12+
{
13+
[JsonIgnore]
14+
public string OriginalName { get; set; }
15+
16+
public SchemaProperties Properties { get; set; }
17+
}
18+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// --------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License.
4+
// --------------------------------------------------------------------------
5+
6+
using System.Collections.Generic;
7+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Extensions;
8+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Abstractions;
9+
10+
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Schemas
11+
{
12+
public class SchemaTemplateResources : ITemplateResources
13+
{
14+
public List<SchemaTemplateResource> Schemas { get; set; } = new();
15+
16+
public TemplateResource[] BuildTemplateResources()
17+
{
18+
return this.Schemas.ToArray();
19+
}
20+
21+
public bool HasContent()
22+
{
23+
return !this.Schemas.IsNullOrEmpty();
24+
}
25+
}
26+
}

src/ArmTemplates/Extractor/EntityExtractors/Abstractions/IMasterTemplateExtractor.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Policy;
1717
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.ProductApis;
1818
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Products;
19+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Schemas;
1920
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.TagApi;
2021
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Tags;
2122
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Extractor.Models;
@@ -38,6 +39,7 @@ Template<MasterTemplateResources> GenerateLinkedMasterTemplate(
3839
NamedValuesResources namedValuesTemplateResources = null,
3940
TagTemplateResources tagTemplateResources = null,
4041
GroupTemplateResources groupTemplateResources = null,
41-
IdentityProviderResources identityProviderTemplateResources = null);
42+
IdentityProviderResources identityProviderTemplateResources = null,
43+
SchemaTemplateResources schemaTemplateResources = null);
4244
}
4345
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// --------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License.
4+
// --------------------------------------------------------------------------
5+
6+
using System.Threading.Tasks;
7+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Abstractions;
8+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Schemas;
9+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Extractor.Models;
10+
11+
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates.Extractor.EntityExtractors.Abstractions
12+
{
13+
public interface ISchemaExtractor
14+
{
15+
Task<Template<SchemaTemplateResources>> GenerateSchemasTemplateAsync(ExtractorParameters extractorParameters);
16+
}
17+
}

src/ArmTemplates/Extractor/EntityExtractors/MasterTemplateExtractor.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.NamedValues;
2626
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Groups;
2727
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.IdentityProviders;
28+
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Templates.Schemas;
2829

2930
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates.Extractor.EntityExtractors
3031
{
@@ -55,7 +56,8 @@ public Template<MasterTemplateResources> GenerateLinkedMasterTemplate(
5556
NamedValuesResources namedValuesTemplateResources = null,
5657
TagTemplateResources tagTemplateResources = null,
5758
GroupTemplateResources groupTemplateResources = null,
58-
IdentityProviderResources identityProviderTemplateResources = null)
59+
IdentityProviderResources identityProviderTemplateResources = null,
60+
SchemaTemplateResources schemaTemplateResources = null)
5961
{
6062
var masterTemplate = this.templateBuilder
6163
.GenerateEmptyTemplate()
@@ -198,6 +200,18 @@ public Template<MasterTemplateResources> GenerateLinkedMasterTemplate(
198200
masterResources.DeploymentResources.Add(authorizationServersDeployment);
199201
}
200202

203+
if (schemaTemplateResources?.HasContent() == true)
204+
{
205+
this.logger.LogDebug("Adding schemas to master template");
206+
const string SchemasTemplate = "schemasTemplate";
207+
208+
apiDependsOn.Add($"[resourceId('{ResourceTypeConstants.ArmDeployments}', '{SchemasTemplate}')]");
209+
var schemasUri = this.GenerateLinkedTemplateUri(fileNames.Schema, extractorParameters);
210+
var schemasDeployment = CreateLinkedMasterTemplateResource(SchemasTemplate, schemasUri, Array.Empty<string>());
211+
212+
masterResources.DeploymentResources.Add(schemasDeployment);
213+
}
214+
201215
if (apiTemplateResources?.HasContent() == true)
202216
{
203217
this.logger.LogDebug("Adding apis to master template");

0 commit comments

Comments
 (0)