Skip to content

Commit

Permalink
Implement ctor accepting a connection string (#14674)
Browse files Browse the repository at this point in the history
* Implement ctor accepting a connection string

* change version

* formatting

* pr comments

* export api

* connectionstring tests
  • Loading branch information
christothes authored Aug 28, 2020
1 parent 01f5c02 commit 4859b7a
Show file tree
Hide file tree
Showing 19 changed files with 791 additions and 55 deletions.
17 changes: 17 additions & 0 deletions sdk/core/Azure.Core/src/Shared/ConnectionString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ internal sealed class ConnectionString
return new ConnectionString(ParseSegments(connectionString, segmentSeparator, keywordValueSeparator), segmentSeparator, keywordValueSeparator);
}

public static ConnectionString Empty(string segmentSeparator = ";", string keywordValueSeparator = "=") =>
new ConnectionString(new Dictionary<string, string>(), segmentSeparator, keywordValueSeparator);

private ConnectionString(Dictionary<string, string> pairs, string pairSeparator, string keywordValueSeparator)
{
_pairs = pairs;
Expand All @@ -34,6 +37,12 @@ public string GetRequired(string keyword) =>
public string? GetNonRequired(string keyword) =>
_pairs.TryGetValue(keyword, out var value) ? value : null;

public bool TryGetSegmentValue(string keyword, out string value) =>
_pairs.TryGetValue(keyword, out value);

public bool ContainsSegmentKey(string keyword) =>
_pairs.ContainsKey(keyword);

public void Replace(string keyword, string value)
{
if (_pairs.ContainsKey(keyword))
Expand All @@ -42,8 +51,16 @@ public void Replace(string keyword, string value)
}
}

public void Add(string keyword, string value) =>
_pairs.Add(keyword, value);

public override string ToString()
{
if (_pairs.Count == 0)
{
return string.Empty;
}

var stringBuilder = new StringBuilder();
var isFirst = true;
foreach (KeyValuePair<string, string> pair in _pairs)
Expand Down
30 changes: 29 additions & 1 deletion sdk/core/Azure.Core/tests/ConnectionStringTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,27 @@ public void RequiredKey()
{
var connectionString = ConnectionString.Parse("x=y");
Assert.AreEqual("y", connectionString.GetRequired("x"));
Assert.Throws<InvalidOperationException>(() => connectionString.GetRequired("y"));
Assert.Throws<InvalidOperationException>(() => connectionString.GetRequired("notpresent"));
}

[Test]
public void TryGetSegmentValue()
{
var connectionString = ConnectionString.Parse("x=y");
Assert.That(connectionString.TryGetSegmentValue("x", out var value));
Assert.That(value, Is.EqualTo("y"));
Assert.That(connectionString.TryGetSegmentValue("notpresent", out _), Is.False);
}

[Test]
public void Add()
{
var connectionString = ConnectionString.Parse("x=y");
Assert.AreEqual("y", connectionString.GetRequired("x"));
Assert.Throws<InvalidOperationException>(() => connectionString.GetRequired("notpresent"));

connectionString.Add("notpresent", "someValue");
Assert.DoesNotThrow(() => connectionString.GetRequired("notpresent"));
}

[Test]
Expand All @@ -82,5 +102,13 @@ public void Replace()
Assert.AreEqual("z", connectionString.GetNonRequired("x"));
Assert.AreEqual(null, connectionString.GetNonRequired("y"));
}

[Test]
public void EmtptyProducesEmptyString()
{
var connectionSring = ConnectionString.Empty();

Assert.That(connectionSring.ToString(), Is.EqualTo(string.Empty));
}
}
}
2 changes: 1 addition & 1 deletion sdk/tables/Azure.Data.Tables/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Release History

## 1.0.0-preview.1 (Unreleased)
## 3.0.0-beta.1 (Unreleased)
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ public partial interface ITableEntity
public partial class TableClient
{
protected TableClient() { }
public TableClient(string tableName, System.Uri endpoint, Azure.Data.Tables.TableClientOptions options = null) { }
public TableClient(string tableName, System.Uri endpoint, Azure.Data.Tables.TableSharedKeyCredential credential) { }
public TableClient(string tableName, System.Uri endpoint, Azure.Data.Tables.TableSharedKeyCredential credential, Azure.Data.Tables.TableClientOptions options = null) { }
public TableClient(string connectionString, string tableName) { }
public TableClient(string connectionString, string tableName, Azure.Data.Tables.TableClientOptions options = null) { }
public TableClient(System.Uri endpoint, string tableName, Azure.Data.Tables.TableClientOptions options = null) { }
public TableClient(System.Uri endpoint, string tableName, Azure.Data.Tables.TableSharedKeyCredential credential) { }
public TableClient(System.Uri endpoint, string tableName, Azure.Data.Tables.TableSharedKeyCredential credential, Azure.Data.Tables.TableClientOptions options = null) { }
public virtual System.Threading.Tasks.Task<Azure.Response> AddEntityAsync<T>(T entity, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) where T : class, Azure.Data.Tables.ITableEntity, new() { throw null; }
public virtual Azure.Response AddEntity<T>(T entity, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) where T : class, Azure.Data.Tables.ITableEntity, new() { throw null; }
public virtual Azure.Response<Azure.Data.Tables.Models.TableItem> Create(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
Expand Down Expand Up @@ -86,6 +88,8 @@ public void Clear() { }
public partial class TableServiceClient
{
protected TableServiceClient() { }
public TableServiceClient(string connectionString) { }
public TableServiceClient(string connectionString, Azure.Data.Tables.TableClientOptions options = null) { }
public TableServiceClient(System.Uri endpoint) { }
public TableServiceClient(System.Uri endpoint, Azure.Data.Tables.TableClientOptions options = null) { }
public TableServiceClient(System.Uri endpoint, Azure.Data.Tables.TableSharedKeyCredential credential) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ var tableClient = serviceClient.GetTableClient(tableName);

```C# Snippet:TablesSample1CreateTableClient
tableClient = new TableClient(
tableName,
new Uri(storageUri),
tableName,
new TableSharedKeyCredential(accountName, storageAccountKey));
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ var tableClient = serviceClient.GetTableClient(tableName);

```C# Snippet:TablesSample1CreateTableClient
tableClient = new TableClient(
tableName,
new Uri(storageUri),
tableName,
new TableSharedKeyCredential(accountName, storageAccountKey));
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ var tableClient = serviceClient.GetTableClient(tableName);

```C# Snippet:TablesSample1CreateTableClient
tableClient = new TableClient(
tableName,
new Uri(storageUri),
tableName,
new TableSharedKeyCredential(accountName, storageAccountKey));
```

Expand Down
3 changes: 2 additions & 1 deletion sdk/tables/Azure.Data.Tables/src/Azure.Data.Tables.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<Description>This client library enables working with the Microsoft Azure Table service</Description>
<AssemblyTitle>Microsoft Azure.Data.Tables client library</AssemblyTitle>
<Version>1.0.0-preview.1</Version>
<Version>3.0.0-beta.1</Version>
<DefineConstants>TableSDK;$(DefineConstants)</DefineConstants>
<PackageTags>Microsoft Azure Tables;Microsoft;Azure;Tables;Table;$(PackageCommonTags)</PackageTags>
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
Expand All @@ -26,6 +26,7 @@
<Compile Include="$(AzureCoreSharedSources)AzureKeyCredentialPolicy.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)AzureResourceProviderNamespaceAttribute.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)ClientDiagnostics.cs" Link="Shared\Core\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)ConnectionString.cs" Link="Shared\Core\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)ContentTypeUtilities.cs" Link="Shared\Core\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)DiagnosticScope.cs" Link="Shared\Core\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)DiagnosticScopeFactory.cs" Link="Shared\Core\%(RecursiveDir)\%(Filename)%(Extension)" />
Expand Down
80 changes: 69 additions & 11 deletions sdk/tables/Azure.Data.Tables/src/TableClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ public class TableClient
/// <summary>
/// Initializes a new instance of the <see cref="TableClient"/>.
/// </summary>
/// <param name="tableName">The name of the table with which this client instance will interact.</param>
/// <param name="endpoint">
/// A <see cref="Uri"/> referencing the table service account.
/// This is likely to be similar to "https://{account_name}.table.core.windows.net/" or "https://{account_name}.table.cosmos.azure.com/".
/// </param>
/// <param name="tableName">The name of the table with which this client instance will interact.</param>
/// <param name="options">
/// Optional client options that define the transport pipeline policies for authentication, retries, etc., that are applied to every request.
/// </param>
/// <exception cref="ArgumentException"><paramref name="endpoint"/> is not https.</exception>
public TableClient(string tableName, Uri endpoint, TableClientOptions options = null)
: this(tableName, endpoint, default(TableSharedKeyPipelinePolicy), options)
public TableClient(Uri endpoint, string tableName, TableClientOptions options = null)
: this(endpoint, tableName, default(TableSharedKeyPipelinePolicy), options)
{
Argument.AssertNotNull(tableName, nameof(tableName));

Expand All @@ -55,15 +55,15 @@ public TableClient(string tableName, Uri endpoint, TableClientOptions options =
/// <summary>
/// Initializes a new instance of the <see cref="TableClient"/>.
/// </summary>
/// <param name="tableName">The name of the table with which this client instance will interact.</param>
/// <param name="endpoint">
/// A <see cref="Uri"/> referencing the table service account.
/// This is likely to be similar to "https://{account_name}.table.core.windows.net/" or "https://{account_name}.table.cosmos.azure.com/".
/// </param>
/// <param name="tableName">The name of the table with which this client instance will interact.</param>
/// <param name="credential">The shared key credential used to sign requests.</param>
/// <exception cref="ArgumentNullException"><paramref name="tableName"/> or <paramref name="credential"/> is null.</exception>
public TableClient(string tableName, Uri endpoint, TableSharedKeyCredential credential)
: this(tableName, endpoint, new TableSharedKeyPipelinePolicy(credential), null)
public TableClient(Uri endpoint, string tableName, TableSharedKeyCredential credential)
: this(endpoint, tableName, new TableSharedKeyPipelinePolicy(credential), null)
{
Argument.AssertNotNull(tableName, nameof(tableName));
Argument.AssertNotNull(credential, nameof(credential));
Expand All @@ -72,24 +72,83 @@ public TableClient(string tableName, Uri endpoint, TableSharedKeyCredential cred
/// <summary>
/// Initializes a new instance of the <see cref="TableClient"/>.
/// </summary>
/// <param name="tableName">The name of the table with which this client instance will interact.</param>
/// <param name="endpoint">
/// A <see cref="Uri"/> referencing the table service account.
/// This is likely to be similar to "https://{account_name}.table.core.windows.net/" or "https://{account_name}.table.cosmos.azure.com/".
/// </param>
/// <param name="tableName">The name of the table with which this client instance will interact.</param>
/// <param name="credential">The shared key credential used to sign requests.</param>
/// <param name="options">
/// Optional client options that define the transport pipeline policies for authentication, retries, etc., that are applied to every request.
/// </param>
/// <exception cref="ArgumentNullException"><paramref name="tableName"/> or <paramref name="credential"/> is null.</exception>
public TableClient(string tableName, Uri endpoint, TableSharedKeyCredential credential, TableClientOptions options = null)
: this(tableName, endpoint, new TableSharedKeyPipelinePolicy(credential), options)
public TableClient(Uri endpoint, string tableName, TableSharedKeyCredential credential, TableClientOptions options = null)
: this(endpoint, tableName, new TableSharedKeyPipelinePolicy(credential), options)
{
Argument.AssertNotNull(tableName, nameof(tableName));
Argument.AssertNotNull(credential, nameof(credential));
}

internal TableClient(string tableName, Uri endpoint, TableSharedKeyPipelinePolicy policy, TableClientOptions options)

/// <summary>
/// Initializes a new instance of the <see cref="TableServiceClient"/>.
/// </summary>
/// <param name="connectionString">
/// A connection string includes the authentication information
/// required for your application to access data in an Azure Storage
/// account at runtime.
///
/// For more information,
/// <see href="https://docs.microsoft.com/azure/storage/common/storage-configure-connection-string">
/// Configure Azure Storage connection strings</see>.
/// </param>
/// <param name="tableName">The name of the table with which this client instance will interact.</param>
public TableClient(string connectionString, string tableName)
: this(connectionString, tableName, default)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="TableServiceClient"/>.
/// </summary>
/// <param name="connectionString">
/// A connection string includes the authentication information
/// required for your application to access data in an Azure Storage
/// account at runtime.
///
/// For more information,
/// <see href="https://docs.microsoft.com/azure/storage/common/storage-configure-connection-string">
/// Configure Azure Storage connection strings</see>.
/// </param>
/// <param name="tableName">The name of the table with which this client instance will interact.</param>
/// <param name="options">
/// Optional client options that define the transport pipeline policies for authentication, retries, etc., that are applied to every request.
/// </param>
public TableClient(string connectionString, string tableName, TableClientOptions options = null)
{
Argument.AssertNotNull(connectionString, nameof(connectionString));

TableConnectionString connString = TableConnectionString.Parse(connectionString);

options ??= new TableClientOptions();
var endpointString = connString.TableStorageUri.PrimaryUri.ToString();

TableSharedKeyPipelinePolicy policy = connString.Credentials switch
{
TableSharedKeyCredential credential => new TableSharedKeyPipelinePolicy(credential),
_ => default
};

HttpPipeline pipeline = HttpPipelineBuilder.Build(options, policy);

_diagnostics = new ClientDiagnostics(options);
_tableOperations = new TableRestClient(_diagnostics, pipeline, endpointString);
_version = options.VersionString;
_table = tableName;
_format = OdataMetadataFormat.ApplicationJsonOdataMinimalmetadata;
_isPremiumEndpoint = TableServiceClient.IsPremiumEndpoint(connString.TableStorageUri.PrimaryUri);
}

internal TableClient(Uri endpoint, string tableName, TableSharedKeyPipelinePolicy policy, TableClientOptions options)
{
Argument.AssertNotNull(tableName, nameof(tableName));
Argument.AssertNotNull(endpoint, nameof(endpoint));
Expand All @@ -103,7 +162,6 @@ internal TableClient(string tableName, Uri endpoint, TableSharedKeyPipelinePolic
_table = tableName;
_format = OdataMetadataFormat.ApplicationJsonOdataMinimalmetadata;
_isPremiumEndpoint = TableServiceClient.IsPremiumEndpoint(endpoint);
;
}

internal TableClient(string table, TableRestClient tableOperations, string version, ClientDiagnostics diagnostics, bool isPremiumEndpoint)
Expand Down
Loading

0 comments on commit 4859b7a

Please sign in to comment.