Skip to content

Commit c5eb62f

Browse files
jpoveyasosMikeGore
authored andcommitted
Do not validate Database or Collection request units. (#43)
* Do not validate Database or Collection request units. - Request units are not required to create the database or the collection. - If the user sets up the database with both Database and Collection RUs as null then cosmos will create a database without shared throughput and the collection with the default 400 RUs. - Collection request units can be set higher than the database request units. - If the user sets up the database with the collection RUs higher than the database then the collection will be created with its own dedicated throughput seperate from the database throughput. * Update StorageEngineFactory UseSharedThroughput method name to UseDatabase - The name UseSharedThroughput is specific to database request units but the method allows users to change options to other database settings - Update the name of the method to be more inline with other builder method names
1 parent 60acd0e commit c5eb62f

4 files changed

Lines changed: 75 additions & 41 deletions

File tree

src/SimpleEventStore/SimpleEventStore.AzureDocumentDb.Tests/AzureDocumentDBEventStoreInitializing.cs

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public async Task when_initializing_with_a_time_to_live_it_is_set()
7272
[Test]
7373
public async Task when_using_shared_throughput_it_is_set_at_a_database_level()
7474
{
75-
const int throughput = 800;
75+
const int dbThroughput = 800;
7676
var collectionName = "SharedCollection_" + Guid.NewGuid();
7777

7878
var storageEngine = await StorageEngineFactory.Create(DatabaseName,
@@ -81,13 +81,18 @@ public async Task when_using_shared_throughput_it_is_set_at_a_database_level()
8181
collectionOptions.CollectionName = collectionName;
8282
collectionOptions.CollectionRequestUnits = null;
8383
},
84-
databaseOptions => { databaseOptions.DatabaseRequestUnits = throughput; });
84+
databaseOptions =>
85+
{
86+
databaseOptions.DatabaseRequestUnits = dbThroughput;
87+
});
8588

8689
await storageEngine.Initialise();
8790

88-
Assert.AreEqual(throughput, await GetDatabaseThroughput());
91+
Assert.AreEqual(dbThroughput, await GetDatabaseThroughput());
92+
Assert.AreEqual(null, await GetCollectionThroughput(collectionName));
8993
}
9094

95+
9196
[Test]
9297
public async Task when_throughput_is_set_offer_is_updated()
9398
{
@@ -109,6 +114,55 @@ public async Task when_throughput_is_set_offer_is_updated()
109114
Assert.AreEqual(collectionThroughput, await GetCollectionThroughput(collectionName));
110115
}
111116

117+
[TestCase(null, null, null, 400)]
118+
[TestCase(600, null, 600, null)]
119+
[TestCase(null, 600, null, 600)]
120+
[TestCase(600, 600, 600, 600)]
121+
[TestCase(600, 1000, 600, 1000)]
122+
[TestCase(1000, 600, 1000, 600)]
123+
public async Task set_database_and_collection_throughput_when_database_has_not_been_created(int? dbThroughput, int? collectionThroughput, int? expectedDbThroughput, int? expectedCollectionThroughput)
124+
{
125+
var collectionName = "CollectionThroughput_" + Guid.NewGuid();
126+
127+
var storageEngine = await StorageEngineFactory.Create(DatabaseName,
128+
collectionOptions =>
129+
{
130+
collectionOptions.CollectionName = collectionName;
131+
collectionOptions.CollectionRequestUnits = collectionThroughput;
132+
},
133+
databaseOptions =>
134+
{
135+
databaseOptions.DatabaseRequestUnits = dbThroughput;
136+
});
137+
138+
await storageEngine.Initialise();
139+
140+
Assert.AreEqual(expectedDbThroughput, await GetDatabaseThroughput());
141+
Assert.AreEqual(expectedCollectionThroughput, await GetCollectionThroughput(collectionName));
142+
}
143+
144+
145+
[TestCase(null, 500, null)]
146+
[TestCase(1000, 500, 1000)]
147+
public async Task set_database_and_collection_throughput_when_database_has_already_been_created(int? collectionThroughput, int? expectedDbThroughput, int? expectedCollectionThroughput)
148+
{
149+
const int existingDbThroughput = 500;
150+
await CreateDatabase(existingDbThroughput);
151+
var collectionName = "CollectionThroughput_" + Guid.NewGuid();
152+
153+
var storageEngine = await StorageEngineFactory.Create(DatabaseName,
154+
collectionOptions =>
155+
{
156+
collectionOptions.CollectionName = collectionName;
157+
collectionOptions.CollectionRequestUnits = collectionThroughput;
158+
});
159+
160+
await storageEngine.Initialise();
161+
162+
Assert.AreEqual(expectedDbThroughput, await GetDatabaseThroughput());
163+
Assert.AreEqual(expectedCollectionThroughput, await GetCollectionThroughput(collectionName));
164+
}
165+
112166
private static async Task InitialiseStorageEngine(string collectionName, int collectionThroughput,
113167
int dbThroughput)
114168
{
@@ -123,23 +177,33 @@ private static async Task InitialiseStorageEngine(string collectionName, int col
123177
await storageEngine.Initialise();
124178
}
125179

126-
public async Task<int> GetCollectionThroughput(string collectionName)
180+
public async Task<int?> GetCollectionThroughput(string collectionName)
127181
{
128182
var collection = await client.ReadDocumentCollectionAsync(UriFactory.CreateDocumentCollectionUri(DatabaseName, collectionName));
129183

130184
var collectionOffer = client.CreateOfferQuery().Where(x => x.ResourceLink == collection.Resource.SelfLink)
131-
.AsEnumerable().First();
185+
.AsEnumerable().FirstOrDefault();
132186

133-
return ((OfferV2)collectionOffer).Content.OfferThroughput;
187+
return ((OfferV2) collectionOffer)?.Content.OfferThroughput;
134188
}
135189

136-
public async Task<int> GetDatabaseThroughput()
190+
public async Task<int?> GetDatabaseThroughput()
137191
{
138192
var db = await client.ReadDatabaseAsync(databaseUri);
139193
var dbOffer = client.CreateOfferQuery().Where(x => x.ResourceLink == db.Resource.SelfLink).AsEnumerable()
140-
.First();
194+
.FirstOrDefault();
141195

142-
return ((OfferV2)dbOffer).Content.OfferThroughput;
196+
return ((OfferV2)dbOffer)?.Content.OfferThroughput;
197+
}
198+
199+
private Task CreateDatabase(int databaseRequestUnits)
200+
{
201+
return client.CreateDatabaseIfNotExistsAsync(
202+
new Database { Id = DatabaseName },
203+
new RequestOptions
204+
{
205+
OfferThroughput = databaseRequestUnits
206+
});
143207
}
144208
}
145209
}

src/SimpleEventStore/SimpleEventStore.AzureDocumentDb.Tests/AzureDocumentDbStorageEngineBuilderTests.cs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,6 @@ public void when_setting_the_jsonserializationsettings_it_must_be_supplied()
5454
Assert.Throws<ArgumentNullException>(() => builder.UseJsonSerializerSettings(null));
5555
}
5656

57-
[Test]
58-
public void throughput_must_be_set_in_one_location()
59-
{
60-
var builder = new AzureDocumentDbStorageEngineBuilder(CreateClient(), "Test")
61-
.UseSharedThroughput(o => { o.DatabaseRequestUnits = null; })
62-
.UseCollection(o => o.CollectionRequestUnits = null);
63-
64-
Assert.Throws<ArgumentException>(() => builder.Build());
65-
}
66-
67-
[Test]
68-
public void collection_throughput_cannot_be_greater_than_database_throughput()
69-
{
70-
var builder = new AzureDocumentDbStorageEngineBuilder(CreateClient(), "Test")
71-
.UseSharedThroughput(o => { o.DatabaseRequestUnits = 400; })
72-
.UseCollection(o => o.CollectionRequestUnits = 500);
73-
74-
Assert.Throws<ArgumentException>(() => builder.Build());
75-
}
76-
7757
private static DocumentClient CreateClient()
7858
{
7959
var client = new DocumentClient(new Uri("https://localhost:8081/"), "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==");

src/SimpleEventStore/SimpleEventStore.AzureDocumentDb.Tests/StorageEngineFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ internal static Task<IStorageEngine> Create(string databaseName, JsonSerializerS
3232
var client = DocumentClientFactory.Create(settings);
3333

3434
return new AzureDocumentDbStorageEngineBuilder(client, databaseName)
35-
.UseSharedThroughput(o =>
35+
.UseDatabase(o =>
3636
{
3737
databaseOverrides?.Invoke(o);
3838
})

src/SimpleEventStore/SimpleEventStore.AzureDocumentDb/AzureDocumentDbStorageEngineBuilder.cs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public AzureDocumentDbStorageEngineBuilder UseJsonSerializerSettings(JsonSeriali
5454
return this;
5555
}
5656

57-
public AzureDocumentDbStorageEngineBuilder UseSharedThroughput(Action<DatabaseOptions> action)
57+
public AzureDocumentDbStorageEngineBuilder UseDatabase(Action<DatabaseOptions> action)
5858
{
5959
Guard.IsNotNull(nameof(action), action);
6060

@@ -64,16 +64,6 @@ public AzureDocumentDbStorageEngineBuilder UseSharedThroughput(Action<DatabaseOp
6464

6565
public IStorageEngine Build()
6666
{
67-
if (this.collectionOptions.CollectionRequestUnits == null && this.databaseOptions.DatabaseRequestUnits == null)
68-
{
69-
throw new ArgumentException("Request units must be set in at least one location");
70-
}
71-
72-
if (this.collectionOptions.CollectionRequestUnits > this.databaseOptions.DatabaseRequestUnits)
73-
{
74-
throw new ArgumentException("Unable to allocate more RUs to the collection than database");
75-
}
76-
7767
var engine = new AzureDocumentDbStorageEngine(this.client, this.databaseName, this.collectionOptions,this.databaseOptions, this.loggingOptions, this.typeMap, JsonSerializer.Create(this.jsonSerializerSettings));
7868
return engine;
7969
}

0 commit comments

Comments
 (0)