コード例 #1
0
        public void UpgradeLsm()
        {
            // Get shard map manager
            ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager(
                Globals.ShardMapManagerConnectionString,
                ShardMapManagerLoadPolicy.Lazy);

            // upgrade GSM to latest version.
            smm.UpgradeGlobalStore();
            VerifyGlobalStore(smm, GlobalConstants.GsmVersionClient);

            // deploy LSM initial version.
            ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, s_shardedDBs[0]);

            smm.UpgradeLocalStore(sl, s_initialLsmVersion);

            // upgrade to version 1.1
            smm.UpgradeLocalStore(sl, new Version(1, 1));

            // Library is still at LSM major version 1, so adding shard with LSM 1.0 should succeed.
            // Library will see that LSM schema already exists at 'sl' and hence will not deploy LSM again, will just try to add the shard.
            // CreateShard will not work with LSM initial version (1.0) as it only has 'StoreVersion' column in ShardMApManagerLocal table, from 1.1 onwards it follows latest schema for version table.
            ListShardMap <int> listsm = smm.CreateListShardMap <int>(ShardMapManagerUpgradeTests.s_shardMapNames[0]);

            listsm.CreateShard(sl);


            // upgrade to version 1.2
            smm.UpgradeLocalStore(sl, new Version(1, 2));

            // upgrade to latest version (1.2): no-op
            smm.UpgradeLocalStore(sl);
        }
コード例 #2
0
        /// <summary> This app will be for automating on-boarding of new tenant </summary>
        static void Main(string[] args)
        {
            Console.WriteLine($"Starting Shard Registration For Tenant:{args[0]}");
            var tenantKey           = args[0];
            var sqlShardDBServer    = args[1];
            var sqlShardDB          = args[2];
            var shardedDBConnection = args[3];

            ShardMapFactory     shardMapFactory = new ShardMapFactory(shardedDBConnection);
            ListShardMap <Guid> shardMap        = (ListShardMap <Guid>)shardMapFactory.CreateShardMap();


            string appserver   = sqlShardDBServer;
            string appdatabase = sqlShardDB;
            Guid   TenantId    = Guid.Parse(tenantKey);

            var shardLocation = new ShardLocation(appserver, appdatabase);

            if (!shardMap.TryGetShard(shardLocation, out var shard))
            {
                shard = shardMap.CreateShard(new ShardLocation(appserver, appdatabase));
            }
            PointMapping <Guid> mapping;

            if (!shardMap.TryGetMappingForKey(TenantId, out mapping))
            {
                shardMap.CreatePointMapping(TenantId, shard);
            }
        }
コード例 #3
0
        public void DateDeletePointMappingDefault()
        {
            CountingCacheStore countingCache = new CountingCacheStore(new CacheStore());

            ShardMapManager smm = new ShardMapManager(
                new SqlShardMapManagerCredentials(Globals.ShardMapManagerConnectionString),
                new SqlStoreConnectionFactory(),
                new StoreOperationFactory(),
                countingCache,
                ShardMapManagerLoadPolicy.Lazy,
                new RetryPolicy(1, TimeSpan.Zero, TimeSpan.Zero, TimeSpan.Zero),
                RetryBehavior.DefaultRetryBehavior);

            ListShardMap <DateTime> lsm = smm.GetListShardMap <DateTime>(DateTimeShardMapperTests.s_listShardMapName);

            Assert.IsNotNull(lsm);

            ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, DateTimeShardMapperTests.s_shardedDBs[0]);

            Shard s = lsm.CreateShard(sl);

            Assert.IsNotNull(s);

            DateTime val = DateTime.Now;
            PointMapping <DateTime> p1 = lsm.CreatePointMapping(val, s);

            PointMapping <DateTime> p2 = lsm.GetMappingForKey(val);

            Assert.IsNotNull(p2);
            Assert.AreEqual(0, countingCache.LookupMappingHitCount);

            // The mapping must be made offline first before it can be deleted.
            PointMappingUpdate ru = new PointMappingUpdate();

            ru.Status = MappingStatus.Offline;

            PointMapping <DateTime> mappingToDelete = lsm.UpdateMapping(p1, ru);

            lsm.DeleteMapping(mappingToDelete);

            // Try to get from store. Because the mapping is missing from the store, we will try to
            // invalidate the cache, but since it is also missing from cache there will be an cache miss.
            bool lookupFailed = false;

            try
            {
                PointMapping <DateTime> pLookup = lsm.GetMappingForKey(val);
            }
            catch (ShardManagementException sme)
            {
                Assert.AreEqual(ShardManagementErrorCategory.ListShardMap, sme.ErrorCategory);
                Assert.AreEqual(ShardManagementErrorCode.MappingNotFoundForKey, sme.ErrorCode);
                lookupFailed = true;
            }

            Assert.IsTrue(lookupFailed);
            Assert.AreEqual(1, countingCache.LookupMappingMissCount);
        }
コード例 #4
0
        private Shard CreateOrGetShard(ListShardMap <int> shardMap, string databaseShardName)
        {
            var shardLocation = new ShardLocation(this.configuration["ShardingServerName"], databaseShardName);
            var shardExists   = shardMap.TryGetShard(shardLocation, out Shard shard);

            if (!shardExists)
            {
                shard = shardMap.CreateShard(shardLocation);
            }

            return(shard);
        }
コード例 #5
0
        public void DateAddPointMappingDuplicate()
        {
            CountingCacheStore countingCache = new CountingCacheStore(new CacheStore());

            ShardMapManager smm = new ShardMapManager(
                new SqlShardMapManagerCredentials(Globals.ShardMapManagerConnectionString),
                new SqlStoreConnectionFactory(),
                new StoreOperationFactory(),
                countingCache,
                ShardMapManagerLoadPolicy.Lazy,
                new RetryPolicy(1, TimeSpan.Zero, TimeSpan.Zero, TimeSpan.Zero), RetryBehavior.DefaultRetryBehavior);

            ListShardMap <DateTime> lsm = smm.GetListShardMap <DateTime>(DateTimeShardMapperTests.s_listShardMapName);

            Assert.IsNotNull(lsm);

            ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, DateTimeShardMapperTests.s_shardedDBs[0]);

            Shard s = lsm.CreateShard(sl);

            Assert.IsNotNull(s);

            DateTime val = DateTime.Now;
            PointMapping <DateTime> p1 = lsm.CreatePointMapping(val, s);

            Assert.IsNotNull(p1);

            bool addFailed = false;

            try
            {
                // add same point mapping again.
                PointMapping <DateTime> pNew = lsm.CreatePointMapping(val, s);
            }
            catch (ShardManagementException sme)
            {
                Assert.AreEqual(ShardManagementErrorCategory.ListShardMap, sme.ErrorCategory);
                Assert.AreEqual(ShardManagementErrorCode.MappingPointAlreadyMapped, sme.ErrorCode);
                addFailed = true;
            }

            Assert.IsTrue(addFailed);

            PointMapping <DateTime> p2 = lsm.GetMappingForKey(val);

            Assert.IsNotNull(p2);
            Assert.AreEqual(0, countingCache.LookupMappingHitCount);
        }
コード例 #6
0
        public void DateDeletePointMappingNonExisting()
        {
            ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager(
                Globals.ShardMapManagerConnectionString,
                ShardMapManagerLoadPolicy.Lazy);

            ListShardMap <DateTime> lsm = smm.GetListShardMap <DateTime>(DateTimeShardMapperTests.s_listShardMapName);

            Assert.IsNotNull(lsm);

            ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, DateTimeShardMapperTests.s_shardedDBs[0]);

            Shard s = lsm.CreateShard(sl);

            Assert.IsNotNull(s);

            DateTime val = DateTime.Now;
            PointMapping <DateTime> p1 = lsm.CreatePointMapping(val, s);

            Assert.IsNotNull(p1);

            PointMappingUpdate ru = new PointMappingUpdate();

            ru.Status = MappingStatus.Offline;

            // The mapping must be made offline before it can be deleted.
            p1 = lsm.UpdateMapping(p1, ru);

            lsm.DeleteMapping(p1);

            bool removeFailed = false;

            try
            {
                lsm.DeleteMapping(p1);
            }
            catch (ShardManagementException sme)
            {
                Assert.AreEqual(ShardManagementErrorCategory.ListShardMap, sme.ErrorCategory);
                Assert.AreEqual(ShardManagementErrorCode.MappingDoesNotExist, sme.ErrorCode);
                removeFailed = true;
            }

            Assert.IsTrue(removeFailed);
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: vijayaraju/code-challenges
        private static Shard GetOrCreateOrderShard(ListShardMap <int> shardMap, string headConnectionString, int customerId)
        {
            string databaseName = $"CustomerOrders{customerId}";

            var shardLocation = new ShardLocation(ShardServer, databaseName);

            // Does this shard already exist?
            Shard shard;

            if (shardMap.TryGetShard(shardLocation, out shard))
            {
                Console.WriteLine($"Found order shard at {databaseName}");
                return(shard);
            }

            // Create the database
            try
            {
                using (var headConn = new SqlConnection(headConnectionString))
                {
                    headConn.Open();

                    Console.WriteLine($"Creating order shard database {databaseName}");
                    headConn.Execute(sql: $@"create database {databaseName} ( SERVICE_OBJECTIVE = ELASTIC_POOL(name = {ShardDatabasePoolName}) )", commandTimeout: 0);
                }
            }
            catch (SqlException ex)
            {
                // Does the database already exist?
                if (ex.Message.Contains("already exists."))
                {
                    Console.WriteLine("Database already exists");
                }
                else
                {
                    throw;
                }
            }

            // Add to the shard map
            Console.WriteLine($"Adding {databaseName} to Shard Map");
            return(shardMap.CreateShard(shardLocation));
        }
コード例 #8
0
ファイル: ShardManager.cs プロジェクト: Pointy-hair/KB
        public bool TryAddShard(string shardName)
        {
            var database = $"{_shardingConfig.ShardPrefix}.{shardName}";
            var location = new ShardLocation(_shardingConfig.ShardServer, database);

            if (!_shardMap.TryGetShard(location, out _))
            {
                lock (_shardLock)
                {
                    if (!_shardMap.TryGetShard(location, out _))
                    {
                        CreateShardDatabase(database);
                        _shardMap.CreateShard(location);
                        return(true);
                    }
                }
            }
            return(false);
        }
コード例 #9
0
        public void DateAddPointMappingDefault()
        {
            CountingCacheStore countingCache = new CountingCacheStore(new CacheStore());

            ShardMapManager smm = new ShardMapManager(
                new SqlShardMapManagerCredentials(Globals.ShardMapManagerConnectionString),
                new SqlStoreConnectionFactory(),
                new StoreOperationFactory(),
                countingCache,
                ShardMapManagerLoadPolicy.Lazy,
                new RetryPolicy(1, TimeSpan.Zero, TimeSpan.Zero, TimeSpan.Zero), RetryBehavior.DefaultRetryBehavior);

            ListShardMap <DateTime> lsm = smm.GetListShardMap <DateTime>(DateTimeShardMapperTests.s_listShardMapName);

            Assert.IsNotNull(lsm);

            ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, DateTimeShardMapperTests.s_shardedDBs[0]);

            Shard s = lsm.CreateShard(sl);

            Assert.IsNotNull(s);

            DateTime val = DateTime.Now;
            PointMapping <DateTime> p1 = lsm.CreatePointMapping(val, s);

            Assert.IsNotNull(p1);

            PointMapping <DateTime> p2 = lsm.GetMappingForKey(val);

            Assert.IsNotNull(p2);
            Assert.AreEqual(0, countingCache.LookupMappingCount);
            Assert.AreEqual(0, countingCache.LookupMappingHitCount);

            // Validate mapping by trying to connect
            using (SqlConnection conn = lsm.OpenConnection(
                       p1,
                       Globals.ShardUserConnectionString,
                       ConnectionOptions.Validate))
            {
            }
        }
コード例 #10
0
        public static void ShardMapManagerLoadTestsInitialize(TestContext testContext)
        {
            // Clear all connection pools.
            SqlConnection.ClearAllPools();

            using (SqlConnection conn = new SqlConnection(Globals.ShardMapManagerTestConnectionString))
            {
                conn.Open();

                // Create ShardMapManager database
                using (SqlCommand cmd = new SqlCommand(
                           string.Format(Globals.CreateDatabaseQuery, Globals.ShardMapManagerDatabaseName),
                           conn))
                {
                    cmd.ExecuteNonQuery();
                }

                // Create shard databases
                for (int i = 0; i < ShardMapManagerLoadTests.s_shardedDBs.Length; i++)
                {
                    using (SqlCommand cmd = new SqlCommand(
                               string.Format(Globals.CreateDatabaseQuery, ShardMapManagerLoadTests.s_shardedDBs[i]),
                               conn))
                    {
                        cmd.ExecuteNonQuery();
                    }
                }

                // cleanup for deadlock monitoring
                foreach (string q in s_deadlockDetectionCleanupQueries)
                {
                    using (SqlCommand cmd = new SqlCommand(q, conn))
                    {
                        try
                        {
                            cmd.ExecuteNonQuery();
                        }
                        catch (SqlException)
                        {
                        }
                    }
                }

                // setup for deadlock monitoring
                foreach (string q in s_deadlockDetectionSetupQueries)
                {
                    using (SqlCommand cmd = new SqlCommand(q, conn))
                    {
                        try
                        {
                            cmd.ExecuteNonQuery();
                        }
                        catch (SqlException)
                        {
                        }
                    }
                }
            }

            // Create shard map manager.
            ShardMapManagerFactory.CreateSqlShardMapManager(
                Globals.ShardMapManagerConnectionString,
                ShardMapManagerCreateMode.ReplaceExisting);

            // Create list shard map.
            ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager(
                Globals.ShardMapManagerConnectionString,
                ShardMapManagerLoadPolicy.Lazy);

            ListShardMap <int> lsm = smm.CreateListShardMap <int>(ShardMapManagerLoadTests.s_listShardMapName);

            Assert.IsNotNull(lsm);

            // Create range shard map.
            RangeShardMap <int> rsm = smm.CreateRangeShardMap <int>(ShardMapManagerLoadTests.s_rangeShardMapName);

            Assert.IsNotNull(rsm);

            // Add 'InitialShardCount' shards to list and range shard map.

            for (int i = 0; i < ShardMapManagerLoadTests.InitialShardCount; i++)
            {
                ShardCreationInfo si = new ShardCreationInfo(
                    new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapManagerLoadTests.s_shardedDBs[i]),
                    ShardStatus.Online);

                Shard sList = lsm.CreateShard(si);
                Assert.IsNotNull(sList);

                Shard sRange = rsm.CreateShard(si);
                Assert.IsNotNull(sRange);
            }

            // Initialize retry policy
            s_retryPolicy = new RetryPolicy <SqlAzureTransientErrorDetectionStrategy>(
                new ExponentialBackoff(5, TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5), TimeSpan.FromMilliseconds(100)));
        }
コード例 #11
0
        public void DateGetPointMappingsForRange()
        {
            ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager(
                Globals.ShardMapManagerConnectionString,
                ShardMapManagerLoadPolicy.Lazy);

            ListShardMap <DateTime> lsm = smm.GetListShardMap <DateTime>(DateTimeShardMapperTests.s_listShardMapName);

            Assert.IsNotNull(lsm);

            Shard s1 = lsm.CreateShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, DateTimeShardMapperTests.s_shardedDBs[0]));

            Assert.IsNotNull(s1);

            Shard s2 = lsm.CreateShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, DateTimeShardMapperTests.s_shardedDBs[1]));

            Assert.IsNotNull(s2);

            DateTime val1 = DateTime.Now.Subtract(TimeSpan.FromMinutes(10));
            PointMapping <DateTime> p1 = lsm.CreatePointMapping(val1, s1);

            Assert.IsNotNull(p1);

            DateTime val2 = DateTime.Now.Subtract(TimeSpan.FromMinutes(20));
            PointMapping <DateTime> p2 = lsm.CreatePointMapping(val2, s1);

            Assert.IsNotNull(p2);

            DateTime val3 = DateTime.Now.Subtract(TimeSpan.FromMinutes(30));
            PointMapping <DateTime> p3 = lsm.CreatePointMapping(val3, s2);

            Assert.IsNotNull(p2);

            // Get all mappings in shard map.
            int count = 0;
            IEnumerable <PointMapping <DateTime> > allMappings = lsm.GetMappings();

            using (IEnumerator <PointMapping <DateTime> > mEnum = allMappings.GetEnumerator())
            {
                while (mEnum.MoveNext())
                {
                    count++;
                }
            }
            Assert.AreEqual(3, count);

            // Get all mappings in specified range.
            Range <DateTime> wantedRange = new Range <DateTime>(val3.AddMinutes(-5), val3.AddMinutes(15));

            count = 0;
            IEnumerable <PointMapping <DateTime> > mappingsInRange = lsm.GetMappings(wantedRange);

            using (IEnumerator <PointMapping <DateTime> > mEnum = mappingsInRange.GetEnumerator())
            {
                while (mEnum.MoveNext())
                {
                    count++;
                }
            }
            Assert.AreEqual(2, count);

            // Get all mappings for a shard.
            count = 0;
            IEnumerable <PointMapping <DateTime> > mappingsForShard = lsm.GetMappings(s1);

            using (IEnumerator <PointMapping <DateTime> > mEnum = mappingsForShard.GetEnumerator())
            {
                while (mEnum.MoveNext())
                {
                    count++;
                }
            }
            Assert.AreEqual(2, count);

            // Get all mappings in specified range for a particular shard.
            count = 0;
            IEnumerable <PointMapping <DateTime> > mappingsInRangeForShard = lsm.GetMappings(wantedRange, s1);

            using (IEnumerator <PointMapping <DateTime> > mEnum = mappingsInRangeForShard.GetEnumerator())
            {
                while (mEnum.MoveNext())
                {
                    count++;
                }
            }
            Assert.AreEqual(1, count);
        }
コード例 #12
0
        public void BasicScenarioListShardMaps()
        {
            bool   success      = true;
            string shardMapName = "PerTenantShardMap";

            try
            {
                #region DeployShardMapManager

                // Deploy shard map manager.
                ShardMapManagerFactory.CreateSqlShardMapManager(
                    Globals.ShardMapManagerConnectionString,
                    ShardMapManagerCreateMode.ReplaceExisting);

                #endregion DeployShardMapManager

                #region GetShardMapManager

                // Obtain shard map manager.
                ShardMapManager shardMapManager = ShardMapManagerFactory.GetSqlShardMapManager(
                    Globals.ShardMapManagerConnectionString,
                    ShardMapManagerLoadPolicy.Lazy);

                #endregion GetShardMapManager

                #region CreateListShardMap

                // Create a single user per-tenant shard map.
                ListShardMap <int> perTenantShardMap = shardMapManager.CreateListShardMap <int>(shardMapName);

                #endregion CreateListShardMap

                #region CreateShardAndPointMapping

                for (int i = 0; i < ScenarioTests.s_perTenantDBs.Length; i++)
                {
                    // Create the shard.
                    Shard s = perTenantShardMap.CreateShard(
                        new ShardLocation(
                            Globals.ShardMapManagerTestsDatasourceName,
                            ScenarioTests.s_perTenantDBs[i]));

                    // Create the mapping.
                    PointMapping <int> p = perTenantShardMap.CreatePointMapping(
                        i + 1,
                        s);
                }

                #endregion CreateShardAndPointMapping

                #region UpdatePointMapping

                // Let's add another point 5 and map it to same shard as 1.

                PointMapping <int> mappingForOne = perTenantShardMap.GetMappingForKey(1);

                PointMapping <int> mappingForFive = perTenantShardMap.CreatePointMapping(5, mappingForOne.Shard);

                Assert.IsTrue(mappingForOne.Shard.Location.Equals(mappingForFive.Shard.Location));

                // Move 3 from PerTenantDB3 to PerTenantDB for 5.
                PointMapping <int> mappingToUpdate = perTenantShardMap.GetMappingForKey(3);
                bool updateFailed = false;

                // Try updating that shard in the mapping without taking it offline first.
                try
                {
                    perTenantShardMap.UpdateMapping(
                        mappingToUpdate,
                        new PointMappingUpdate
                    {
                        Shard = mappingForFive.Shard
                    });
                }
                catch (ShardManagementException smme)
                {
                    Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingIsNotOffline);
                    updateFailed = true;
                }

                Assert.IsTrue(updateFailed);

                // Perform the actual update.
                PointMapping <int> newMappingFor3 = MarkMappingOfflineAndUpdateShard <int>(
                    perTenantShardMap, mappingToUpdate, mappingForFive.Shard);

                // Verify that update succeeded.
                Assert.IsTrue(newMappingFor3.Shard.Location.Equals(mappingForFive.Shard.Location));
                Assert.IsTrue(newMappingFor3.Status == MappingStatus.Offline);

                // Update custom field for the updated mapping.
                //PointMapping<int> veryNewMappingFor3 = perTenantShardMap.UpdatePointMapping(
                //    newMappingFor3,
                //    new PointMappingUpdate
                //    {
                //        Custom = new byte[] { 0x12, 0x34 }
                //    });

                #endregion UpdatePointMapping

                #region DeleteMapping

                // Find the shard by location.
                PointMapping <int> mappingToDelete = perTenantShardMap.GetMappingForKey(5);
                bool operationFailed = false;

                // Try to delete mapping while it is online, the delete should fail.
                try
                {
                    perTenantShardMap.DeleteMapping(mappingToDelete);
                }
                catch (ShardManagementException smme)
                {
                    operationFailed = true;
                    Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingIsNotOffline);
                }

                Trace.Assert(operationFailed);

                // The mapping must be taken offline first before it can be deleted.
                mappingToDelete = perTenantShardMap.UpdateMapping(
                    mappingToDelete,
                    new PointMappingUpdate
                {
                    Status = MappingStatus.Offline,
                });

                perTenantShardMap.DeleteMapping(mappingToDelete);

                // Verify that delete succeeded.
                try
                {
                    PointMapping <int> deletedMapping = perTenantShardMap.GetMappingForKey(5);
                }
                catch (ShardManagementException smme)
                {
                    Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingNotFoundForKey);
                }

                #endregion DeleteMapping

                #region OpenConnection without Validation

                using (SqlConnection conn = perTenantShardMap.OpenConnectionForKey(
                           2,
                           Globals.ShardUserConnectionString,
                           ConnectionOptions.None))
                {
                }

                #endregion OpenConnection without Validation

                #region OpenConnection with Validation

                // Use the stale state of "shardToUpdate" shard & see if validation works.
                bool validationFailed = false;
                try
                {
                    using (SqlConnection conn = perTenantShardMap.OpenConnection(
                               mappingToDelete,
                               Globals.ShardUserConnectionString,
                               ConnectionOptions.Validate))
                    {
                    }
                }
                catch (ShardManagementException smme)
                {
                    validationFailed = true;
                    Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingDoesNotExist);
                }

                Assert.AreEqual(validationFailed, true);

                #endregion OpenConnection with Validation

                #region OpenConnection without Validation and Empty Cache

                // Obtain a new ShardMapManager instance
                ShardMapManager newShardMapManager = ShardMapManagerFactory.GetSqlShardMapManager(
                    Globals.ShardMapManagerConnectionString,
                    ShardMapManagerLoadPolicy.Lazy);

                // Get the ShardMap
                ListShardMap <int> newPerTenantShardMap = newShardMapManager.GetListShardMap <int>(shardMapName);

                using (SqlConnection conn = newPerTenantShardMap.OpenConnectionForKey(
                           2,
                           Globals.ShardUserConnectionString,
                           ConnectionOptions.None))
                {
                }

                #endregion

                #region OpenConnection with Validation and Empty Cache

                // Use the stale state of "shardToUpdate" shard & see if validation works.
                validationFailed = false;

                // Obtain a new ShardMapManager instance
                newShardMapManager = ShardMapManagerFactory.GetSqlShardMapManager(
                    Globals.ShardMapManagerConnectionString,
                    ShardMapManagerLoadPolicy.Lazy);

                // Get the ShardMap
                newPerTenantShardMap = newShardMapManager.GetListShardMap <int>(shardMapName);

                // Create a new mapping
                PointMapping <int> newMappingToDelete = newPerTenantShardMap.CreatePointMapping(6,
                                                                                                newPerTenantShardMap.GetMappingForKey(1).Shard);

                // Delete the mapping
                newMappingToDelete = newPerTenantShardMap.UpdateMapping(
                    newMappingToDelete,
                    new PointMappingUpdate
                {
                    Status = MappingStatus.Offline,
                });

                newPerTenantShardMap.DeleteMapping(newMappingToDelete);

                try
                {
                    using (SqlConnection conn = newPerTenantShardMap.OpenConnection(
                               newMappingToDelete,
                               Globals.ShardUserConnectionString,
                               ConnectionOptions.Validate))
                    {
                    }
                }
                catch (ShardManagementException smme)
                {
                    validationFailed = true;
                    Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingDoesNotExist);
                }

                Assert.AreEqual(validationFailed, true);

                #endregion

                #region OpenConnectionAsync without Validation

                using (SqlConnection conn = perTenantShardMap.OpenConnectionForKeyAsync(
                           2,
                           Globals.ShardUserConnectionString,
                           ConnectionOptions.None).Result)
                {
                }

                #endregion

                #region OpenConnectionAsync with Validation

                // Use the stale state of "shardToUpdate" shard & see if validation works.
                validationFailed = false;
                try
                {
                    using (SqlConnection conn = perTenantShardMap.OpenConnectionAsync(
                               mappingToDelete,
                               Globals.ShardUserConnectionString,
                               ConnectionOptions.Validate).Result)
                    {
                    }
                }
                catch (AggregateException ex)
                {
                    ShardManagementException smme = ex.InnerException as ShardManagementException;
                    if (smme != null)
                    {
                        validationFailed = true;
                        Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingDoesNotExist);
                    }
                }

                Assert.AreEqual(validationFailed, true);

                #endregion

                #region OpenConnectionAsync without Validation and Empty Cache

                // Obtain a new ShardMapManager instance
                newShardMapManager = ShardMapManagerFactory.GetSqlShardMapManager(
                    Globals.ShardMapManagerConnectionString,
                    ShardMapManagerLoadPolicy.Lazy);

                // Get the ShardMap
                newPerTenantShardMap = newShardMapManager.GetListShardMap <int>(shardMapName);
                using (SqlConnection conn = newPerTenantShardMap.OpenConnectionForKeyAsync(
                           2,
                           Globals.ShardUserConnectionString,
                           ConnectionOptions.None).Result)
                {
                }

                #endregion

                #region OpenConnectionAsync with Validation and Empty Cache

                // Use the stale state of "shardToUpdate" shard & see if validation works.
                validationFailed = false;

                // Obtain a new ShardMapManager instance
                newShardMapManager = ShardMapManagerFactory.GetSqlShardMapManager(
                    Globals.ShardMapManagerConnectionString,
                    ShardMapManagerLoadPolicy.Lazy);

                // Get the ShardMap
                newPerTenantShardMap = newShardMapManager.GetListShardMap <int>(shardMapName);

                // Create a new mapping
                newMappingToDelete = newPerTenantShardMap.CreatePointMapping(6,
                                                                             newPerTenantShardMap.GetMappingForKey(1).Shard);

                // Delete the mapping
                newMappingToDelete = newPerTenantShardMap.UpdateMapping(
                    newMappingToDelete,
                    new PointMappingUpdate
                {
                    Status = MappingStatus.Offline,
                });

                newPerTenantShardMap.DeleteMapping(newMappingToDelete);

                try
                {
                    using (SqlConnection conn = newPerTenantShardMap.OpenConnectionAsync(
                               newMappingToDelete,
                               Globals.ShardUserConnectionString,
                               ConnectionOptions.Validate).Result)
                    {
                    }
                }
                catch (AggregateException ex)
                {
                    ShardManagementException smme = ex.InnerException as ShardManagementException;
                    if (smme != null)
                    {
                        validationFailed = true;
                        Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingDoesNotExist);
                    }
                }

                Assert.AreEqual(validationFailed, true);

                #endregion

                #region LookupPointMapping

                // Perform tenant lookup. This will populate the cache.
                for (int i = 0; i < ScenarioTests.s_perTenantDBs.Length; i++)
                {
                    PointMapping <int> result = shardMapManager
                                                .GetListShardMap <int>("PerTenantShardMap")
                                                .GetMappingForKey(i + 1);

                    Trace.WriteLine(result.Shard.Location);

                    // Since we moved 3 to database 1 earlier.
                    Assert.IsTrue(result.Shard.Location.Database == ScenarioTests.s_perTenantDBs[i != 2 ? i : 0]);
                }

                // Perform tenant lookup. This will read from the cache.
                for (int i = 0; i < ScenarioTests.s_perTenantDBs.Length; i++)
                {
                    PointMapping <int> result = shardMapManager
                                                .GetListShardMap <int>("PerTenantShardMap")
                                                .GetMappingForKey(i + 1);

                    Trace.WriteLine(result.Shard.Location);

                    // Since we moved 3 to database 1 earlier.
                    Assert.IsTrue(result.Shard.Location.Database == ScenarioTests.s_perTenantDBs[i != 2 ? i : 0]);
                }

                #endregion LookupPointMapping
            }
            catch (ShardManagementException smme)
            {
                success = false;

                Trace.WriteLine(String.Format("Error Category: {0}", smme.ErrorCategory));
                Trace.WriteLine(String.Format("Error Code    : {0}", smme.ErrorCode));
                Trace.WriteLine(String.Format("Error Message : {0}", smme.Message));

                if (smme.InnerException != null)
                {
                    Trace.WriteLine(String.Format("Storage Error Message : {0}", smme.InnerException.Message));

                    if (smme.InnerException.InnerException != null)
                    {
                        Trace.WriteLine(String.Format("SqlClient Error Message : {0}", smme.InnerException.InnerException.Message));
                    }
                }
            }

            Assert.IsTrue(success);
        }
コード例 #13
0
        private bool RefreshShardListMap(List <Tuple <long, string> > ListMappings = null)
        {
            try
            {
                string shardServer1 = WingtipTicketApp.Config.PrimaryDatabaseServer;
                string shardServer2 = WingtipTicketApp.Config.ShardDatabaseServer;
                string ticketsDbName = WingtipTicketApp.Config.TicketsDbName;
                Shard  shard1 = null, shard2 = null;
                PointMapping <long> lmpg;

                // check if shard map manager exists and if not, create it (Idempotent / tolerant of re-execute)
                if (!ShardMapManager.TryGetListShardMap(mapManagerName, out lsm))
                {
                    lsm = ShardMapManager.CreateListShardMap <long>(mapManagerName);
                }

                try
                {
                    // check if shard exists and if not, create it (Idempotent / tolerant of re-execute)
                    if (!lsm.TryGetShard(new ShardLocation(shardServer1, ticketsDbName), out shard1))
                    {
                        shard1 = lsm.CreateShard(new ShardLocation(shardServer1, ticketsDbName));
                    }
                }
                catch // sometimes, it may throw an error stating that a concurrent user recently changed some settings.
                      //This is a retry logic to cover this scenario.
                {
                    Thread.Sleep(500);
                    // check if shard map manager exists and if not, create it (Idempotent / tolerant of re-execute)
                    if (!ShardMapManager.TryGetListShardMap(mapManagerName, out lsm))
                    {
                        lsm = ShardMapManager.CreateListShardMap <long>(mapManagerName);
                    }
                    // check if shard exists and if not, create it (Idempotent / tolerant of re-execute)
                    if (!lsm.TryGetShard(new ShardLocation(shardServer1, ticketsDbName), out shard1))
                    {
                        shard1 = lsm.CreateShard(new ShardLocation(shardServer1, ticketsDbName));
                    }
                }
                if (!lsm.TryGetShard(new ShardLocation(shardServer2, ticketsDbName), out shard2))
                {
                    shard2 = lsm.CreateShard(new ShardLocation(shardServer2, ticketsDbName));
                }

                // Check if mapping exists and if not, create it (Idempotent / tolerant of re-execute)

                if (ListMappings != null)
                {
                    foreach (Tuple <long, string> mapping in ListMappings)
                    {
                        if (!lsm.TryGetMappingForKey(mapping.Item1, out lmpg))
                        {
                            if (mapping.Item2 == shardServer1)
                            {
                                lsm.CreatePointMapping(new PointMappingCreationInfo <long>(mapping.Item1, shard1, MappingStatus.Online));
                            }
                            else if (mapping.Item2 == shardServer2)
                            {
                                lsm.CreatePointMapping(new PointMappingCreationInfo <long>(mapping.Item1, shard2, MappingStatus.Online));
                            }
                        }
                    }
                }
                return(true);
            }
            catch { return(false); }
        }