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

Commit 1caa535

Browse files
authored
Support split api templates (#266)
1 parent b1ce1f6 commit 1caa535

File tree

2 files changed

+93
-50
lines changed

2 files changed

+93
-50
lines changed

src/APIM_ARMTemplate/apimtemplate/Commands/Extract.cs

Lines changed: 88 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using System.Collections.Generic;
44
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common;
55
using System.Linq;
6+
using Newtonsoft.Json.Linq;
7+
using System.Threading.Tasks;
68

79
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates.Extract
810
{
@@ -21,6 +23,7 @@ public ExtractCommand()
2123
var linkedTemplatesBaseUrlName = this.Option("--linkedTemplatesBaseUrl <linkedTemplatesBaseUrl>", "Creates a master template with links", CommandOptionType.SingleValue);
2224
var linkedTemplatesUrlQueryString = this.Option("--linkedTemplatesUrlQueryString <linkedTemplatesUrlQueryString>", "Query string appended to linked templates uris that enables retrieval from private storage", CommandOptionType.SingleValue);
2325
var policyXMLBaseUrlName = this.Option("--policyXMLBaseUrl <policyXMLBaseUrl>", "Writes policies to local XML files that require deployment to remote folder", CommandOptionType.SingleValue);
26+
var splitAPITemplates = this.Option("--splitAPIs <splitAPIs>", "Split APIs into multiple templates", CommandOptionType.SingleValue);
2427

2528
this.HelpOption();
2629

@@ -33,11 +36,18 @@ public ExtractCommand()
3336
if (!resourceGroupName.HasValue()) throw new Exception("Missing parameter <resourceGroup>.");
3437
if (!fileFolderName.HasValue()) throw new Exception("Missing parameter <filefolder>.");
3538

39+
// check if specify "split apis" and use "single api" at the same time
40+
string splitAPIs = splitAPITemplates.HasValue() ? splitAPITemplates.Value().ToString() : null;
41+
if (splitAPIs != null && splitAPIs.Equals("true") && apiName.Values.Count > 0)
42+
{
43+
throw new Exception("Can't use splitAPIs when you extract single API");
44+
}
45+
3646
// isolate cli parameters
3747
string resourceGroup = resourceGroupName.Value().ToString();
3848
string sourceApim = sourceApimName.Value().ToString();
3949
string destinationApim = destinationAPIManagementName.Value().ToString();
40-
string fileFolder = fileFolderName.Value().ToString();
50+
string dirName = fileFolderName.Value().ToString();
4151
string linkedBaseUrl = linkedTemplatesBaseUrlName.HasValue() ? linkedTemplatesBaseUrlName.Value().ToString() : null;
4252
string linkedUrlQueryString = linkedTemplatesUrlQueryString.HasValue() ? linkedTemplatesUrlQueryString.Value().ToString() : null;
4353
string policyXMLBaseUrl = policyXMLBaseUrlName.HasValue() ? policyXMLBaseUrlName.Value().ToString() : null;
@@ -65,56 +75,31 @@ public ExtractCommand()
6575
FileNameGenerator fileNameGenerator = new FileNameGenerator();
6676
FileNames fileNames = fileNameGenerator.GenerateFileNames(sourceApim);
6777

68-
// initialize entity extractor classes
69-
APIExtractor apiExtractor = new APIExtractor(fileWriter);
70-
APIVersionSetExtractor apiVersionSetExtractor = new APIVersionSetExtractor();
71-
AuthorizationServerExtractor authorizationServerExtractor = new AuthorizationServerExtractor();
72-
BackendExtractor backendExtractor = new BackendExtractor();
73-
LoggerExtractor loggerExtractor = new LoggerExtractor();
74-
PolicyExtractor policyExtractor = new PolicyExtractor(fileWriter);
75-
PropertyExtractor propertyExtractor = new PropertyExtractor();
76-
TagExtractor tagExtractor = new TagExtractor();
77-
ProductExtractor productExtractor = new ProductExtractor(fileWriter);
78-
MasterTemplateExtractor masterTemplateExtractor = new MasterTemplateExtractor();
79-
80-
// extract templates from apim service
81-
Template globalServicePolicyTemplate = await policyExtractor.GenerateGlobalServicePolicyTemplateAsync(sourceApim, resourceGroup, policyXMLBaseUrl, fileFolder);
82-
Template apiTemplate = await apiExtractor.GenerateAPIsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, policyXMLBaseUrl, fileFolder);
83-
List<TemplateResource> apiTemplateResources = apiTemplate.resources.ToList();
84-
Template apiVersionSetTemplate = await apiVersionSetExtractor.GenerateAPIVersionSetsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
85-
Template authorizationServerTemplate = await authorizationServerExtractor.GenerateAuthorizationServersARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
86-
Template loggerTemplate = await loggerExtractor.GenerateLoggerTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
87-
Template productTemplate = await productExtractor.GenerateProductsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl, fileFolder);
88-
List<TemplateResource> productTemplateResources = productTemplate.resources.ToList();
89-
Template namedValueTemplate = await propertyExtractor.GenerateNamedValuesTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
90-
Template tagTemplate = await tagExtractor.GenerateTagsTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, productTemplateResources, policyXMLBaseUrl);
91-
List<TemplateResource> namedValueResources = namedValueTemplate.resources.ToList();
92-
Template backendTemplate = await backendExtractor.GenerateBackendsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, namedValueResources, policyXMLBaseUrl);
93-
94-
// create parameters file
95-
Template templateParameters = masterTemplateExtractor.CreateMasterTemplateParameterValues(destinationApim, linkedBaseUrl, linkedUrlQueryString, policyXMLBaseUrl);
96-
97-
// write templates to output file location
98-
string apiFileName = fileNameGenerator.GenerateExtractorAPIFileName(singleApiName, sourceApim);
99-
fileWriter.WriteJSONToFile(apiTemplate, String.Concat(@fileFolder, apiFileName));
100-
fileWriter.WriteJSONToFile(apiVersionSetTemplate, String.Concat(@fileFolder, fileNames.apiVersionSets));
101-
fileWriter.WriteJSONToFile(authorizationServerTemplate, String.Concat(@fileFolder, fileNames.authorizationServers));
102-
fileWriter.WriteJSONToFile(backendTemplate, String.Concat(@fileFolder, fileNames.backends));
103-
fileWriter.WriteJSONToFile(loggerTemplate, String.Concat(@fileFolder, fileNames.loggers));
104-
fileWriter.WriteJSONToFile(namedValueTemplate, String.Concat(@fileFolder, fileNames.namedValues));
105-
fileWriter.WriteJSONToFile(tagTemplate, String.Concat(@fileFolder, fileNames.tags));
106-
fileWriter.WriteJSONToFile(productTemplate, String.Concat(@fileFolder, fileNames.products));
107-
fileWriter.WriteJSONToFile(globalServicePolicyTemplate, String.Concat(@fileFolder, fileNames.globalServicePolicy));
108-
109-
if (linkedBaseUrl != null)
78+
// create template folder with all apis and split api templates
79+
if (splitAPIs != null && splitAPIs.Equals("true"))
11080
{
111-
// create a master template that links to all other templates
112-
Template masterTemplate = masterTemplateExtractor.GenerateLinkedMasterTemplate(apiTemplate, globalServicePolicyTemplate, apiVersionSetTemplate, productTemplate, loggerTemplate, backendTemplate, authorizationServerTemplate, namedValueTemplate, tagTemplate, fileNames, apiFileName, linkedUrlQueryString, policyXMLBaseUrl);
113-
fileWriter.WriteJSONToFile(masterTemplate, String.Concat(@fileFolder, fileNames.linkedMaster));
114-
}
81+
APIExtractor apiExtractor = new APIExtractor(fileWriter);
82+
// pull all apis from service
83+
string apis = await apiExtractor.GetAPIsAsync(sourceApim, resourceGroup);
84+
JObject oApi = JObject.Parse(apis);
85+
for (int i = 0; i < ((JContainer)oApi["value"]).Count; i++)
86+
{
87+
string apiName = ((JValue)oApi["value"][i]["name"]).Value.ToString();
88+
89+
// create folder for each API
90+
string apiFileFolder = String.Concat(@dirName, $@"/{apiName}");
91+
System.IO.Directory.CreateDirectory(apiFileFolder);
11592

116-
// write parameters to outputLocation
117-
fileWriter.WriteJSONToFile(templateParameters, String.Concat(fileFolder, fileNames.parameters));
93+
// generate templates for each API
94+
await this.GenerateTemplates(sourceApim, destinationApim, apiName, resourceGroup, policyXMLBaseUrl, apiFileFolder, linkedBaseUrl, linkedUrlQueryString, fileNameGenerator, fileNames, fileWriter);
95+
96+
Console.WriteLine($@"Finish extracting API {apiName}");
97+
}
98+
}
99+
else
100+
{
101+
await this.GenerateTemplates(sourceApim, destinationApim, singleApiName, resourceGroup, policyXMLBaseUrl, dirName, linkedBaseUrl, linkedUrlQueryString, fileNameGenerator, fileNames, fileWriter);
102+
}
118103
Console.WriteLine("Templates written to output location");
119104
Console.WriteLine("Press any key to exit process:");
120105
#if DEBUG
@@ -128,5 +113,59 @@ public ExtractCommand()
128113
}
129114
});
130115
}
116+
private async Task<Boolean> GenerateTemplates(string sourceApim, string destinationApim, string singleApiName, string resourceGroup, string policyXMLBaseUrl, string dirName, string linkedBaseUrl, string linkedUrlQueryString, FileNameGenerator fileNameGenerator, FileNames fileNames, FileWriter fileWriter)
117+
{
118+
// initialize entity extractor classes
119+
APIExtractor apiExtractor = new APIExtractor(fileWriter);
120+
APIVersionSetExtractor apiVersionSetExtractor = new APIVersionSetExtractor();
121+
AuthorizationServerExtractor authorizationServerExtractor = new AuthorizationServerExtractor();
122+
BackendExtractor backendExtractor = new BackendExtractor();
123+
LoggerExtractor loggerExtractor = new LoggerExtractor();
124+
PolicyExtractor policyExtractor = new PolicyExtractor(fileWriter);
125+
PropertyExtractor propertyExtractor = new PropertyExtractor();
126+
TagExtractor tagExtractor = new TagExtractor();
127+
ProductExtractor productExtractor = new ProductExtractor(fileWriter);
128+
MasterTemplateExtractor masterTemplateExtractor = new MasterTemplateExtractor();
129+
130+
// extract templates from apim service
131+
Template globalServicePolicyTemplate = await policyExtractor.GenerateGlobalServicePolicyTemplateAsync(sourceApim, resourceGroup, policyXMLBaseUrl, dirName);
132+
Template apiTemplate = await apiExtractor.GenerateAPIsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, policyXMLBaseUrl, dirName);
133+
List<TemplateResource> apiTemplateResources = apiTemplate.resources.ToList();
134+
Template apiVersionSetTemplate = await apiVersionSetExtractor.GenerateAPIVersionSetsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
135+
Template authorizationServerTemplate = await authorizationServerExtractor.GenerateAuthorizationServersARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
136+
Template loggerTemplate = await loggerExtractor.GenerateLoggerTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
137+
Template productTemplate = await productExtractor.GenerateProductsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl, dirName);
138+
List<TemplateResource> productTemplateResources = productTemplate.resources.ToList();
139+
Template namedValueTemplate = await propertyExtractor.GenerateNamedValuesTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
140+
Template tagTemplate = await tagExtractor.GenerateTagsTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, productTemplateResources, policyXMLBaseUrl);
141+
List<TemplateResource> namedValueResources = namedValueTemplate.resources.ToList();
142+
Template backendTemplate = await backendExtractor.GenerateBackendsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, namedValueResources, policyXMLBaseUrl);
143+
144+
// create parameters file
145+
Template templateParameters = masterTemplateExtractor.CreateMasterTemplateParameterValues(destinationApim, linkedBaseUrl, linkedUrlQueryString, policyXMLBaseUrl);
146+
147+
// write templates to output file location
148+
string apiFileName = fileNameGenerator.GenerateExtractorAPIFileName(singleApiName, sourceApim);
149+
fileWriter.WriteJSONToFile(apiTemplate, String.Concat(@dirName, apiFileName));
150+
fileWriter.WriteJSONToFile(apiVersionSetTemplate, String.Concat(@dirName, fileNames.apiVersionSets));
151+
fileWriter.WriteJSONToFile(authorizationServerTemplate, String.Concat(@dirName, fileNames.authorizationServers));
152+
fileWriter.WriteJSONToFile(backendTemplate, String.Concat(@dirName, fileNames.backends));
153+
fileWriter.WriteJSONToFile(loggerTemplate, String.Concat(@dirName, fileNames.loggers));
154+
fileWriter.WriteJSONToFile(namedValueTemplate, String.Concat(@dirName, fileNames.namedValues));
155+
fileWriter.WriteJSONToFile(tagTemplate, String.Concat(@dirName, fileNames.tags));
156+
fileWriter.WriteJSONToFile(productTemplate, String.Concat(@dirName, fileNames.products));
157+
fileWriter.WriteJSONToFile(globalServicePolicyTemplate, String.Concat(@dirName, fileNames.globalServicePolicy));
158+
159+
if (linkedBaseUrl != null)
160+
{
161+
// create a master template that links to all other templates
162+
Template masterTemplate = masterTemplateExtractor.GenerateLinkedMasterTemplate(apiTemplate, globalServicePolicyTemplate, apiVersionSetTemplate, productTemplate, loggerTemplate, backendTemplate, authorizationServerTemplate, namedValueTemplate, tagTemplate, fileNames, apiFileName, linkedUrlQueryString, policyXMLBaseUrl);
163+
fileWriter.WriteJSONToFile(masterTemplate, String.Concat(@dirName, fileNames.linkedMaster));
164+
}
165+
166+
// write parameters to outputLocation
167+
fileWriter.WriteJSONToFile(templateParameters, String.Concat(dirName, fileNames.parameters));
168+
return true;
169+
}
131170
}
132171
}

src/APIM_ARMTemplate/apimtemplate/Common/FileHandlers/FileNameGenerator.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ public FileNames GenerateFileNames(string apimServiceName)
1919
tags = $@"/{apimServiceName}-tags.template.json",
2020
products = $@"/{apimServiceName}-products.template.json",
2121
parameters = $@"/{apimServiceName}-parameters.json",
22-
linkedMaster = $@"/{apimServiceName}-master.template.json"
22+
linkedMaster = $@"/{apimServiceName}-master.template.json",
23+
apis = "/Apis",
24+
splitAPIs = "/SplitAPIs"
2325
};
2426
}
2527

@@ -63,5 +65,7 @@ public class FileNames
6365
public string parameters { get; set; }
6466
// linked property outputs 1 master template
6567
public string linkedMaster { get; set; }
68+
public string apis { get; set; }
69+
public string splitAPIs { get; set; }
6670
}
6771
}

0 commit comments

Comments
 (0)