public void ShouldReturnIdsFromThirdBatchIfSecondBatchTakenByAnotherGenerator() { // Arrange var account = CloudStorageAccount.DevelopmentStorageAccount; using (var testScope = new TestScope(account)) { var store1 = new BlobOptimisticDataStore(account, testScope.ContainerName); var generator1 = new UniqueIdGenerator(store1) { BatchSize = 3 }; var store2 = new BlobOptimisticDataStore(account, testScope.ContainerName); var generator2 = new UniqueIdGenerator(store2) { BatchSize = 3 }; // Act generator1.NextId(testScope.IdScopeName); //1 generator1.NextId(testScope.IdScopeName); //2 generator1.NextId(testScope.IdScopeName); //3 generator2.NextId(testScope.IdScopeName); //4 var lastId = generator1.NextId(testScope.IdScopeName); //7 // Assert Assert.AreEqual(7, lastId); } }
protected override IOptimisticDataStore BuildStore(TestScope scope) { var blobOptimisticDataStore = new BlobOptimisticDataStore(storageAccount, scope.ContainerName); blobOptimisticDataStore.Init().GetAwaiter().GetResult(); return(blobOptimisticDataStore); }
public static long GetUniqueId() { if (_instance != null) { return(_instance.NextId("identificador")); } var connectionString = "DefaultEndpointsProtocol=https;AccountName=hefesoftautentication;AccountKey=G943HAZgCsBqPwANE8tfKWaPq0FDM68gaUH4fCQz+W1NTGOBswZvQka1SFnquoYv+xrcPQQew7LQFcelJHycxw=="; var storageAccount = CloudStorageAccount.Parse(connectionString); IOptimisticDataStore blobDataStore = new BlobOptimisticDataStore(storageAccount, "Consecutivos"); _instance = new UniqueIdGenerator(blobDataStore); return(_instance.NextId("identificador")); }
public CoreIdGenerator(IConfiguration config) { var storageConnection = config.GetSection("ConnectionStrings:AzureBlobStorage").Get <BlobStorageConnection>(); var batchSize = config.GetValue <int>("IdGeneratorBatchSize"); _cloudStorageAccount = Microsoft.Azure.Storage.CloudStorageAccount.Parse(storageConnection.ConnectionString); _containerName = storageConnection.ContainerName; _dataStore = BlobOptimisticDataStore.CreateAsync(_cloudStorageAccount, _containerName).Result; _generator = new UniqueIdGenerator(_dataStore) { BatchSize = batchSize }; }
public AutoNumberGenerator(string connectionString, string containerName, int batchSize, int maxWriteAttempts) { var blobStorageAccount = CloudStorageAccount.Parse(connectionString); var blobOptimisticDataStore = new BlobOptimisticDataStore(blobStorageAccount, containerName); var options = new AutoNumberOptions { BatchSize = batchSize, MaxWriteAttempts = maxWriteAttempts }; IOptions <AutoNumberOptions> optionsProvider = new OptionsWrapper <AutoNumberOptions>(options); generator = new UniqueIdGenerator(blobOptimisticDataStore, optionsProvider); }
public void ConfigureServices(IServiceCollection services) { // Enable header based versioning services.AddApiVersioning(o => { o.ReportApiVersions = true; o.AssumeDefaultVersionWhenUnspecified = true; o.DefaultApiVersion = new ApiVersion(1, 0); o.ApiVersionReader = new HeaderApiVersionReader("api-version"); }) .AddSwaggerGen(setupAction => { setupAction.SwaggerDoc("v1", new OpenApiInfo { Title = APIName, Version = "v1" }); var xmlCommentsFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlCommentsFullPath = Path.Combine(AppContext.BaseDirectory, xmlCommentsFile); setupAction.IncludeXmlComments(xmlCommentsFullPath); }) .AddServicesRegistrations() .AddRepositoriesRegistrations() .AddProvidersRegistrations() // SQL Server configuration .AddDbContext <AppDBContext>(opts => opts.UseSqlServer(Configuration.GetConnectionString("UrlShortnerDB"))) // IOptimisticDataStore for SnowMaker .AddSingleton <IOptimisticDataStore>(sp => { var cloudStorageAccount = CloudStorageAccount.Parse(Configuration["AppSettings:SnowMakerConfiguration:StorageAccountConnection"]); // I know it is bad practice but as per my knowledge there is no support for async resolve option in Microsoft DI return(BlobOptimisticDataStore.CreateAsync(cloudStorageAccount, UniqueKeysStorageContainerName).Result); }) //SnowMaker UniqueIdGenerator .AddSingleton <IUniqueIdGenerator>(sp => { var dataStore = sp.GetService <IOptimisticDataStore>(); if (dataStore != null) { return(new UniqueIdGenerator(dataStore)); } return(null); }); services.AddAutoMapper(typeof(Startup)); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
public void ShouldSupportUsingOneGeneratorFromMultipleThreads() { // Arrange var account = CloudStorageAccount.DevelopmentStorageAccount; using (var testScope = new TestScope(account)) { var store = new BlobOptimisticDataStore(account, testScope.ContainerName); var generator = new UniqueIdGenerator(store) { BatchSize = 1000 }; const int testLength = 10000; // Act var generatedIds = new ConcurrentQueue <long>(); var threadIds = new ConcurrentQueue <int>(); var scopeName = testScope.IdScopeName; Parallel.For( 0, testLength, new ParallelOptions { MaxDegreeOfParallelism = 10 }, i => { generatedIds.Enqueue(generator.NextId(scopeName)); threadIds.Enqueue(Thread.CurrentThread.ManagedThreadId); }); // Assert we generated the right count of ids Assert.AreEqual(testLength, generatedIds.Count); // Assert there were no duplicates Assert.IsFalse(generatedIds.GroupBy(n => n).Where(g => g.Count() != 1).Any()); // Assert we used multiple threads var uniqueThreadsUsed = threadIds.Distinct().Count(); if (uniqueThreadsUsed == 1) { Assert.Inconclusive("The test failed to actually utilize multiple threads"); } } }
public void ConnectToStorageAccountAndInitializeGenerators() { var cloudStorageAccount = CloudStorageAccount.Parse(_connectionString); var dataStoreForUsers = new BlobOptimisticDataStore(cloudStorageAccount, UsersContainer); _generatorForUsers = new UniqueIdGenerator(dataStoreForUsers) { BatchSize = BatchSize, MaxWriteAttempts = MaxWriteAttempts }; var dataStoreForMessages = new BlobOptimisticDataStore(cloudStorageAccount, MessagesContainer); _generatorForMessages = new UniqueIdGenerator(dataStoreForMessages) { BatchSize = BatchSize, MaxWriteAttempts = MaxWriteAttempts }; }
public void ShouldInitializeBlobForFirstIdInNewScope() { // Arrange var account = CloudStorageAccount.DevelopmentStorageAccount; using (var testScope = new TestScope(account)) { var store = new BlobOptimisticDataStore(account, testScope.ContainerName); var generator = new UniqueIdGenerator(store) { BatchSize = 3 }; // Act generator.NextId(testScope.IdScopeName); //1 // Assert Assert.AreEqual("4", testScope.ReadCurrentBlobValue()); } }
public void ShouldReturnOneForFirstIdInNewScope() { // Arrange var account = CloudStorageAccount.DevelopmentStorageAccount; using (var testScope = new TestScope(account)) { var store = new BlobOptimisticDataStore(account, testScope.ContainerName); var generator = new UniqueIdGenerator(store) { BatchSize = 3 }; // Act var generatedId = generator.NextId(testScope.IdScopeName); // Assert Assert.AreEqual(1, generatedId); } }
public void ShouldReturnIdsAcrossMultipleGenerators() { // Arrange var account = CloudStorageAccount.DevelopmentStorageAccount; using (var testScope = new TestScope(account)) { var store1 = new BlobOptimisticDataStore(account, testScope.ContainerName); var generator1 = new UniqueIdGenerator(store1) { BatchSize = 3 }; var store2 = new BlobOptimisticDataStore(account, testScope.ContainerName); var generator2 = new UniqueIdGenerator(store2) { BatchSize = 3 }; // Act var generatedIds = new[] { generator1.NextId(testScope.IdScopeName), //1 generator1.NextId(testScope.IdScopeName), //2 generator1.NextId(testScope.IdScopeName), //3 generator2.NextId(testScope.IdScopeName), //4 generator1.NextId(testScope.IdScopeName), //7 generator2.NextId(testScope.IdScopeName), //5 generator2.NextId(testScope.IdScopeName), //6 generator2.NextId(testScope.IdScopeName), //10 generator1.NextId(testScope.IdScopeName), //8 generator1.NextId(testScope.IdScopeName) //9 }; // Assert CollectionAssert.AreEqual( new[] { 1, 2, 3, 4, 7, 5, 6, 10, 8, 9 }, generatedIds); } }
public void ShouldUpdateBlobWhenGeneratingNextIdAfterEndOfBatch() { // Arrange var account = CloudStorageAccount.DevelopmentStorageAccount; using (var testScope = new TestScope(account)) { var store = new BlobOptimisticDataStore(account, testScope.ContainerName); var generator = new UniqueIdGenerator(store) { BatchSize = 3 }; // Act generator.NextId(testScope.IdScopeName); //1 generator.NextId(testScope.IdScopeName); //2 generator.NextId(testScope.IdScopeName); //3 generator.NextId(testScope.IdScopeName); //4 // Assert Assert.AreEqual("7", testScope.ReadCurrentBlobValue()); } }
protected override async Task <IOptimisticDataStore> BuildStoreAsync(TestScope scope) { return(await BlobOptimisticDataStore.CreateAsync(storageAccount, scope.ContainerName)); }