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

Commit 9c6b584

Browse files
authored
[Extractor] Add API revisions extraction for single API && bug fixing (#289)
* [Extractor] API revision && bug fixing * [Extractor] Finish revision code
1 parent 83bd714 commit 9c6b584

File tree

6 files changed

+474
-123
lines changed

6 files changed

+474
-123
lines changed

src/APIM_ARMTemplate/apimtemplate/Commands/Extract.cs

Lines changed: 89 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,66 +22,72 @@ public ExtractCommand()
2222
// convert config file to extractorConfig class
2323
FileReader fileReader = new FileReader();
2424
ExtractorConfig extractorConfig = fileReader.ConvertConfigJsonToExtractorConfig();
25-
25+
2626
try
2727
{
2828
if (extractorConfig.sourceApimName == null) throw new Exception("Missing parameter <sourceApimName>.");
2929
if (extractorConfig.destinationApimName == null) throw new Exception("Missing parameter <destinationApimName>.");
3030
if (extractorConfig.resourceGroup == null) throw new Exception("Missing parameter <resourceGroup>.");
3131
if (extractorConfig.fileFolder == null) throw new Exception("Missing parameter <filefolder>.");
3232

33-
bool splitAPIs = extractorConfig.splitAPIs != null && extractorConfig.splitAPIs.Equals("true");
34-
string apiVersionSetName = extractorConfig.apiVersionSetName;
3533
string singleApiName = extractorConfig.apiName;
34+
bool splitAPIs = extractorConfig.splitAPIs != null && extractorConfig.splitAPIs.Equals("true");
35+
bool hasVersionSetName = extractorConfig.apiVersionSetName != null;
36+
bool hasSingleApi = singleApiName != null;
37+
bool includeRevisions = extractorConfig.includeAllRevisions != null && extractorConfig.includeAllRevisions.Equals("true");
3638

3739
// validaion check
38-
if (splitAPIs && singleApiName != null)
40+
if (splitAPIs && hasSingleApi)
3941
{
40-
throw new Exception("Can't use --splitAPIs and --apiName at same time");
42+
throw new Exception("Can't use splitAPIs and apiName at same time");
4143
}
4244

43-
if (splitAPIs && apiVersionSetName != null)
45+
if (splitAPIs && hasVersionSetName)
4446
{
45-
throw new Exception("Can't use --splitAPIs and --apiVersionSetName at same time");
47+
throw new Exception("Can't use splitAPIs and apiVersionSetName at same time");
4648
}
4749

48-
if (singleApiName != null && apiVersionSetName != null)
50+
if (hasSingleApi && hasVersionSetName)
4951
{
50-
throw new Exception("Can't use --apiName and --apiVersionSetName at same time");
52+
throw new Exception("Can't use apiName and apiVersionSetName at same time");
5153
}
5254

55+
// start running extractor
5356
Console.WriteLine("API Management Template");
54-
Console.WriteLine();
5557
Console.WriteLine("Connecting to {0} API Management Service on {1} Resource Group ...", extractorConfig.sourceApimName, extractorConfig.resourceGroup);
56-
if (singleApiName != null)
57-
{
58-
Console.WriteLine("Executing extraction for {0} API ...", singleApiName);
59-
}
60-
else
61-
{
62-
Console.WriteLine("Executing full extraction ...");
63-
}
6458

6559
// initialize file helper classes
6660
FileWriter fileWriter = new FileWriter();
6761
FileNameGenerator fileNameGenerator = new FileNameGenerator();
6862
FileNames fileNames = fileNameGenerator.GenerateFileNames(extractorConfig.sourceApimName);
6963

70-
// create template folder with all apis and split api templates
7164
if (splitAPIs)
7265
{
7366
// create split api templates for all apis in the sourceApim
7467
await this.GenerateSplitAPITemplates(extractorConfig, fileNameGenerator, fileWriter, fileNames);
7568
}
76-
else if (apiVersionSetName != null)
69+
else if (hasVersionSetName)
7770
{
7871
// create split api templates and aggregated api templates for this apiversionset
7972
await this.GenerateAPIVersionSetTemplates(extractorConfig, fileNameGenerator, fileNames, fileWriter);
8073
}
74+
else if (hasSingleApi && includeRevisions)
75+
{
76+
// handle singel API include Revision extraction
77+
await this.GenerateSingleAPIWithRevisionsTemplates(extractorConfig, singleApiName, fileNameGenerator, fileWriter, fileNames);
78+
}
8179
else
8280
{
8381
// create single api template or create aggregated api templates for all apis within the sourceApim
84-
await this.GenerateTemplates(new Extractor(extractorConfig), fileNameGenerator, fileNames, fileWriter);
82+
if (hasSingleApi)
83+
{
84+
Console.WriteLine("Executing extraction for {0} API ...", singleApiName);
85+
}
86+
else
87+
{
88+
Console.WriteLine("Executing full extraction ...");
89+
}
90+
await this.GenerateTemplates(new Extractor(extractorConfig), singleApiName, null, fileNameGenerator, fileNames, fileWriter, null);
8591
}
8692
Console.WriteLine("Templates written to output location");
8793
Console.WriteLine("Press any key to exit process:");
@@ -102,9 +108,16 @@ public ExtractCommand()
102108
2. multipleApiNams is null, then generate separate folder and master template for each API
103109
3. when both singleApiName and multipleApiNams is null, then generate one master template to link all apis in the sourceapim
104110
*/
105-
private async Task GenerateTemplates(Extractor exc, FileNameGenerator fileNameGenerator, FileNames fileNames, FileWriter fileWriter)
111+
private async Task GenerateTemplates(
112+
Extractor exc,
113+
string singleApiName,
114+
List<string> multipleAPINames,
115+
FileNameGenerator fileNameGenerator,
116+
FileNames fileNames,
117+
FileWriter fileWriter,
118+
Template apiTemplate)
106119
{
107-
if (exc.apiName != null && exc.multipleAPINames != null)
120+
if (singleApiName != null && multipleAPINames != null)
108121
{
109122
throw new Exception("can't specify single API and multiple APIs to extract at the same time");
110123
}
@@ -123,17 +136,19 @@ private async Task GenerateTemplates(Extractor exc, FileNameGenerator fileNameGe
123136
// read parameters
124137
string sourceApim = exc.sourceApimName;
125138
string resourceGroup = exc.resourceGroup;
126-
string singleApiName = exc.apiName;
127139
string destinationApim = exc.destinationApimName;
128140
string linkedBaseUrl = exc.linkedTemplatesBaseUrl;
129141
string policyXMLBaseUrl = exc.policyXMLBaseUrl;
130142
string dirName = exc.fileFolder;
131-
List<string> multipleApiNames = exc.multipleAPINames;
143+
List<string> multipleApiNames = multipleAPINames;
132144
string linkedUrlQueryString = exc.linkedTemplatesUrlQueryString;
133145

134146
// extract templates from apim service
135147
Template globalServicePolicyTemplate = await policyExtractor.GenerateGlobalServicePolicyTemplateAsync(sourceApim, resourceGroup, policyXMLBaseUrl, dirName);
136-
Template apiTemplate = await apiExtractor.GenerateAPIsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, multipleApiNames, policyXMLBaseUrl, dirName);
148+
if (apiTemplate == null)
149+
{
150+
apiTemplate = await apiExtractor.GenerateAPIsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, multipleApiNames, policyXMLBaseUrl, dirName);
151+
}
137152
List<TemplateResource> apiTemplateResources = apiTemplate.resources.ToList();
138153
Template apiVersionSetTemplate = await apiVersionSetExtractor.GenerateAPIVersionSetsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
139154
Template authorizationServerTemplate = await authorizationServerExtractor.GenerateAuthorizationServersARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
@@ -183,7 +198,11 @@ private async Task GenerateTemplates(Extractor exc, FileNameGenerator fileNameGe
183198
if (linkedBaseUrl != null)
184199
{
185200
// create a master template that links to all other templates
186-
Template masterTemplate = masterTemplateExtractor.GenerateLinkedMasterTemplate(apiTemplate, globalServicePolicyTemplate, apiVersionSetTemplate, productTemplate, loggerTemplate, backendTemplate, authorizationServerTemplate, namedValueTemplate, tagTemplate, fileNames, apiFileName, linkedUrlQueryString, policyXMLBaseUrl);
201+
Template masterTemplate = masterTemplateExtractor.GenerateLinkedMasterTemplate(
202+
apiTemplate, globalServicePolicyTemplate, apiVersionSetTemplate, productTemplate,
203+
loggerTemplate, backendTemplate, authorizationServerTemplate, namedValueTemplate,
204+
tagTemplate, fileNames, apiFileName, linkedUrlQueryString, policyXMLBaseUrl);
205+
187206
fileWriter.WriteJSONToFile(masterTemplate, String.Concat(@dirName, fileNames.linkedMaster));
188207
}
189208

@@ -207,16 +226,13 @@ public async Task GenerateAPIVersionSetTemplates(ExtractorConfig exc, FileNameGe
207226
// generate seperate folder for each API
208227
string apiFileFolder = String.Concat(@exc.fileFolder, $@"/{apiName}");
209228
System.IO.Directory.CreateDirectory(apiFileFolder);
210-
// config instance with singleApiName
211-
Extractor excConfig = new Extractor(exc, apiName, apiFileFolder);
212-
await this.GenerateTemplates(excConfig, fileNameGenerator, fileNames, fileWriter);
229+
await this.GenerateTemplates(new Extractor(exc, apiFileFolder), apiName, null, fileNameGenerator, fileNames, fileWriter, null);
213230
}
214231

215232
// create master templates for this apiVersionSet
216233
string versionSetFolder = String.Concat(@exc.fileFolder, fileNames.versionSetMasterFolder);
217234
System.IO.Directory.CreateDirectory(versionSetFolder);
218-
Extractor versionConfig = new Extractor(exc, apiDictionary[exc.apiVersionSetName], versionSetFolder);
219-
await this.GenerateTemplates(versionConfig, fileNameGenerator, fileNames, fileWriter);
235+
await this.GenerateTemplates(new Extractor(exc, versionSetFolder), null, apiDictionary[exc.apiVersionSetName], fileNameGenerator, fileNames, fileWriter, null);
220236

221237
Console.WriteLine($@"Finish extracting APIVersionSet {exc.apiVersionSetName}");
222238

@@ -247,8 +263,7 @@ public async Task GenerateSplitAPITemplates(ExtractorConfig exc, FileNameGenerat
247263
// create master templates for each apiVersionSet
248264
string versionSetFolder = String.Concat(@apiFileFolder, fileNames.versionSetMasterFolder);
249265
System.IO.Directory.CreateDirectory(versionSetFolder);
250-
Extractor masterConfig = new Extractor(exc, versionSetEntry.Value, versionSetFolder);
251-
await this.GenerateTemplates(masterConfig, fileNameGenerator, fileNames, fileWriter);
266+
await this.GenerateTemplates(new Extractor(exc, versionSetFolder), null, versionSetEntry.Value, fileNameGenerator, fileNames, fileWriter, null);
252267

253268
Console.WriteLine($@"Finish extracting APIVersionSet {versionSetEntry.Key}");
254269
}
@@ -259,15 +274,53 @@ public async Task GenerateSplitAPITemplates(ExtractorConfig exc, FileNameGenerat
259274
// create folder for each API
260275
string tempFileFolder = String.Concat(@apiFileFolder, $@"/{apiName}");
261276
System.IO.Directory.CreateDirectory(tempFileFolder);
262-
Extractor excConfig = new Extractor(exc, apiName, tempFileFolder);
263277
// generate templates for each API
264-
await this.GenerateTemplates(excConfig, fileNameGenerator, fileNames, fileWriter);
278+
await this.GenerateTemplates(new Extractor(exc, tempFileFolder), apiName, null, fileNameGenerator, fileNames, fileWriter, null);
265279

266280
Console.WriteLine($@"Finish extracting API {apiName}");
267281
}
268282
}
269283
}
270284

285+
public async Task GenerateSingleAPIWithRevisionsTemplates(ExtractorConfig exc, string apiName, FileNameGenerator fileNameGenerator, FileWriter fileWriter, FileNames fileNames)
286+
{
287+
Console.WriteLine("Extracting singleAPI {0} with revisions", apiName);
288+
289+
APIExtractor apiExtractor = new APIExtractor(fileWriter);
290+
// Get all revisions for this api
291+
string revisions = await apiExtractor.GetAPIRevisionsAsync(exc.sourceApimName, exc.resourceGroup, apiName);
292+
JObject revs = JObject.Parse(revisions);
293+
string currentRevision = null;
294+
List<string> revList = new List<string>();
295+
296+
// Generate seperate folder for each API revision
297+
for (int i = 0; i < ((JContainer)revs["value"]).Count; i++)
298+
{
299+
string apiID = ((JValue)revs["value"][i]["apiId"]).Value.ToString();
300+
string singleApiName = apiID.Split("/")[2];
301+
if (((JValue)revs["value"][i]["isCurrent"]).Value.ToString().Equals("True"))
302+
{
303+
currentRevision = singleApiName;
304+
}
305+
306+
string revFileFolder = String.Concat(@exc.fileFolder, $@"/{singleApiName}");
307+
System.IO.Directory.CreateDirectory(revFileFolder);
308+
await this.GenerateTemplates(new Extractor(exc, revFileFolder), singleApiName, null, fileNameGenerator, fileNames, fileWriter, null);
309+
revList.Add(singleApiName);
310+
}
311+
312+
if (currentRevision == null)
313+
{
314+
throw new Exception($"Revision {apiName} doesn't exist, something went wrong!");
315+
}
316+
// generate revisions master folder
317+
string revMasterFolder = String.Concat(@exc.fileFolder, fileNames.revisionMasterFolder);
318+
System.IO.Directory.CreateDirectory(revMasterFolder);
319+
Extractor revExc = new Extractor(exc, revMasterFolder);
320+
Template apiRevisionTemplate = await apiExtractor.GenerateAPIRevisionTemplateAsync(currentRevision, revList, apiName, revExc);
321+
await GenerateTemplates(revExc, null, null, fileNameGenerator, fileNames, fileWriter, apiRevisionTemplate);
322+
}
323+
271324
// this function will generate an api dictionary with apiName/versionsetName (if exist one) as key, list of apiNames as value
272325
public async Task<Dictionary<string, List<string>>> GetAllAPIsDictionary(string sourceApim, string resourceGroup, FileWriter fileWriter)
273326
{

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ public FileNames GenerateFileNames(string apimServiceName)
2222
linkedMaster = $@"/{apimServiceName}-master.template.json",
2323
apis = "/Apis",
2424
splitAPIs = "/SplitAPIs",
25-
versionSetMasterFolder = "/VersionSetMasterFolder"
25+
versionSetMasterFolder = "/VersionSetMasterFolder",
26+
revisionMasterFolder = "/RevisionMasterFolder"
2627
};
2728
}
2829

@@ -69,5 +70,6 @@ public class FileNames
6970
public string apis { get; set; }
7071
public string splitAPIs { get; set; }
7172
public string versionSetMasterFolder { get; set; }
73+
public string revisionMasterFolder { get; set; }
7274
}
7375
}

0 commit comments

Comments
 (0)