public ProductAPIExtractor(FileWriter fileWriter) : base(fileWriter)
 {
     this.fileWriter = fileWriter;
 }
 public APITagExtractor(FileWriter fileWriter) : base(fileWriter)
 {
     this.fileWriter = fileWriter;
 }
        public ExtractCommand()
        {
            this.Name        = GlobalConstants.ExtractName;
            this.Description = GlobalConstants.ExtractDescription;

            var sourceApimName = this.Option("--sourceApimName <sourceApimName>", "Source API Management name", CommandOptionType.SingleValue);
            var destinationAPIManagementName = this.Option("--destinationApimName <destinationApimName>", "Destination API Management name", CommandOptionType.SingleValue);
            var resourceGroupName            = this.Option("--resourceGroup <resourceGroup>", "Resource Group name", CommandOptionType.SingleValue);
            var fileFolderName                = this.Option("--fileFolder <filefolder>", "ARM Template files folder", CommandOptionType.SingleValue);
            var apiName                       = this.Option("--apiName <apiName>", "API name", CommandOptionType.SingleValue);
            var linkedTemplatesBaseUrlName    = this.Option("--linkedTemplatesBaseUrl <linkedTemplatesBaseUrl>", "Creates a master template with links", CommandOptionType.SingleValue);
            var linkedTemplatesUrlQueryString = this.Option("--linkedTemplatesUrlQueryString <linkedTemplatesUrlQueryString>", "Query string appended to linked templates uris that enables retrieval from private storage", CommandOptionType.SingleValue);
            var policyXMLBaseUrlName          = this.Option("--policyXMLBaseUrl <policyXMLBaseUrl>", "Writes policies to local XML files that require deployment to remote folder", CommandOptionType.SingleValue);

            this.HelpOption();

            this.OnExecute(async() =>
            {
                try
                {
                    if (!sourceApimName.HasValue())
                    {
                        throw new Exception("Missing parameter <sourceApimName>.");
                    }
                    if (!destinationAPIManagementName.HasValue())
                    {
                        throw new Exception("Missing parameter <destinationApimName>.");
                    }
                    if (!resourceGroupName.HasValue())
                    {
                        throw new Exception("Missing parameter <resourceGroup>.");
                    }
                    if (!fileFolderName.HasValue())
                    {
                        throw new Exception("Missing parameter <filefolder>.");
                    }

                    // isolate cli parameters
                    string resourceGroup        = resourceGroupName.Value().ToString();
                    string sourceApim           = sourceApimName.Value().ToString();
                    string destinationApim      = destinationAPIManagementName.Value().ToString();
                    string fileFolder           = fileFolderName.Value().ToString();
                    string linkedBaseUrl        = linkedTemplatesBaseUrlName.HasValue() ? linkedTemplatesBaseUrlName.Value().ToString() : null;
                    string linkedUrlQueryString = linkedTemplatesUrlQueryString.HasValue() ? linkedTemplatesUrlQueryString.Value().ToString() : null;
                    string policyXMLBaseUrl     = policyXMLBaseUrlName.HasValue() ? policyXMLBaseUrlName.Value().ToString() : null;
                    string singleApiName        = null;

                    if (apiName.Values.Count > 0)
                    {
                        singleApiName = apiName.Value().ToString();
                    }

                    Console.WriteLine("API Management Template");
                    Console.WriteLine();
                    Console.WriteLine("Connecting to {0} API Management Service on {1} Resource Group ...", sourceApim, resourceGroup);
                    if (singleApiName != null)
                    {
                        Console.WriteLine("Executing extraction for {0} API ...", singleApiName);
                    }
                    else
                    {
                        Console.WriteLine("Executing full extraction ...", singleApiName);
                    }

                    // initialize file helper classes
                    FileWriter fileWriter = new FileWriter();
                    FileNameGenerator fileNameGenerator = new FileNameGenerator();
                    FileNames fileNames = fileNameGenerator.GenerateFileNames(sourceApim);

                    // initialize entity extractor classes
                    APIExtractor apiExtractor = new APIExtractor(fileWriter);
                    APIVersionSetExtractor apiVersionSetExtractor             = new APIVersionSetExtractor();
                    AuthorizationServerExtractor authorizationServerExtractor = new AuthorizationServerExtractor();
                    BackendExtractor backendExtractor               = new BackendExtractor();
                    LoggerExtractor loggerExtractor                 = new LoggerExtractor();
                    PolicyExtractor policyExtractor                 = new PolicyExtractor(fileWriter);
                    PropertyExtractor propertyExtractor             = new PropertyExtractor();
                    ProductExtractor productExtractor               = new ProductExtractor(fileWriter);
                    MasterTemplateExtractor masterTemplateExtractor = new MasterTemplateExtractor();

                    // extract templates from apim service
                    Template globalServicePolicyTemplate = await policyExtractor.GenerateGlobalServicePolicyTemplateAsync(sourceApim, resourceGroup, policyXMLBaseUrl, fileFolder);
                    Template apiTemplate = await apiExtractor.GenerateAPIsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, policyXMLBaseUrl, fileFolder);
                    List <TemplateResource> apiTemplateResources = apiTemplate.resources.ToList();
                    Template apiVersionSetTemplate       = await apiVersionSetExtractor.GenerateAPIVersionSetsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
                    Template authorizationServerTemplate = await authorizationServerExtractor.GenerateAuthorizationServersARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
                    Template loggerTemplate     = await loggerExtractor.GenerateLoggerTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
                    Template productTemplate    = await productExtractor.GenerateProductsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl, fileFolder);
                    Template namedValueTemplate = await propertyExtractor.GenerateNamedValuesTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl);
                    List <TemplateResource> namedValueResources = namedValueTemplate.resources.ToList();
                    Template backendTemplate = await backendExtractor.GenerateBackendsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, namedValueResources, policyXMLBaseUrl);

                    // create parameters file
                    Template templateParameters = masterTemplateExtractor.CreateMasterTemplateParameterValues(destinationApim, linkedBaseUrl, linkedUrlQueryString, policyXMLBaseUrl);

                    // write templates to output file location
                    string apiFileName = fileNameGenerator.GenerateExtractorAPIFileName(singleApiName, sourceApim);
                    fileWriter.WriteJSONToFile(apiTemplate, String.Concat(@fileFolder, apiFileName));
                    fileWriter.WriteJSONToFile(apiVersionSetTemplate, String.Concat(@fileFolder, fileNames.apiVersionSets));
                    fileWriter.WriteJSONToFile(authorizationServerTemplate, String.Concat(@fileFolder, fileNames.authorizationServers));
                    fileWriter.WriteJSONToFile(backendTemplate, String.Concat(@fileFolder, fileNames.backends));
                    fileWriter.WriteJSONToFile(loggerTemplate, String.Concat(@fileFolder, fileNames.loggers));
                    fileWriter.WriteJSONToFile(namedValueTemplate, String.Concat(@fileFolder, fileNames.namedValues));
                    fileWriter.WriteJSONToFile(productTemplate, String.Concat(@fileFolder, fileNames.products));
                    fileWriter.WriteJSONToFile(globalServicePolicyTemplate, String.Concat(@fileFolder, fileNames.globalServicePolicy));

                    if (linkedBaseUrl != null)
                    {
                        // create a master template that links to all other templates
                        Template masterTemplate = masterTemplateExtractor.GenerateLinkedMasterTemplate(apiTemplate, globalServicePolicyTemplate, apiVersionSetTemplate, productTemplate, loggerTemplate, backendTemplate, authorizationServerTemplate, namedValueTemplate, fileNames, apiFileName, linkedUrlQueryString, policyXMLBaseUrl);
                        fileWriter.WriteJSONToFile(masterTemplate, String.Concat(@fileFolder, fileNames.linkedMaster));
                    }

                    // write parameters to outputLocation
                    fileWriter.WriteJSONToFile(templateParameters, String.Concat(fileFolder, fileNames.parameters));
                    Console.WriteLine("Templates written to output location");
                    Console.WriteLine("Press any key to exit process:");
#if DEBUG
                    Console.ReadKey();
#endif
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error occured: " + ex.Message);
                    throw;
                }
            });
        }
 public PolicyExtractor(FileWriter fileWriter)
 {
     this.fileWriter = fileWriter;
 }
Ejemplo n.º 5
0
 public ProductExtractor(FileWriter fileWriter)
 {
     this.fileWriter = fileWriter;
 }
Ejemplo n.º 6
0
 public APIExtractor(FileWriter fileWriter)
 {
     this.fileWriter = fileWriter;
 }
Ejemplo n.º 7
0
        /* three condistions to use this function:
         *  1. singleApiName is null, then generate one master template for the multipleAPIs in multipleApiNams
         *  2. multipleApiNams is null, then generate separate folder and master template for each API
         *  3. when both singleApiName and multipleApiNams is null, then generate one master template to link all apis in the sourceapim
         */
        public static async Task GenerateTemplates(
            Extractor exc,
            string singleApiName,
            List <string> multipleAPINames,
            FileNameGenerator fileNameGenerator,
            FileNames fileNames,
            FileWriter fileWriter,
            Template apiTemplate)
        {
            if (singleApiName != null && multipleAPINames != null)
            {
                throw new Exception("can't specify single API and multiple APIs to extract at the same time");
            }
            // initialize entity extractor classes
            APIExtractor                 apiExtractor                 = new APIExtractor(fileWriter);
            APIVersionSetExtractor       apiVersionSetExtractor       = new APIVersionSetExtractor();
            AuthorizationServerExtractor authorizationServerExtractor = new AuthorizationServerExtractor();
            BackendExtractor             backendExtractor             = new BackendExtractor();
            LoggerExtractor              loggerExtractor              = new LoggerExtractor();
            PolicyExtractor              policyExtractor              = new PolicyExtractor(fileWriter);
            PropertyExtractor            propertyExtractor            = new PropertyExtractor();
            TagExtractor                 tagExtractor                 = new TagExtractor();
            ProductExtractor             productExtractor             = new ProductExtractor(fileWriter);
            MasterTemplateExtractor      masterTemplateExtractor      = new MasterTemplateExtractor();

            // read parameters
            string        sourceApim           = exc.sourceApimName;
            string        resourceGroup        = exc.resourceGroup;
            string        destinationApim      = exc.destinationApimName;
            string        linkedBaseUrl        = exc.linkedTemplatesBaseUrl;
            string        linkedSasToken       = exc.linkedTemplatesSasToken;
            string        policyXMLBaseUrl     = exc.policyXMLBaseUrl;
            string        policyXMLSasToken    = exc.policyXMLSasToken;
            string        dirName              = exc.fileFolder;
            List <string> multipleApiNames     = multipleAPINames;
            string        linkedUrlQueryString = exc.linkedTemplatesUrlQueryString;

            // Get all Apis that will be extracted
            List <string> apisToExtract = new List <string>();

            if (singleApiName != null)
            {
                apisToExtract.Add(singleApiName);
            }
            else if (multipleApiNames != null)
            {
                apisToExtract.AddRange(multipleApiNames);
            }
            else
            {
                List <string> allApis = await apiExtractor.GetAllAPINamesAsync(exc.sourceApimName, exc.resourceGroup);

                apisToExtract.AddRange(allApis);
            }
            Dictionary <string, Dictionary <string, string> > apiLoggerId = null;

            if (exc.paramApiLoggerId)
            {
                apiLoggerId = await GetAllReferencedLoggers(apisToExtract, exc);
            }

            // extract templates from apim service
            Template globalServicePolicyTemplate = await policyExtractor.GenerateGlobalServicePolicyTemplateAsync(sourceApim, resourceGroup, policyXMLBaseUrl, policyXMLSasToken, dirName);

            if (apiTemplate == null)
            {
                apiTemplate = await apiExtractor.GenerateAPIsARMTemplateAsync(singleApiName, multipleApiNames, exc);
            }
            List <TemplateResource> apiTemplateResources = apiTemplate.resources.ToList();
            Template apiVersionSetTemplate = await apiVersionSetExtractor.GenerateAPIVersionSetsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl, policyXMLSasToken);

            Template authorizationServerTemplate = await authorizationServerExtractor.GenerateAuthorizationServersARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl, policyXMLSasToken);

            Template loggerTemplate = await loggerExtractor.GenerateLoggerTemplateAsync(exc, singleApiName, apiTemplateResources, apiLoggerId);

            Template productTemplate = await productExtractor.GenerateProductsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, policyXMLBaseUrl, policyXMLSasToken, dirName);

            List <TemplateResource> productTemplateResources = productTemplate.resources.ToList();
            Template namedValueTemplate = await propertyExtractor.GenerateNamedValuesTemplateAsync(singleApiName, apiTemplateResources, exc);

            Template tagTemplate = await tagExtractor.GenerateTagsTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, productTemplateResources, policyXMLBaseUrl, policyXMLSasToken);

            List <TemplateResource> namedValueResources = namedValueTemplate.resources.ToList();
            Template backendTemplate = await backendExtractor.GenerateBackendsARMTemplateAsync(sourceApim, resourceGroup, singleApiName, apiTemplateResources, namedValueResources, policyXMLBaseUrl, policyXMLSasToken);

            // Add Named Values from Backend
            if (namedValueResources.Count > namedValueTemplate.resources.Length)
            {
                namedValueTemplate.resources = namedValueResources.ToArray();
            }

            Dictionary <string, string> loggerResourceIds = null;

            if (exc.paramLogResourceId)
            {
                List <TemplateResource> loggerResources = loggerTemplate.resources.ToList();
                loggerResourceIds = loggerExtractor.GetAllLoggerResourceIds(loggerResources);
                loggerTemplate    = loggerExtractor.SetLoggerResourceId(loggerTemplate);
            }

            // create parameters file
            Template templateParameters = await masterTemplateExtractor.CreateMasterTemplateParameterValues(apisToExtract, exc, apiLoggerId, loggerResourceIds);

            // write templates to output file location
            string apiFileName = fileNameGenerator.GenerateExtractorAPIFileName(singleApiName, fileNames.baseFileName);

            fileWriter.WriteJSONToFile(apiTemplate, String.Concat(@dirName, apiFileName));
            // won't generate template when there is no resources
            if (apiVersionSetTemplate.resources.Count() != 0)
            {
                fileWriter.WriteJSONToFile(apiVersionSetTemplate, String.Concat(@dirName, fileNames.apiVersionSets));
            }
            if (backendTemplate.resources.Count() != 0)
            {
                fileWriter.WriteJSONToFile(backendTemplate, String.Concat(@dirName, fileNames.backends));
            }
            if (loggerTemplate.resources.Count() != 0)
            {
                fileWriter.WriteJSONToFile(loggerTemplate, String.Concat(@dirName, fileNames.loggers));
            }
            if (authorizationServerTemplate.resources.Count() != 0)
            {
                fileWriter.WriteJSONToFile(authorizationServerTemplate, String.Concat(@dirName, fileNames.authorizationServers));
            }
            if (productTemplate.resources.Count() != 0)
            {
                fileWriter.WriteJSONToFile(productTemplate, String.Concat(@dirName, fileNames.products));
            }
            if (tagTemplate.resources.Count() != 0)
            {
                fileWriter.WriteJSONToFile(tagTemplate, String.Concat(@dirName, fileNames.tags));
            }
            if (namedValueTemplate.resources.Count() != 0)
            {
                fileWriter.WriteJSONToFile(namedValueTemplate, String.Concat(@dirName, fileNames.namedValues));
            }
            if (globalServicePolicyTemplate.resources.Count() != 0)
            {
                fileWriter.WriteJSONToFile(globalServicePolicyTemplate, String.Concat(@dirName, fileNames.globalServicePolicy));
            }
            if (linkedBaseUrl != null)
            {
                // create a master template that links to all other templates
                Template masterTemplate = masterTemplateExtractor.GenerateLinkedMasterTemplate(
                    apiTemplate, globalServicePolicyTemplate, apiVersionSetTemplate, productTemplate,
                    loggerTemplate, backendTemplate, authorizationServerTemplate, namedValueTemplate,
                    tagTemplate, fileNames, apiFileName, exc);

                fileWriter.WriteJSONToFile(masterTemplate, String.Concat(@dirName, fileNames.linkedMaster));
            }

            // write parameters to outputLocation
            fileWriter.WriteJSONToFile(templateParameters, String.Concat(dirName, fileNames.parameters));
        }
Ejemplo n.º 8
0
        // this function will generate an api dictionary with apiName/versionsetName (if exist one) as key, list of apiNames as value
        public static async Task <Dictionary <string, List <string> > > GetAllAPIsDictionary(string sourceApim, string resourceGroup, FileWriter fileWriter)
        {
            APIExtractor apiExtractor = new APIExtractor(fileWriter);

            // pull all apis from service
            JToken[] apis = await apiExtractor.GetAllAPIObjsAsync(sourceApim, resourceGroup);

            // Generate folders based on all apiversionset
            var apiDictionary = new Dictionary <string, List <string> >();

            foreach (JToken oApi in apis)
            {
                string apiDisplayName = ((JValue)oApi["properties"]["displayName"]).Value.ToString();
                if (!apiDictionary.ContainsKey(apiDisplayName))
                {
                    List <string> apiVersionSet = new List <string>();
                    apiVersionSet.Add(((JValue)oApi["name"]).Value.ToString());
                    apiDictionary[apiDisplayName] = apiVersionSet;
                }
                else
                {
                    apiDictionary[apiDisplayName].Add(((JValue)oApi["name"]).Value.ToString());
                }
            }
            return(apiDictionary);
        }
Ejemplo n.º 9
0
        // this function will generate split api templates / folders for each api in this sourceApim
        public static async Task GenerateSplitAPITemplates(ExtractorConfig exc, FileNameGenerator fileNameGenerator, FileWriter fileWriter, FileNames fileNames)
        {
            // Generate folders based on all apiversionset
            var apiDictionary = await GetAllAPIsDictionary(exc.sourceApimName, exc.resourceGroup, fileWriter);

            // Generate templates based on each API/APIversionSet
            foreach (KeyValuePair <string, List <string> > versionSetEntry in apiDictionary)
            {
                string apiFileFolder = exc.fileFolder;

                // if it's APIVersionSet, generate the versionsetfolder for templates
                if (versionSetEntry.Value.Count > 1)
                {
                    // this API has VersionSet
                    string apiDisplayName = versionSetEntry.Key;

                    // create apiVersionSet folder
                    apiFileFolder = String.Concat(@apiFileFolder, $@"/{apiDisplayName}");
                    System.IO.Directory.CreateDirectory(apiFileFolder);

                    // create master templates for each apiVersionSet
                    string versionSetFolder = String.Concat(@apiFileFolder, fileNames.versionSetMasterFolder);
                    System.IO.Directory.CreateDirectory(versionSetFolder);
                    await GenerateTemplates(new Extractor(exc, versionSetFolder), null, versionSetEntry.Value, fileNameGenerator, fileNames, fileWriter, null);

                    Console.WriteLine($@"Finish extracting APIVersionSet {versionSetEntry.Key}");
                }

                // Generate templates for each api
                foreach (string apiName in versionSetEntry.Value)
                {
                    // create folder for each API
                    string tempFileFolder = String.Concat(@apiFileFolder, $@"/{apiName}");
                    System.IO.Directory.CreateDirectory(tempFileFolder);
                    // generate templates for each API
                    await GenerateTemplates(new Extractor(exc, tempFileFolder), apiName, null, fileNameGenerator, fileNames, fileWriter, null);

                    Console.WriteLine($@"Finish extracting API {apiName}");
                }
            }
        }
Ejemplo n.º 10
0
        public static async Task GenerateSingleAPIWithRevisionsTemplates(ExtractorConfig exc, string apiName, FileNameGenerator fileNameGenerator, FileWriter fileWriter, FileNames fileNames)
        {
            Console.WriteLine("Extracting singleAPI {0} with revisions", apiName);

            APIExtractor apiExtractor = new APIExtractor(fileWriter);
            // Get all revisions for this api
            string revisions = await apiExtractor.GetAPIRevisionsAsync(exc.sourceApimName, exc.resourceGroup, apiName);

            JObject       revs            = JObject.Parse(revisions);
            string        currentRevision = null;
            List <string> revList         = new List <string>();

            // Generate seperate folder for each API revision
            for (int i = 0; i < ((JContainer)revs["value"]).Count; i++)
            {
                string apiID         = ((JValue)revs["value"][i]["apiId"]).Value.ToString();
                string singleApiName = apiID.Split("/")[2];
                if (((JValue)revs["value"][i]["isCurrent"]).Value.ToString().Equals("True"))
                {
                    currentRevision = singleApiName;
                }

                string revFileFolder = String.Concat(@exc.fileFolder, $@"/{singleApiName}");
                System.IO.Directory.CreateDirectory(revFileFolder);
                await GenerateTemplates(new Extractor(exc, revFileFolder), singleApiName, null, fileNameGenerator, fileNames, fileWriter, null);

                revList.Add(singleApiName);
            }

            if (currentRevision == null)
            {
                throw new Exception($"Revision {apiName} doesn't exist, something went wrong!");
            }
            // generate revisions master folder
            string revMasterFolder = String.Concat(@exc.fileFolder, fileNames.revisionMasterFolder);

            System.IO.Directory.CreateDirectory(revMasterFolder);
            Extractor revExc = new Extractor(exc, revMasterFolder);
            Template  apiRevisionTemplate = await apiExtractor.GenerateAPIRevisionTemplateAsync(currentRevision, revList, apiName, revExc);

            await GenerateTemplates(revExc, null, null, fileNameGenerator, fileNames, fileWriter, apiRevisionTemplate);
        }
Ejemplo n.º 11
0
        // this function will generate templates for multiple specified APIs
        public static async Task GenerateMultipleAPIsTemplates(ExtractorConfig exc, FileNameGenerator fileNameGenerator, FileWriter fileWriter, FileNames fileNames)
        {
            if (exc.multipleAPIs == null && exc.multipleAPIs.Equals(""))
            {
                throw new Exception("multipleAPIs parameter doesn't have any data");
            }

            string[] apis = exc.multipleAPIs.Split(',');
            for (int i = 0; i < apis.Length; i++)
            {
                apis[i] = apis[i].Trim();
            }

            Console.WriteLine("Start extracting these {0} APIs", apis.Length);

            foreach (string apiName in apis)
            {
                // generate seperate folder for each API
                string apiFileFolder = String.Concat(@exc.fileFolder, $@"/{apiName}");
                System.IO.Directory.CreateDirectory(apiFileFolder);
                await GenerateTemplates(new Extractor(exc, apiFileFolder), apiName, null, fileNameGenerator, fileNames, fileWriter, null);
            }

            // create master templates for these apis
            string groupApiFolder = String.Concat(@exc.fileFolder, fileNames.groupAPIsMasterFolder);

            System.IO.Directory.CreateDirectory(groupApiFolder);
            await GenerateTemplates(new Extractor(exc, groupApiFolder), null, apis.ToList(), fileNameGenerator, fileNames, fileWriter, null);

            Console.WriteLine($@"Finish extracting mutiple APIs");
        }
Ejemplo n.º 12
0
        // this function will generate master template for each API within this version set and an extra master template to link these apis
        public static async Task GenerateAPIVersionSetTemplates(ExtractorConfig exc, FileNameGenerator fileNameGenerator, FileNames fileNames, FileWriter fileWriter)
        {
            // get api dictionary and check api version set
            var apiDictionary = await GetAllAPIsDictionary(exc.sourceApimName, exc.resourceGroup, fileWriter);

            if (!apiDictionary.ContainsKey(exc.apiVersionSetName))
            {
                throw new Exception("API Version Set with this name doesn't exist");
            }
            else
            {
                Console.WriteLine("Start extracting the API version set {0}", exc.apiVersionSetName);

                foreach (string apiName in apiDictionary[exc.apiVersionSetName])
                {
                    // generate seperate folder for each API
                    string apiFileFolder = String.Concat(@exc.fileFolder, $@"/{apiName}");
                    System.IO.Directory.CreateDirectory(apiFileFolder);
                    await GenerateTemplates(new Extractor(exc, apiFileFolder), apiName, null, fileNameGenerator, fileNames, fileWriter, null);
                }

                // create master templates for this apiVersionSet
                string versionSetFolder = String.Concat(@exc.fileFolder, fileNames.versionSetMasterFolder);
                System.IO.Directory.CreateDirectory(versionSetFolder);
                await GenerateTemplates(new Extractor(exc, versionSetFolder), null, apiDictionary[exc.apiVersionSetName], fileNameGenerator, fileNames, fileWriter, null);

                Console.WriteLine($@"Finish extracting APIVersionSet {exc.apiVersionSetName}");
            }
        }
        public ExtractCommand()
        {
            this.Name        = GlobalConstants.ExtractName;
            this.Description = GlobalConstants.ExtractDescription;
            var filePath = this.Option("--extractorConfig <extractorConfig>", "Config file of the extractor", CommandOptionType.SingleValue);

            this.HelpOption();

            this.OnExecute(async() =>
            {
                // convert config file to extractorConfig class
                FileReader fileReader      = new FileReader();
                string extractorConfigPath = filePath.HasValue() ? filePath.Value().ToString() : null;

                ExtractorConfig extractorConfig = fileReader.ConvertConfigJsonToExtractorConfig(extractorConfigPath);

                try
                {
                    //validation check
                    ExtractorUtils.validationCheck(extractorConfig);

                    string singleApiName   = extractorConfig.apiName;
                    bool splitAPIs         = extractorConfig.splitAPIs != null && extractorConfig.splitAPIs.Equals("true");
                    bool hasVersionSetName = extractorConfig.apiVersionSetName != null;
                    bool hasSingleApi      = singleApiName != null;
                    bool includeRevisions  = extractorConfig.includeAllRevisions != null && extractorConfig.includeAllRevisions.Equals("true");
                    bool hasMultipleAPIs   = extractorConfig.mutipleAPIs != null;

                    // start running extractor
                    Console.WriteLine("API Management Template");
                    Console.WriteLine("Connecting to {0} API Management Service on {1} Resource Group ...", extractorConfig.sourceApimName, extractorConfig.resourceGroup);

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

                    if (splitAPIs)
                    {
                        // create split api templates for all apis in the sourceApim
                        await ExtractorUtils.GenerateSplitAPITemplates(extractorConfig, fileNameGenerator, fileWriter, fileNames);
                    }
                    else if (hasVersionSetName)
                    {
                        // create split api templates and aggregated api templates for this apiversionset
                        await ExtractorUtils.GenerateAPIVersionSetTemplates(extractorConfig, fileNameGenerator, fileNames, fileWriter);
                    }
                    else if (hasMultipleAPIs)
                    {
                        // generate templates for multiple APIs
                        await ExtractorUtils.GenerateMultipleAPIsTemplates(extractorConfig, fileNameGenerator, fileWriter, fileNames);
                    }
                    else if (hasSingleApi && includeRevisions)
                    {
                        // handle singel API include Revision extraction
                        await ExtractorUtils.GenerateSingleAPIWithRevisionsTemplates(extractorConfig, singleApiName, fileNameGenerator, fileWriter, fileNames);
                    }
                    else
                    {
                        // create single api template or create aggregated api templates for all apis within the sourceApim
                        if (hasSingleApi)
                        {
                            Console.WriteLine("Executing extraction for {0} API ...", singleApiName);
                        }
                        else
                        {
                            Console.WriteLine("Executing full extraction ...");
                        }
                        await ExtractorUtils.GenerateTemplates(new Extractor(extractorConfig), singleApiName, null, fileNameGenerator, fileNames, fileWriter, null);
                    }
                    Console.WriteLine("Templates written to output location");
                    Console.WriteLine("Press any key to exit process:");
#if DEBUG
                    Console.ReadKey();
#endif
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error occured: " + ex.Message);
                    throw;
                }
            });
        }
        private void GenerateARMTemplate(string apimname, string resourceGroup, string fileFolder, string singleApiName)
        {
            #region API's
            FileWriter   fileWriter;
            APIExtractor apiExtractor = new APIExtractor();
            string       apis         = apiExtractor.GetAPIs(apimname, resourceGroup).Result;

            Template armTemplate = new Template()
            {
                schema         = "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                contentVersion = "1.0.0.0",
                parameters     = new Dictionary <string, TemplateParameterProperties>
                {
                    { "ApimServiceName", new TemplateParameterProperties()
                      {
                          type = "string"
                      } }
                },
                variables = { },
                resources = { },
                outputs   = { }
            };

            JObject oApi = JObject.Parse(apis);
            oApi = FormatoApi(singleApiName, oApi);

            Console.WriteLine("{0} API's found ...", ((JContainer)oApi["value"]).Count.ToString());

            if (singleApiName == null)
            {
                GenerateLoggerTemplate(resourceGroup, apimname, fileFolder);
            }

            List <TemplateResource> templateResources = new List <TemplateResource>();

            for (int i = 0; i < ((JContainer)oApi["value"]).Count; i++)
            {
                string apiName    = ((JValue)oApi["value"][i]["name"]).Value.ToString();
                string apiDetails = apiExtractor.GetAPIDetails(apimname, resourceGroup, apiName).Result;

                Console.WriteLine("------------------------------------------");
                Console.WriteLine("Geting operations from {0} API:", apiName);

                JObject             oApiDetails = JObject.Parse(apiDetails);
                APITemplateResource apiResource = JsonConvert.DeserializeObject <APITemplateResource>(apiDetails);
                string oApiName = ((JValue)oApiDetails["name"]).Value.ToString();

                apiResource.type       = ((JValue)oApiDetails["type"]).Value.ToString();
                apiResource.name       = $"[concat(parameters('ApimServiceName'), '/{oApiName}')]";
                apiResource.apiVersion = "2018-06-01-preview";
                apiResource.scale      = null;

                if (apiResource.properties.apiVersionSetId != null)
                {
                    apiResource.dependsOn = new string[] { };

                    string versionSetName     = apiResource.properties.apiVersionSetId;
                    int    versionSetPosition = versionSetName.IndexOf("api-version-sets/");

                    versionSetName = versionSetName.Substring(versionSetPosition, (versionSetName.Length - versionSetPosition));
                    apiResource.properties.apiVersionSetId = $"[concat(resourceId('Microsoft.ApiManagement/service', parameters('ApimServiceName')), '/{versionSetName}')]";
                    GenerateVersionSetARMTemplate(apimname, resourceGroup, versionSetName, fileFolder);
                }
                else
                {
                    apiResource.dependsOn = new string[] { };
                }

                templateResources.Add(apiResource);

                #region Operations

                string  operations  = apiExtractor.GetAPIOperations(apimname, resourceGroup, apiName).Result;
                JObject oOperations = JObject.Parse(operations);

                foreach (var item in oOperations["value"])
                {
                    string operationName    = ((JValue)item["name"]).Value.ToString();
                    string operationDetails = apiExtractor.GetAPIOperationDetail(apimname, resourceGroup, apiName, operationName).Result;

                    Console.WriteLine("'{0}' Operation found", operationName);

                    OperationTemplateResource operationResource = JsonConvert.DeserializeObject <OperationTemplateResource>(operationDetails);
                    string operationResourceName = operationResource.name;
                    operationResource.name       = $"[concat(parameters('ApimServiceName'), '/{oApiName}/{operationResourceName}')]";
                    operationResource.apiVersion = "2018-06-01-preview";
                    operationResource.scale      = null;
                    operationResource.dependsOn  = new string[] { $"[resourceId('Microsoft.ApiManagement/service/apis', parameters('ApimServiceName'), '{oApiName}')]" };

                    templateResources.Add(operationResource);
                    try
                    {
                        string operationPolicy = apiExtractor.GetOperationPolicy(apimname, resourceGroup, oApiName, operationName).Result;
                        Console.WriteLine($" - Policy found to {operationName} operation");
                        PolicyTemplateResource operationPolicyResource = JsonConvert.DeserializeObject <PolicyTemplateResource>(operationPolicy);
                        operationPolicyResource.name       = $"[concat(parameters('ApimServiceName'), '/{oApiName}/{operationResourceName}/policy')]";
                        operationPolicyResource.apiVersion = "2018-06-01-preview";
                        operationPolicyResource.scale      = null;
                        operationPolicyResource.dependsOn  = new string[] { $"[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('ApimServiceName'), '{oApiName}', '{operationResourceName}')]" };

                        templateResources.Add(operationPolicyResource);
                    }
                    catch (Exception)
                    {
                        Console.WriteLine($" - No policy found for {operationName} operation");
                    }
                }
                #endregion

                #region API Policies
                try
                {
                    Console.WriteLine("Geting API Policy from {0} API: ", apiName);
                    string apiPolicies = apiExtractor.GetAPIPolicies(apimname, resourceGroup, apiName).Result;
                    Console.WriteLine("API Policy found!");
                    PolicyTemplateResource apiPoliciesResource = JsonConvert.DeserializeObject <PolicyTemplateResource>(apiPolicies);

                    apiPoliciesResource.apiVersion = "2018-06-01-preview";
                    apiPoliciesResource.name       = $"[concat(parameters('ApimServiceName'), '/{oApiName}/{apiPoliciesResource.name}')]";
                    apiPoliciesResource.dependsOn  = new string[] { $"[resourceId('Microsoft.ApiManagement/service/apis', parameters('ApimServiceName'), '{apiName}')]" };

                    templateResources.Add(apiPoliciesResource);
                }
                catch (Exception)
                {
                    Console.WriteLine("No API policy!");
                }
                #endregion

                #region API Products
                try
                {
                    Console.WriteLine("Geting API Products from {0} API: ", apiName);
                    string  apiProducts  = apiExtractor.GetApiProducts(apimname, resourceGroup, apiName).Result;
                    JObject oApiProducts = JObject.Parse(apiProducts);

                    foreach (var item in oApiProducts["value"])
                    {
                        string apiProductName = ((JValue)item["name"]).Value.ToString();
                        Console.WriteLine($" -- {apiProductName} Product found to {oApiName} API");
                        ApiProductsTemplateResource apiProductsResource = JsonConvert.DeserializeObject <ApiProductsTemplateResource>(apiProducts);
                        apiProductsResource.type       = "Microsoft.ApiManagement/service/products/apis";
                        apiProductsResource.name       = $"[concat(parameters('ApimServiceName'), '/{apiProductName}/{oApiName}')]";
                        apiProductsResource.apiVersion = "2018-06-01-preview";
                        apiProductsResource.scale      = null;
                        apiProductsResource.dependsOn  = new string[] { $"[resourceId('Microsoft.ApiManagement/service/apis', parameters('ApimServiceName'), '{oApiName}')]" };

                        templateResources.Add(apiProductsResource);
                    }
                }
                catch (Exception)
                {
                    Console.WriteLine("No API products!");
                }
                #endregion

                #region Diagnostics

                Console.WriteLine("------------------------------------------");
                Console.WriteLine("Geting diagnostics from {0} API:", apiName);
                string  diagnostics  = apiExtractor.GetAPIDiagnostics(apimname, resourceGroup, apiName).Result;
                JObject oDiagnostics = JObject.Parse(diagnostics);
                foreach (var diagnostic in oDiagnostics["value"])
                {
                    string diagnosticName = ((JValue)diagnostic["name"]).Value.ToString();
                    Console.WriteLine("'{0}' Diagnostic found", diagnosticName);

                    DiagnosticTemplateResource diagnosticResource = diagnostic.ToObject <DiagnosticTemplateResource>();
                    diagnosticResource.name       = $"[concat(parameters('ApimServiceName'), '/{oApiName}/{diagnosticName}')]";
                    diagnosticResource.type       = "Microsoft.ApiManagement/service/apis/diagnostics";
                    diagnosticResource.apiVersion = "2018-06-01-preview";
                    diagnosticResource.scale      = null;
                    diagnosticResource.dependsOn  = new string[] { $"[resourceId('Microsoft.ApiManagement/service/apis', parameters('ApimServiceName'), '{oApiName}')]" };

                    if (!diagnosticName.Contains("applicationinsights"))
                    {
                        // enableHttpCorrelationHeaders only works for application insights, causes errors otherwise
                        diagnosticResource.properties.enableHttpCorrelationHeaders = null;
                    }

                    templateResources.Add(diagnosticResource);
                }

                #endregion

                armTemplate.resources = templateResources.ToArray();

                if (singleApiName != null)
                {
                    fileWriter = new FileWriter();
                    fileWriter.WriteJSONToFile(armTemplate, @fileFolder + Path.DirectorySeparatorChar + apimname + "-" + oApiName + "-template.json");
                    templateResources = new List <TemplateResource>();
                }
            }

            if (singleApiName == null)
            {
                fileWriter = new FileWriter();
                fileWriter.WriteJSONToFile(armTemplate, @fileFolder + Path.DirectorySeparatorChar + apimname + "-apis-template.json");
            }
            #endregion
        }
        private async void GenerateLoggerTemplate(string resourceGroup, string apimname, string fileFolder)
        {
            Console.WriteLine("------------------------------------------");
            Console.WriteLine("Geting loggers from service");
            LoggerExtractor   loggerExtractor   = new LoggerExtractor();
            PropertyExtractor propertyExtractor = new PropertyExtractor();
            Template          armTemplate       = new Template()
            {
                schema         = "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                contentVersion = "1.0.0.0",
                parameters     = new Dictionary <string, TemplateParameterProperties>
                {
                    { "ApimServiceName", new TemplateParameterProperties()
                      {
                          type = "string"
                      } }
                },
                variables = { },
                resources = { },
                outputs   = { }
            };

            List <TemplateResource> templateResources = new List <TemplateResource>();

            // pull named values for later credential reference
            string  properties  = propertyExtractor.GetProperties(apimname, resourceGroup).Result;
            JObject oProperties = JObject.Parse(properties);
            List <PropertyTemplateResource> propertyResources = oProperties["value"].ToObject <List <PropertyTemplateResource> >();

            string  loggers  = loggerExtractor.GetLoggers(apimname, resourceGroup).Result;
            JObject oLoggers = JObject.Parse(loggers);

            foreach (var extractedLogger in oLoggers["value"])
            {
                string loggerName = ((JValue)extractedLogger["name"]).Value.ToString();
                Console.WriteLine("'{0}' Logger found", loggerName);

                string fullLoggerResource = await loggerExtractor.GetLogger(apimname, resourceGroup, loggerName);

                LoggerTemplateResource loggerResource = JsonConvert.DeserializeObject <LoggerTemplateResource>(fullLoggerResource);
                loggerResource.name       = $"[concat(parameters('ApimServiceName'), '/{loggerName}')]";
                loggerResource.type       = "Microsoft.ApiManagement/service/loggers";
                loggerResource.apiVersion = "2018-06-01-preview";
                loggerResource.scale      = null;

                // swap credentials for their hidden values, taken from named values
                if (loggerResource.properties.credentials != null)
                {
                    if (loggerResource.properties.credentials.instrumentationKey != null)
                    {
                        string hiddenKey = loggerResource.properties.credentials.instrumentationKey.Substring(2, loggerResource.properties.credentials.instrumentationKey.Length - 4);
                        loggerResource.properties.credentials.instrumentationKey = propertyResources.Find(p => p.properties.displayName == hiddenKey).properties.value;
                    }
                    else if (loggerResource.properties.credentials.connectionString != null)
                    {
                        string hiddenKey = loggerResource.properties.credentials.connectionString.Substring(2, loggerResource.properties.credentials.connectionString.Length - 4);
                        loggerResource.properties.credentials.connectionString = propertyResources.Find(p => p.properties.displayName == hiddenKey).properties.value;
                    }
                }

                templateResources.Add(loggerResource);
            }

            armTemplate.resources = templateResources.ToArray();
            FileWriter fileWriter = new FileWriter();
            string     filePath   = fileFolder + Path.DirectorySeparatorChar + string.Format("loggers", "/", "-") + ".json";

            fileWriter.WriteJSONToFile(armTemplate, filePath);
        }