I want to save my conversation history to Azure Cosmos DB or storageAccount.
It seems really easy to use IActivityLogger. But I don't know how could I get the DB connection which is connected in Global.asax.cs. Or it's better to get it again in IActivityLogger?
According this, SDK also provides a way to save conversation history using storageAccount. But the Activity has been compressed. I want to save my real conversation[JSON] which is not compressed, to storageAccount.
I'm trying to insert a row to Azure table storage which has compressed data. But Activity0 is always null.
public class ActivityEntity : TableEntity
{
/// <summary>
/// Empty constructor.
/// </summary>
public ActivityEntity()
{ }
/// <summary>
/// Construct from an IActivity.
/// </summary>
/// <param name="activity"></param>
public ActivityEntity(byte[] Activity)
{
PartitionKey = "111";
RowKey = "11";
From = "111";
Recipient = "111";
Activity0 = Activity;
Version = 3.0;
}
/// <summary>
/// Version number for the underlying activity.
/// </summary>
public double Version { get; set; }
/// <summary>
/// Channel identifier for sender.
/// </summary>
public string From { get; set; }
/// <summary>
/// Channel identifier for receiver.
/// </summary>
public string Recipient { get; set; }
/// <summary>
/// Logged activity.
/// </summary>
[IgnoreProperty]
public byte[] Activity0 { get; set; }
/// <summary>
/// Generate a partition key given <paramref name="channelId"/> and <paramref name="conversationId"/>.
/// </summary>
/// <param name="channelId">Channel where activity happened.</param>
/// <param name="conversationId">Conversation where activity happened.</param>
/// <returns>Partition key.</returns>
public static string GeneratePartitionKey(string channelId, string conversationId)
{
return $"{channelId}|{conversationId}";
}
/// <summary>
/// Generate row key for ascending <paramref name="timestamp"/>.
/// </summary>
/// <param name="timestamp">Timestamp of activity.</param>
/// <returns></returns>
public static string GenerateRowKey(DateTime timestamp)
{
return $"{timestamp.Ticks:D19}";
}
}
class Program
{
public static object CloudConfigurationManager { get; private set; }
static void Main(string[] args)
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=storagetesthuafu;AccountKey=iQ0EZexm3wbpWZqly2HtVH0/CZKRyMY9l2b0g20AQkUz7BX0BFLuBinMyYLe8Ow/zOA7vJqAMSxSHllT3JTL2g==;EndpointSuffix=core.windows.net");
// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
// Create the CloudTable object that represents the "TemperatureData" table.
CloudTable table = tableClient.GetTableReference("messagelog");
TableQuery<BotDataRow> query = new TableQuery<BotDataRow>();
var data = table.ExecuteQuery(query);
var dataarry = data.ToArray();
var aa = dataarry.First();
var activity = aa.Activity0;
var after = Decompress(activity);
CloudTable tableTEST = tableClient.GetTableReference("messagelog");
byte[] bb = Encoding.UTF8.GetBytes(after);
ActivityEntity customer4 = new ActivityEntity(bb);
// Create the InsertOrReplace TableOperation.
TableOperation insertOrReplaceOperation = TableOperation.InsertOrReplace(customer4);
// added to the table.
table.Execute(insertOrReplaceOperation);
}
Creating an IActivityLogger implementation that uses DocumentDb doesn't require much code. Here's an example using the Azure Cosmos DB Emulator:
class DocumentDbActivityLogger : IActivityLogger
{
const string DbKey = "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==";
const string DbUri = "https://localhost:8081";
const string DbId = "ActivityLogsDb";
const string CollectionId = "ActivityLogsColleciton";
async Task IActivityLogger.LogAsync(IActivity activity)
{
try
{
var message = activity.AsMessageActivity();
if (message != null)
{
using (var documentClient = new DocumentClient(new Uri(DbUri), DbKey))
{
await documentClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DbId, CollectionId), message);
}
}
}
catch (Exception e)
{
System.Diagnostics.Debug.Print(e.ToString());
}
}
}
Then, register it in Global.asax.cs:
Conversation.UpdateContainer(builder =>
{
builder.RegisterType<DocumentDbActivityLogger>().AsImplementedInterfaces().InstancePerDependency();
}