Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update CosmosDB Samples #141

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 1 addition & 19 deletions WebJobs.Extensions.Redis.sln
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.Functions.W
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.Redis", "src\Microsoft.Azure.WebJobs.Extensions.Redis\Microsoft.Azure.WebJobs.Extensions.Redis.csproj", "{A1A50657-EB50-4B7C-9BDD-AB2A357F8235}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadThroughSamples", "samples\CosmosDBIntegration\ReadThroughSamples\ReadThroughSamples.csproj", "{77A0D8F6-CAB3-450B-BBCB-658C8A47EB3C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WriteAroundSamples", "samples\CosmosDBIntegration\WriteAroundSamples\WriteAroundSamples.csproj", "{780469B0-E554-46F8-8333-4C1630C04E3D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WriteBehindSamples", "samples\CosmosDBIntegration\WriteBehindSamples\WriteBehindSamples.csproj", "{C6273150-22D0-4967-B7B6-9A2EA674053D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WriteThroughSamples", "samples\CosmosDBIntegration\WriteThroughSamples\WriteThroughSamples.csproj", "{61001020-ABEE-4B06-BF56-1C1989838CBA}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.Redis.Samples.CosmosDB", "samples\CosmosDBIntegration\ReadThroughSamples\Microsoft.Azure.WebJobs.Extensions.Redis.Samples.CosmosDB.csproj", "{77A0D8F6-CAB3-450B-BBCB-658C8A47EB3C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.Functions.Worker.Extensions.Redis.Samples", "samples\dotnet-isolated\Microsoft.Azure.Functions.Worker.Extensions.Redis.Samples.csproj", "{9EA54616-32DD-44C5-BB24-D0FEA4733850}"
EndProject
Expand Down Expand Up @@ -50,18 +44,6 @@ Global
{77A0D8F6-CAB3-450B-BBCB-658C8A47EB3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77A0D8F6-CAB3-450B-BBCB-658C8A47EB3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77A0D8F6-CAB3-450B-BBCB-658C8A47EB3C}.Release|Any CPU.Build.0 = Release|Any CPU
{780469B0-E554-46F8-8333-4C1630C04E3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{780469B0-E554-46F8-8333-4C1630C04E3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{780469B0-E554-46F8-8333-4C1630C04E3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{780469B0-E554-46F8-8333-4C1630C04E3D}.Release|Any CPU.Build.0 = Release|Any CPU
{C6273150-22D0-4967-B7B6-9A2EA674053D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C6273150-22D0-4967-B7B6-9A2EA674053D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C6273150-22D0-4967-B7B6-9A2EA674053D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C6273150-22D0-4967-B7B6-9A2EA674053D}.Release|Any CPU.Build.0 = Release|Any CPU
{61001020-ABEE-4B06-BF56-1C1989838CBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61001020-ABEE-4B06-BF56-1C1989838CBA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61001020-ABEE-4B06-BF56-1C1989838CBA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61001020-ABEE-4B06-BF56-1C1989838CBA}.Release|Any CPU.Build.0 = Release|Any CPU
{9EA54616-32DD-44C5-BB24-D0FEA4733850}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9EA54616-32DD-44C5-BB24-D0FEA4733850}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9EA54616-32DD-44C5-BB24-D0FEA4733850}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,10 @@
<TargetFramework>net6.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Models\RedisData.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.CosmosDB" Version="4.3.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Redis" Version="0.3.1-preview" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.2.0" />
<PackageReference Include="StackExchange.Redis" Version="2.6.122" />
<PackageReference Include="StackExchange.Redis" Version="2.7.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.Azure.Functions.Worker.Extensions.Redis\Microsoft.Azure.Functions.Worker.Extensions.Redis.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
 using System.Collections.Generic;

namespace Microsoft.Azure.WebJobs.Extensions.Redis.Samples.CosmosDB.Models
{
public record CosmosDBListData(
string id,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should ideally start with capital letters by convention. This applies to all the models

List<string> value
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace Microsoft.Azure.WebJobs.Extensions.Redis.Samples.CosmosDB.Models
{
public record PubSubData(
string id,
string channel,
string message,
DateTime timestamp
);
}
11 changes: 11 additions & 0 deletions samples/CosmosDBIntegration/ReadThroughSamples/Models/RedisData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace Microsoft.Azure.WebJobs.Extensions.Redis.Samples.CosmosDB.Models
{
public record RedisData(
string id,
string key,
string value,
DateTime timestamp
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using System.Collections.Generic;
using System.Linq;

namespace Microsoft.Azure.WebJobs.Extensions.Redis.Samples.CosmosDB.Models
{
public class StreamData

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not a record like PubSubData and RedisData?

{
public string id { get; set; }
public Dictionary<string, string> values { get; set; }

// Helper method to format stream message
public static StreamData Format(StreamEntry entry, ILogger logger)
{
logger.LogInformation("ID: {val}", entry.Id.ToString());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we logging in a Format method? Is this best practice?


// Map each key value pair
Dictionary<string, string> dict = entry.Values.ToDictionary(value => value.Name.ToString(), value => value.Value.ToString());

StreamData sampleItem = new StreamData { id = entry.Id, values = dict };
return sampleItem;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using System.Collections.Generic;
using System.Linq;

namespace Microsoft.Azure.WebJobs.Extensions.Redis.Samples.CosmosDB.Models
{
public class StreamDataSingleDocument
{
public string id { get; set; }
public int maxlen { get; set; }
public Dictionary<string, Dictionary<string, string>> messages { get; set; }

public static StreamDataSingleDocument CreateNewEntry(StreamEntry entry, string streamName, ILogger logger)
{
logger.LogInformation("Creating a new document for {val}. Inserting ID: {val} as the first entry", streamName, entry.Id.ToString());

// Map each key value pair
Dictionary<string, string> dict = entry.Values.ToDictionary(value => value.Name.ToString(), value => value.Value.ToString());

// Create a new list of messages
var list = new Dictionary<string, Dictionary<string, string>>();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can simplify to var list = new Dictionary<string, Dictionary<string, string>> { { entry.Id.ToString(), dict } };

list.Add(entry.Id.ToString(), dict);

StreamDataSingleDocument data = new StreamDataSingleDocument { id = streamName, maxlen = 1000, messages = list };
return data;
}

public static StreamDataSingleDocument UpdateExistingEntry(StreamDataSingleDocument results, StreamEntry entry, ILogger logger)
{
logger.LogInformation("Adding to {val} document. Inserting ID: {val} ", results.id, entry.Id.ToString());

// Map each key value pair
Dictionary<string, string> dict = entry.Values.ToDictionary(value => value.Name.ToString(), value => value.Value.ToString());

// Update list of messages
var list = results.messages;
list.Add(entry.Id.ToString(), dict);

if (list.Count > results.maxlen)
{
string minKey = list.Keys.Min();
list.Remove(minKey);
}

StreamDataSingleDocument data = new StreamDataSingleDocument { id = results.id, maxlen = results.maxlen, messages = list };

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can simplify to new()

return data;
}

}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Linq;
using Microsoft.Azure.WebJobs.Extensions.Redis.Samples.Models;
using Microsoft.Azure.WebJobs.Extensions.Redis.Samples.CosmosDB.Models;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace Microsoft.Azure.WebJobs.Extensions.Redis.Samples
namespace Microsoft.Azure.WebJobs.Extensions.Redis.Samples.CosmosDB.ReadThrough
{
public static class ListSample
public static class ListReadThrough
{
//Redis Cache primary connection string from local.settings.json
public const string RedisConnectionString = "RedisConnectionString";
Expand All @@ -22,28 +22,6 @@ public static class ListSample
//Uses the key of the user's choice and should be changed accordingly
public const string ListKey = "userListName";

/// <summary>
/// Adds a CosmosDBListData item to a Redis list with a specific key.
/// </summary>
/// <param name="response"> The response object returned by a Cosmos DB query. </param>
/// <param name="item"> The item to be added to the Redis cache. </param>
/// <param name="listEntry">The key for the Redis list to which the item will be added. </param>
/// <returns> None </returns>
public static async Task ToCacheAsync(FeedResponse<CosmosDBListData> response, CosmosDBListData item, string listEntry)
{
//Retrieve the values in cosmos associated with the list name, so you can access each item
var fullEntry = response.Take(response.Count);

if (fullEntry == null) return;

//Accessing each value from the entry
foreach (CosmosDBListData inputValues in fullEntry)
{
RedisValue[] redisValues = Array.ConvertAll(inputValues.value.ToArray(), item => (RedisValue)item);
await s_redisDb.Value.ListRightPushAsync(listEntry, redisValues);
}
}

/// <summary>
/// Function that retrieves a list from CosmosDB based on a Redis key miss event, and stores it in Redis cache using read-through caching.
/// The function takes a RedisPubSubTrigger attribute, which listens for key miss events on the Redis cache
Expand All @@ -52,8 +30,8 @@ public static async Task ToCacheAsync(FeedResponse<CosmosDBListData> response, C
/// <param name="client">A Cosmos DB client object used to connect to the database.</param>
/// <param name="logger">An ILogger object used for logging purposes.</param>
/// <returns></returns>
[FunctionName(nameof(ListTriggerReadThroughFunc))]
public static async Task ListTriggerReadThroughFunc(
[FunctionName(nameof(ListReadThrough))]
public static async Task Run(
[RedisPubSubTrigger(RedisConnectionString, "__keyevent@0__:keymiss")] string listEntry, [CosmosDB(
Connection = "CosmosDBConnectionString" )]CosmosClient client,
ILogger logger)
Expand Down Expand Up @@ -89,5 +67,27 @@ public static async Task ListTriggerReadThroughFunc(
await ToCacheAsync(response, item, listEntry);
}
}

/// <summary>
/// Adds a CosmosDBListData item to a Redis list with a specific key.
/// </summary>
/// <param name="response"> The response object returned by a Cosmos DB query. </param>
/// <param name="item"> The item to be added to the Redis cache. </param>
/// <param name="listEntry">The key for the Redis list to which the item will be added. </param>
/// <returns> None </returns>
private static async Task ToCacheAsync(FeedResponse<CosmosDBListData> response, CosmosDBListData item, string listEntry)
{
//Retrieve the values in cosmos associated with the list name, so you can access each item
var fullEntry = response.Take(response.Count);

if (fullEntry == null) return;

//Accessing each value from the entry
foreach (CosmosDBListData inputValues in fullEntry)
{
RedisValue[] redisValues = Array.ConvertAll(inputValues.value.ToArray(), item => (RedisValue)item);
await s_redisDb.Value.ListRightPushAsync(listEntry, redisValues);
}
}
}
}
Loading