diff --git a/OrleansShardedStorageProvider/AzureShardedGrainBase.cs b/OrleansShardedStorageProvider/AzureShardedGrainBase.cs
new file mode 100644
index 0000000..269fef8
--- /dev/null
+++ b/OrleansShardedStorageProvider/AzureShardedGrainBase.cs
@@ -0,0 +1,79 @@
+using Orleans.Runtime;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OrleansShardedStorageProvider
+{
+ public class AzureShardedGrainBase
+ {
+ protected readonly string _serviceId;
+ protected readonly AzureShardedStorageOptions _options;
+
+ public AzureShardedGrainBase(string serviceId, AzureShardedStorageOptions options)
+ {
+ _serviceId = serviceId;
+ _options = options;
+ }
+
+ protected int GetShardNumberFromKey(string pk)
+ {
+ var hash = GetStableHashCode(pk);
+ var storageNum = Math.Abs(hash % this._options.ConnectionStrings.Count());
+
+ return storageNum;
+ }
+
+ ///
+ /// Take from https://stackoverflow.com/a/36845864/852806
+ ///
+ ///
+ ///
+ protected int GetStableHashCode(string str)
+ {
+ unchecked
+ {
+ int hash1 = 5381;
+ int hash2 = hash1;
+
+ for (int i = 0; i < str.Length && str[i] != '\0'; i += 2)
+ {
+ hash1 = ((hash1 << 5) + hash1) ^ str[i];
+ if (i == str.Length - 1 || str[i + 1] == '\0')
+ break;
+ hash2 = ((hash2 << 5) + hash2) ^ str[i + 1];
+ }
+
+ return hash1 + (hash2 * 1566083941);
+ }
+ }
+
+
+ private const string KeyStringSeparator = "__";
+
+ protected string GetKeyString(GrainId grainId)
+ {
+ var key = $"{this._serviceId}{KeyStringSeparator}{grainId.ToString()}";
+
+ return SanitizeTableProperty(key);
+ }
+
+ protected string SanitizeTableProperty(string key)
+ {
+ // Remove any characters that can't be used in Azure PartitionKey or RowKey values
+ // http://www.jamestharpe.com/web-development/azure-table-service-character-combinations-disallowed-in-partitionkey-rowkey/
+ key = key
+ .Replace('/', '_') // Forward slash
+ .Replace('\\', '_') // Backslash
+ .Replace('#', '_') // Pound sign
+ .Replace('?', '_'); // Question mark
+
+ if (key.Length >= 1024)
+ throw new ArgumentException(string.Format("Key length {0} is too long to be an Azure table key. Key={1}", key.Length, key));
+
+ return key;
+ }
+ }
+}
diff --git a/OrleansShardedStorageProvider/AzureShardedGrainStorage.cs b/OrleansShardedStorageProvider/AzureShardedGrainStorage.cs
index c0c472b..d39ef21 100644
--- a/OrleansShardedStorageProvider/AzureShardedGrainStorage.cs
+++ b/OrleansShardedStorageProvider/AzureShardedGrainStorage.cs
@@ -1,5 +1,6 @@
using Azure;
using Azure.Data.Tables;
+using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Microsoft.Extensions.DependencyInjection;
@@ -19,24 +20,21 @@ namespace OrleansShardedStorageProvider
/// Origin: https://github.com/JsAndDotNet/OrleansShardedStorage
/// Similar to Oreleans:src\Azure\Orleans.Persistence.AzureStorage\Providers\Storage\AzureTableStorage.cs
///
- public class AzureShardedGrainStorage : IGrainStorage, ILifecycleParticipant
+ public class AzureShardedGrainStorage : AzureShardedGrainBase, IGrainStorage, ILifecycleParticipant
{
- private readonly string _serviceId;
private readonly string _name;
private readonly ILogger _logger;
- private readonly AzureShardedStorageOptions _options;
private List _tableClients = new List();
private List _blobClients = new List();
private StorageType _storageType = StorageType.TableStorage;
public AzureShardedGrainStorage(string name, AzureShardedStorageOptions options, IOptions clusterOptions, ILoggerFactory loggerFactory)
+ : base(clusterOptions.Value.ServiceId, options)
{
this._name = name;
var loggerName = $"{typeof(AzureShardedGrainStorage).FullName}.{name}";
this._logger = loggerFactory.CreateLogger(loggerName);
- this._options = options;
- this._serviceId = clusterOptions.Value.ServiceId;
}
public void Participate(ISiloLifecycle lifecycle)
@@ -66,9 +64,9 @@ public async Task Init(CancellationToken ct)
{
_storageType = StorageType.TableStorage;
- var shareClient = new TableServiceClient(
- storage.BaseTableUri,
- new AzureSasCredential(storage.SasToken));
+ var shareClient = String.IsNullOrEmpty(storage.SasToken) ?
+ new TableServiceClient(storage.BaseTableUri, new DefaultAzureCredential()) :
+ new TableServiceClient(storage.BaseTableUri, new AzureSasCredential(storage.SasToken));
var table = await shareClient.CreateTableIfNotExistsAsync(storage.TableOrContainerName);
@@ -83,7 +81,9 @@ public async Task Init(CancellationToken ct)
{
_storageType = StorageType.BlobStorage;
- BlobServiceClient blobServiceClient = new BlobServiceClient(storage.BaseBlobUri, storage.SasCredential);
+ BlobServiceClient blobServiceClient = (null == storage.SasCredential) ?
+ new BlobServiceClient(storage.BaseBlobUri, new DefaultAzureCredential()) :
+ new BlobServiceClient(storage.BaseBlobUri, storage.SasCredential);
var containerClient = blobServiceClient.GetBlobContainerClient(storage.TableOrContainerName);
await containerClient.CreateIfNotExistsAsync();
@@ -401,74 +401,6 @@ public Task Close(CancellationToken ct)
return Task.CompletedTask;
}
-
-
-
-
- #region "Utils"
-
- private int GetShardNumberFromKey(string pk)
- {
- var hash = GetStableHashCode(pk);
- var storageNum = Math.Abs(hash % this._options.ConnectionStrings.Count());
-
- return storageNum;
- }
-
- ///
- /// Take from https://stackoverflow.com/a/36845864/852806
- ///
- ///
- ///
- public int GetStableHashCode(string str)
- {
- unchecked
- {
- int hash1 = 5381;
- int hash2 = hash1;
-
- for (int i = 0; i < str.Length && str[i] != '\0'; i += 2)
- {
- hash1 = ((hash1 << 5) + hash1) ^ str[i];
- if (i == str.Length - 1 || str[i + 1] == '\0')
- break;
- hash2 = ((hash2 << 5) + hash2) ^ str[i + 1];
- }
-
- return hash1 + (hash2 * 1566083941);
- }
- }
-
-
- private const string KeyStringSeparator = "__";
-
- private string GetKeyString(GrainId grainId)
- {
- var key = $"{this._serviceId}{KeyStringSeparator}{grainId.ToString()}";
-
- return SanitizeTableProperty(key);
- }
-
- public string SanitizeTableProperty(string key)
- {
- // Remove any characters that can't be used in Azure PartitionKey or RowKey values
- // http://www.jamestharpe.com/web-development/azure-table-service-character-combinations-disallowed-in-partitionkey-rowkey/
- key = key
- .Replace('/', '_') // Forward slash
- .Replace('\\', '_') // Backslash
- .Replace('#', '_') // Pound sign
- .Replace('?', '_'); // Question mark
-
- if (key.Length >= 1024)
- throw new ArgumentException(string.Format("Key length {0} is too long to be an Azure table key. Key={1}", key.Length, key));
-
- return key;
- }
-
-
-
-
- #endregion
}
public static class AzureShardedGrainStorageFactory
diff --git a/OrleansShardedStorageProvider/OrleansShardedStorageProvider.csproj b/OrleansShardedStorageProvider/OrleansShardedStorageProvider.csproj
index a207c2f..05b6e89 100644
--- a/OrleansShardedStorageProvider/OrleansShardedStorageProvider.csproj
+++ b/OrleansShardedStorageProvider/OrleansShardedStorageProvider.csproj
@@ -8,6 +8,7 @@
+