Beispiel #1
0
        /// <summary>
        /// Initialization routine
        /// </summary>
        /// <param name="action">action</param>
        /// <returns>initialization task</returns>
        private async Task Initialize(Action action)
        {
            // load the environment configuration file from UtilsInternal
            var sr                    = new FileSettingsReader(ConfigurationManager.AppSettings["ConfigRelativePath"] + Path.DirectorySeparatorChar + environmentName + ".config");
            var certThumbprint        = sr.ReadValue(SocialPlusCertThumbprint);
            var clientID              = sr.ReadValue(EmbeddedSocialClientIdSetting);
            var storeLocation         = StoreLocation.CurrentUser;
            var vaultUrl              = sr.ReadValue(SocialPlusVaultUrlSetting);
            ICertificateHelper cert   = new CertificateHelper(certThumbprint, clientID, storeLocation);
            IKeyVaultClient    client = new AzureKeyVaultClient(cert);

            var log      = new Log(LogDestination.Console, Log.DefaultCategoryName);
            var kv       = new KV(log, clientID, vaultUrl, certThumbprint, storeLocation, client);
            var kvReader = new KVSettingsReader(sr, kv);

            IConnectionStringProvider connectionStringProvider = new ConnectionStringProvider(kvReader);
            int          queueBatchIntervalMs = int.Parse(sr.ReadValue(ServiceBusBatchIntervalMsSetting));
            QueueManager queueManager         = new QueueManager(connectionStringProvider, queueBatchIntervalMs);
            var          sbConnect            = await connectionStringProvider.GetServiceBusConnectionString(ServiceBusInstanceType.Default);

            // the ListQueues action requires an instance of a ServiceBus object
            if (action == Action.ListQueues)
            {
                this.sb = new ServiceBus(sbConnect);
            }

            // all the remaining actions operate on an instance of a ServiceBusQueue object
            if (action != Action.ListQueues)
            {
                // ParseArgs() ensures that queueName is valid here
                this.sbQueue = await ServiceBusQueue.Create(sbConnect, queueName, queueBatchIntervalMs);

                this.selectedQueue = await queueManager.GetQueue((QueueIdentifier)selectedQueueId);
            }
        }
        /// <summary>
        /// Initializes static members of the <see cref="TestConstants"/> class.
        /// </summary>
        static TestConstants()
        {
#if OBA_DEV_ALEC
            string environmentName = "oba-dev-alec";
            ConfigFileName = environmentName + ".config";
#endif
#if OBA_DEV_SHARAD
            string environmentName = "oba-dev-sharad";
            ConfigFileName = environmentName + ".config";
#endif
#if OBA_PPE
            string environmentName = "oba-ppe";
            ConfigFileName = environmentName + ".config";
#endif
#if OBA_PROD
            string environmentName = "oba-prod";
            ConfigFileName = environmentName + ".config";
#endif

            // use the fsr to read values that are not secrets
            var fsr = new FileSettingsReader(ConfigurationManager.AppSettings["ConfigRelativePath"] + Path.DirectorySeparatorChar + ConfigFileName);

            EmbeddedSocialAdminUserHandle = fsr.ReadValue("EmbeddedSocialAdminUserHandle");
            EmbeddedSocialAppKey          = fsr.ReadValue("EmbeddedSocialAppKey");
            EmbeddedSocialUri             = new Uri(fsr.ReadValue("EmbeddedSocialUri"));

            AADOBAAppId    = fsr.ReadValue("AADOBAAppId");
            AADOBAHomePage = fsr.ReadValue("AADOBAHomePage");
            AADTenantId    = fsr.ReadValue("AADTenantId");

            KeyVaultUri       = fsr.ReadValue("KeyVaultUri");
            OBACertThumbprint = fsr.ReadValue("OBACertThumbprint");
            OBARegionsListUri = fsr.ReadValue("OBARegionsListUri");

            // use the kvr to read secrets
            ICertificateHelper cert     = new CertificateHelper(OBACertThumbprint, AADOBAAppId, StoreLocation.CurrentUser);
            IKeyVaultClient    kvClient = new AzureKeyVaultClient(cert);
            var log = new Log(LogDestination.Debug, Log.DefaultCategoryName);
            var kv  = new KV(log, AADOBAAppId, KeyVaultUri, OBACertThumbprint, StoreLocation.CurrentUser, kvClient);
            var kvr = new KVSettingsReader(fsr, kv);

            AzureStorageConnectionString = kvr.ReadValueAsync("AzureStorageConnectionString").Result;
            OBAApiKey                  = kvr.ReadValueAsync("OBAApiKey").Result;
            SendGridEmailAddr          = kvr.ReadValueAsync("SendGridEmailAddr").Result;
            SendGridKey                = kvr.ReadValueAsync("SendGridKey").Result;
            ServiceBusConnectionString = kvr.ReadValueAsync("ServiceBusConnectionString").Result;

            // Obtain an AAD token using a cert from the local store for the current user
            AADSettings       aadSettings = new AADSettings(TestConstants.AADTenantId, TestConstants.AADOBAAppId, TestConstants.AADOBAHomePage, TestConstants.OBACertThumbprint);
            CertificateHelper certHelper  = new CertificateHelper(TestConstants.OBACertThumbprint, TestConstants.AADOBAAppId, StoreLocation.CurrentUser);
            EmbeddedSocialAADToken = certHelper.GetAccessToken(aadSettings.Authority, aadSettings.AppUri).Result;
        }
        /// <summary>
        /// Retrieves SendGrid key from KV
        /// </summary>
        /// <param name="configFile">config file path</param>
        /// <returns>SendGrid key</returns>
        public static string GetSendGridKey(string configFile)
        {
            var sr                    = new FileSettingsReader(configFile);
            var certThumbprint        = sr.ReadValue(TestConstants.SocialPlusCertThumbprint);
            var clientID              = sr.ReadValue(TestConstants.EmbeddedSocialClientIdSetting);
            var storeLocation         = StoreLocation.CurrentUser;
            var vaultUrl              = sr.ReadValue(TestConstants.SocialPlusVaultUrlSetting);
            ICertificateHelper cert   = new CertificateHelper(certThumbprint, clientID, storeLocation);
            IKeyVaultClient    client = new AzureKeyVaultClient(cert);

            var log      = new Log(LogDestination.Console, Log.DefaultCategoryName);
            var kv       = new KV(log, clientID, vaultUrl, certThumbprint, storeLocation, client);
            var kvReader = new KVSettingsReader(sr, kv);

            return(kvReader.ReadValueAsync("SendGridInstrumentationKey").Result);
        }
        /// <summary>
        /// Initialization routine
        /// </summary>
        /// <returns>init task</returns>
        private async Task Initialize()
        {
            // load the environment configuration file from UtilsInternal
            var sr                    = new FileSettingsReader(ConfigurationManager.AppSettings["ConfigRelativePath"] + Path.DirectorySeparatorChar + environmentName + ".config");
            var certThumbprint        = sr.ReadValue(SocialPlusCertThumbprint);
            var clientID              = sr.ReadValue(EmbeddedSocialClientIdSetting);
            var storeLocation         = StoreLocation.CurrentUser;
            var vaultUrl              = sr.ReadValue(SocialPlusVaultUrlSetting);
            ICertificateHelper cert   = new CertificateHelper(certThumbprint, clientID, storeLocation);
            IKeyVaultClient    client = new AzureKeyVaultClient(cert);

            var log      = new Log(LogDestination.Console, Log.DefaultCategoryName);
            var kv       = new KV(log, clientID, vaultUrl, certThumbprint, storeLocation, client);
            var kvReader = new KVSettingsReader(sr, kv);
            IConnectionStringProvider connectionStringProvider = new ConnectionStringProvider(kvReader);

            cvsUrl = await connectionStringProvider.GetCVSUrl(CVSInstanceType.Default);

            cvsSubscriptionKey = await connectionStringProvider.GetCVSKey(CVSInstanceType.Default);
        }
        /// <summary>
        /// Initializes the store instance for a specific environment name
        /// </summary>
        /// <param name="environmentName">name of environment</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        protected async Task Init(string environmentName)
        {
            var sr                    = new FileSettingsReader(ConfigurationManager.AppSettings["ConfigRelativePath"] + Path.DirectorySeparatorChar + environmentName + ".config");
            var certThumbprint        = sr.ReadValue(SocialPlusCertThumbprint);
            var clientID              = sr.ReadValue(EmbeddedSocialClientIdSetting);
            var vaultUrl              = sr.ReadValue(SocialPlusVaultUrlSetting);
            var storeLocation         = StoreLocation.CurrentUser;
            ICertificateHelper cert   = new CertificateHelper(certThumbprint, clientID, storeLocation);
            IKeyVaultClient    client = new AzureKeyVaultClient(cert);

            var log      = new Log(LogDestination.Console, Log.DefaultCategoryName);
            IKV kv       = new KV(log, clientID, vaultUrl, certThumbprint, storeLocation, client);
            var kvReader = new KVSettingsReader(sr, kv);

            ConnectionStringProvider csp             = new ConnectionStringProvider(kvReader);
            string azureTableStorageConnectionString = await kvReader.ReadValueAsync("AzureStorageConnectionString");

            // Retrieve the storage account from the connection string.
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(azureTableStorageConnectionString);

            // Create the table client.
            this.tableClient = storageAccount.CreateCloudTableClient();
        }
Beispiel #6
0
        /// <summary>
        /// Async version of the Main program
        /// </summary>
        /// <param name="args">command line args</param>
        /// <returns>a task</returns>
        public static async Task AsyncMain(string[] args)
        {
            ParseArgs(args);

            var sr                    = new FileSettingsReader(ConfigurationManager.AppSettings["ConfigRelativePath"] + Path.DirectorySeparatorChar + environmentName + ".config");
            var certThumbprint        = sr.ReadValue(OBACertThumbprint);
            var clientID              = sr.ReadValue(OBAClientId);
            var storeLocation         = StoreLocation.CurrentUser;
            var vaultUrl              = sr.ReadValue(OBAVaultUrl);
            ICertificateHelper cert   = new CertificateHelper(certThumbprint, clientID, storeLocation);
            IKeyVaultClient    client = new AzureKeyVaultClient(cert);
            var log                   = new Log(LogDestination.Debug, Log.DefaultCategoryName);

            kv = new KV(log, clientID, vaultUrl, certThumbprint, storeLocation, client);
            var kvReader = new KVSettingsReader(sr, kv);

            if (doClean)
            {
                DisplayWarning();
            }

            // display current configuration
            await ValidateAndPrintConfiguration(environmentName, kvReader);

            if (forceOperation == false)
            {
                // get user approval
                Console.Write("Are you sure you want to proceed? [y/n] : ");
                ConsoleKeyInfo keyInfo = Console.ReadKey(false);
                if (keyInfo.KeyChar != 'y')
                {
                    return;
                }

                Console.WriteLine();
            }

            if (doAll || doTables)
            {
                string azureTableStorageConnectionString = await kvReader.ReadValueAsync("AzureStorageConnectionString");

                if (doClean)
                {
                    // Delete tables
                    await Tables.Clean(azureTableStorageConnectionString);
                }

                if (doCreate)
                {
                    // Create tables
                    await Tables.Create(azureTableStorageConnectionString);
                }
            }

            if (doAll || doQueues)
            {
                if (doClean)
                {
                    // Delete queues
                    await Queues.Clean();
                }

                if (doCreate)
                {
                    // Create queues
                    await Queues.Create();
                }
            }

            if (doAll || doLogs)
            {
                string azureDiagnosticsConnectionString = await kvReader.ReadValueAsync("AzureStorageConnectionString");

                if (doClean)
                {
                    // Delete logs
                    await Logs.Clean(azureDiagnosticsConnectionString);
                }

                if (doCreate)
                {
                    // Create queues
                    await Logs.Create();
                }
            }

            Console.WriteLine("All done! Bye!");
        }
        /// <summary>
        /// Actual OBAService code is invoked here
        /// </summary>
        /// <param name="cancellationToken">token that represents a cancel</param>
        /// <returns>task that runs OBAService</returns>
        private async Task RunAsync(CancellationToken cancellationToken)
        {
            bool            enableAzureSettingsReaderTracing = false;
            ISettingsReader settingsReader = new AzureSettingsReader(enableAzureSettingsReaderTracing);

            // use the normal azure settings reader to fetch the OBA app id, the OBA cert, and the key vault uri
            string aadAppId          = settingsReader.ReadValue("AADOBAAppId");
            string obaCertThumbprint = settingsReader.ReadValue("OBACertThumbprint");
            string keyVaultUri       = settingsReader.ReadValue("KeyVaultUri");

            // create a key vault settings reader to read secrets
            ICertificateHelper certHelper = new CertificateHelper(obaCertThumbprint, aadAppId, StoreLocation.LocalMachine);
            IKeyVaultClient    kvClient   = new AzureKeyVaultClient(certHelper);
            var log = new Log(LogDestination.Debug, Log.DefaultCategoryName);
            var kv  = new KV(log, aadAppId, keyVaultUri, obaCertThumbprint, StoreLocation.LocalMachine, kvClient);
            var kvr = new KVSettingsReader(settingsReader, kv);

            // get all the settings
            string azureStorageConnectionString = await kvr.ReadValueAsync("AzureStorageConnectionString");

            string obaApiKey = await kvr.ReadValueAsync("OBAApiKey");

            string obaRegionsListUri = await kvr.ReadValueAsync("OBARegionsListUri");

            Uri    embeddedSocialUri    = new Uri(await kvr.ReadValueAsync("EmbeddedSocialUri"));
            string embeddedSocialAppKey = await kvr.ReadValueAsync("EmbeddedSocialAppKey");

            string embeddedSocialAdminUserHandle = await kvr.ReadValueAsync("EmbeddedSocialAdminUserHandle");

            string aadTenantId = await kvr.ReadValueAsync("AADTenantId");

            string aadAppHomePage = await kvr.ReadValueAsync("AADOBAHomePage");

            string sendGridEmailAddr = await kvr.ReadValueAsync("SendGridEmailAddr");

            string sendGridKey = await kvr.ReadValueAsync("SendGridKey");

            while (!cancellationToken.IsCancellationRequested)
            {
                // create a runId
                string runId = RunId.GenerateRunId();

                // setup email
                Email email = new Email();
                email.To = new List <string>()
                {
                    sendGridEmailAddr
                };
                email.Add(runId);
                email.Add(embeddedSocialUri);

                try
                {
                    // obtain an AAD token using a cert from the local store for the current user
                    AADSettings aadSettings            = new AADSettings(aadTenantId, aadAppId, aadAppHomePage, obaCertThumbprint);
                    string      embeddedSocialAADToken = await certHelper.GetAccessToken(aadSettings.Authority, aadSettings.AppUri);

                    // create all the managers
                    OBADownload.DownloadManager            downloadManager = new OBADownload.DownloadManager(azureStorageConnectionString, runId, obaApiKey, obaRegionsListUri);
                    Diff.DiffManager                       diffManager     = new Diff.DiffManager(azureStorageConnectionString, runId);
                    PublishToEmbeddedSocial.PublishManager publishManager  = new PublishToEmbeddedSocial.PublishManager(azureStorageConnectionString, runId, embeddedSocialUri, embeddedSocialAppKey, embeddedSocialAADToken, embeddedSocialAdminUserHandle);

                    // initialize storage
                    await downloadManager.InitializeStorage();

                    await diffManager.InitializeStorage();

                    await publishManager.InitializeStorage();

                    // download routes and stops from OBA servers
                    await downloadManager.DownloadAndStore();

                    // add download metadata to email
                    StorageManager downloadMetadataManager = new StorageManager(azureStorageConnectionString, TableNames.TableType.DownloadMetadata, runId);
                    IEnumerable <DownloadMetadataEntity> downloadMetadata = downloadMetadataManager.DownloadMetadataStore.Get(runId);
                    email.Add(downloadMetadata);

                    // compare downloaded data to previously published data
                    await diffManager.DiffAndStore();

                    // add diff metadata to email
                    StorageManager diffMetadataManager            = new StorageManager(azureStorageConnectionString, TableNames.TableType.DiffMetadata, runId);
                    IEnumerable <DiffMetadataEntity> diffMetadata = diffMetadataManager.DiffMetadataStore.Get(runId);
                    email.Add(diffMetadata);

                    // publish changes to Embedded Social
                    await publishManager.PublishAndStore();

                    // add publish metadata to email
                    StorageManager publishMetadataManager = new StorageManager(azureStorageConnectionString, TableNames.TableType.PublishMetadata, runId);
                    IEnumerable <PublishMetadataEntity> publishMetadata = publishMetadataManager.PublishMetadataStore.Get(runId);
                    email.Add(publishMetadata);
                }
                catch (Exception e)
                {
                    // add the exception to email
                    email.Add(e);

                    // record it in diagnostic logs
                    Alerts.Error(e);
                }

                // remove the OBA key from the email
                email.RemoveString(obaApiKey);

                // send the email
                await email.Send(sendGridKey);

                // sleep for 24 hours
                await Task.Delay(1000 * 60 * 60 * 24);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Async version of the Main program
        /// </summary>
        /// <param name="args">command line args</param>
        /// <returns>a task</returns>
        public static async Task AsyncMain(string[] args)
        {
            ParseArgs(args);

            var sr                    = new FileSettingsReader(ConfigurationManager.AppSettings["ConfigRelativePath"] + Path.DirectorySeparatorChar + environmentName + ".config");
            var certThumbprint        = sr.ReadValue(SocialPlusCertThumbprint);
            var clientID              = sr.ReadValue(EmbeddedSocialClientIdSetting);
            var storeLocation         = StoreLocation.CurrentUser;
            var vaultUrl              = sr.ReadValue(SocialPlusVaultUrlSetting);
            ICertificateHelper cert   = new CertificateHelper(certThumbprint, clientID, storeLocation);
            IKeyVaultClient    client = new AzureKeyVaultClient(cert);

            log = new Log(LogDestination.Console, Log.DefaultCategoryName);
            kv  = new KV(log, clientID, vaultUrl, certThumbprint, storeLocation, client);
            var kvReader = new KVSettingsReader(sr, kv);

            RedisCache redisCache = null;

            if (redisType == RedisType.Volatile)
            {
                var volatileRedis = await kvReader.ReadValueAsync("VolatileRedisConnectionString");

                if (action == "get-info")
                {
                    volatileRedis += ", allowAdmin=1";
                }

                redisCache = new RedisCache(volatileRedis);
            }
            else if (redisType == RedisType.Persistent)
            {
                var persistentRedis = await kvReader.ReadValueAsync("PersistentRedisConnectionString");

                if (action == "get-info")
                {
                    persistentRedis += ", allowAdmin=1";
                }

                redisCache = new RedisCache(persistentRedis);
            }

            // note that the get-info command does not use a container or a table
            if (action == "get-info")
            {
                var actions = new Actions(redisCache, null, null);
                await actions.GetInfo();

                return;
            }

            var container = LookupContainer(containerName);
            var table     = LookupTable(tableName, container);

            if (container != null && table != null)
            {
                var actions = new Actions(redisCache, container, table);
                if (action == "get")
                {
                    await actions.GetObject(partitionKey, objKey);
                }
                else if (action == "get-rank-feed")
                {
                    await actions.GetRankFeed(partitionKey, feedKey, rankFeedOrder);
                }
                else if (action == "delete")
                {
                    await actions.DeleteObject(partitionKey, objKey);
                }
            }
        }
        /// <summary>
        /// Initialization routine
        /// </summary>
        private void Initialize()
        {
            // load the environment configuration file from UtilsInternal
            var sr                    = new FileSettingsReader(ConfigurationManager.AppSettings["ConfigRelativePath"] + Path.DirectorySeparatorChar + environmentName + ".config");
            var certThumbprint        = sr.ReadValue(SocialPlusCertThumbprint);
            var clientID              = sr.ReadValue(EmbeddedSocialClientIdSetting);
            var storeLocation         = StoreLocation.CurrentUser;
            var vaultUrl              = sr.ReadValue(SocialPlusVaultUrlSetting);
            ICertificateHelper cert   = new CertificateHelper(certThumbprint, clientID, storeLocation);
            IKeyVaultClient    client = new AzureKeyVaultClient(cert);

            var log      = new Log(LogDestination.Console, Log.DefaultCategoryName);
            var kv       = new KV(log, clientID, vaultUrl, certThumbprint, storeLocation, client);
            var kvReader = new KVSettingsReader(sr, kv);
            IConnectionStringProvider connectionStringProvider = new ConnectionStringProvider(kvReader);
            int queueBatchIntervalMs = int.Parse(sr.ReadValue(ServiceBusBatchIntervalMsSetting));

            // Lots of things need to be created to create an appsManager.
            ICTStoreManager tableStoreManager = new CTStoreManager(connectionStringProvider);
            bool            tableInit         = false;
            Exception       exception         = null;

            try
            {
                // use Task.Run to ensure that the async Initialize routine runs on a threadpool thread
                Task <bool> task = Task <bool> .Run(() => tableStoreManager.Initialize());

                // task.Result blocks until the result is ready
                tableInit = task.Result;
            }
            catch (Exception e)
            {
                exception = e;
            }

            if (tableInit == false)
            {
                string errorMessage = "CTstore version number does not match the expected version number." + Environment.NewLine +
                                      "If your tables are empty, then you probably forgot to provision storage." + Environment.NewLine +
                                      "If not, then you need to convert the data format and update the storage version number.";
                Console.WriteLine(errorMessage);
                if (exception != null)
                {
                    Console.WriteLine("Exception message:" + exception.Message);
                }

                Environment.Exit(0);
            }

            ICBStoreManager blobStoreManager = new CBStoreManager(connectionStringProvider);
            AppsStore       appsStore        = new AppsStore(tableStoreManager);
            UsersStore      usersStore       = new UsersStore(tableStoreManager);
            ViewsManager    viewsManager     = new ViewsManager(
                log,
                appsStore,
                usersStore,
                new UserRelationshipsStore(tableStoreManager),
                new TopicsStore(tableStoreManager),
                new TopicRelationshipsStore(tableStoreManager),
                new CommentsStore(tableStoreManager),
                new RepliesStore(tableStoreManager),
                new LikesStore(tableStoreManager),
                new PinsStore(tableStoreManager),
                new BlobsStore(blobStoreManager));
            PushNotificationsManager pushManager = new PushNotificationsManager(log, new PushRegistrationsStore(tableStoreManager), appsStore, viewsManager, connectionStringProvider);

            this.appsManager = new AppsManager(appsStore, pushManager);
            SearchManager       searchManager       = new SearchManager(log, connectionStringProvider);
            PopularUsersManager popularUsersManager = new PopularUsersManager(usersStore);
            QueueManager        queueManager        = new QueueManager(connectionStringProvider, queueBatchIntervalMs);
            SearchQueue         searchQueue         = new SearchQueue(queueManager);

            this.usersManager = new UsersManager(usersStore, pushManager, popularUsersManager, searchQueue);
        }
Beispiel #10
0
        /// <summary>
        /// Async version of the Main program
        /// </summary>
        /// <param name="args">command line args</param>
        /// <returns>a task</returns>
        public static async Task AsyncMain(string[] args)
        {
            ParseArgs(args);

            var sr                    = new FileSettingsReader(ConfigurationManager.AppSettings["ConfigRelativePath"] + Path.DirectorySeparatorChar + environmentName + ".config");
            var certThumbprint        = sr.ReadValue(SocialPlusCertThumbprint);
            var clientID              = sr.ReadValue(EmbeddedSocialClientIdSetting);
            var storeLocation         = StoreLocation.CurrentUser;
            var vaultUrl              = sr.ReadValue(SocialPlusVaultUrlSetting);
            ICertificateHelper cert   = new CertificateHelper(certThumbprint, clientID, storeLocation);
            IKeyVaultClient    client = new AzureKeyVaultClient(cert);

            log = new Log(LogDestination.Console, Log.DefaultCategoryName);
            kv  = new KV(log, clientID, vaultUrl, certThumbprint, storeLocation, client);
            var kvReader = new KVSettingsReader(sr, kv);

            // Create a null connection string provider needed for blobStoreManager and tableStoreManager
            NullConnectionStringProvider connectionStringProvider = new NullConnectionStringProvider();

            if (doUpgradeStoreVersion)
            {
                if (!forceOperation)
                {
                    Console.WriteLine("You must specify the -Force option when using -UpgradeStoreVersion");
                    Console.WriteLine("The -UpgradeStoreVersion option is only intended to be used by our version upgrade scripts");
                    Console.WriteLine("If you are trying to use this by hand, you're probably doing something wrong.");
                    return;
                }

                CTStoreManager tableStoreManager = new CTStoreManager(connectionStringProvider);
                string         redisPersistentConnectionString = await kvReader.ReadValueAsync("PersistentRedisConnectionString");

                string azureTableStorageConnectionString = await kvReader.ReadValueAsync("AzureStorageConnectionString");
                await UpgradeStoreVersion(tableStoreManager, azureTableStorageConnectionString, redisPersistentConnectionString);

                return;
            }

            if (doClean)
            {
                DisplayWarning();
            }

            // display current configuration
            await ValidateAndPrintConfiguration(environmentName, kvReader);

            if (forceOperation == false)
            {
                // get user approval
                Console.Write("Are you sure you want to proceed? [y/n] : ");
                ConsoleKeyInfo keyInfo = Console.ReadKey(false);
                if (keyInfo.KeyChar != 'y')
                {
                    return;
                }
            }

            // Mr Clean!!
            Console.WriteLine();
            Console.WriteLine();

            if (doAll || doSearch)
            {
                string searchServiceName = await kvReader.ReadValueAsync("SearchServiceName");

                string searchServiceAdminKey = await kvReader.ReadValueAsync("SearchServiceAdminKey");

                if (doClean)
                {
                    // delete search indices
                    await DeleteSearch(searchServiceName, searchServiceAdminKey);
                }

                if (doCreate)
                {
                    // create search indices
                    await ProvisionSearch(searchServiceName, searchServiceAdminKey);
                }
            }

            if (doAll || doQueues)
            {
                string serviceBusConnectionString = await kvReader.ReadValueAsync("ServiceBusConnectionString");

                if (doClean)
                {
                    // Delete queues
                    await DeleteServiceBusQueues(serviceBusConnectionString);
                }

                if (doCreate)
                {
                    // Create queues
                    await ProvisionServiceBusQueues(serviceBusConnectionString);
                }
            }

            if (doAll || doTables)
            {
                CTStoreManager tableStoreManager = new CTStoreManager(connectionStringProvider);
                string         azureTableStorageConnectionString = await kvReader.ReadValueAsync("AzureStorageConnectionString");

                if (doClean)
                {
                    // Delete tables
                    await DeleteAzureTables(azureTableStorageConnectionString);
                }

                if (doCreate)
                {
                    await ProvisionAzureStorageTables(tableStoreManager, azureTableStorageConnectionString);
                }
            }

            if (doAll || doBlobs)
            {
                CBStoreManager blobStoreManager = new CBStoreManager(connectionStringProvider);
                string         azureBlobStorageConnectionString = await kvReader.ReadValueAsync("AzureBlobStorageConnectionString");

                if (doClean)
                {
                    // Delete blobs
                    await DeleteAzureBlobs(blobStoreManager, azureBlobStorageConnectionString);
                }

                if (doCreate)
                {
                    await ProvisionAzureStorageBlobs(blobStoreManager, azureBlobStorageConnectionString);
                }
            }

            if (doAll || doRedis)
            {
                if (doClean)
                {
                    // Delete redis cache
                    string redisVolatileConnectionString = await kvReader.ReadValueAsync("VolatileRedisConnectionString") + ", allowAdmin=1";

                    string redisPersistentConnectionString = await kvReader.ReadValueAsync("PersistentRedisConnectionString") + ", allowAdmin=1";

                    DeleteRedisCaches(redisVolatileConnectionString, redisPersistentConnectionString);
                }

                if (doCreate)
                {
                    string redisPersistentConnectionString = await kvReader.ReadValueAsync("PersistentRedisConnectionString");

                    CTStoreManager tableStoreManager = new CTStoreManager(connectionStringProvider);
                    await ProvisionRedisCaches(redisPersistentConnectionString, tableStoreManager);
                }
            }

            if (doAll || doLogs)
            {
                CBStoreManager blobStoreManager = new CBStoreManager(connectionStringProvider);
                string         azureBlobStorageConnectionString = await kvReader.ReadValueAsync("AzureBlobStorageConnectionString");

                if (doClean)
                {
                    // Delete logs
                    await DeleteAzureLogs(azureBlobStorageConnectionString);
                }

                if (doCreate)
                {
                    // No need to create the Azure logs (aka WAD* tables). Azure Diagnostics creates them automatically.
                }
            }

            // bye
            Console.WriteLine();
            Console.WriteLine("All done! Bye!");
            Console.WriteLine();
        }