From 9c355e98e290717f5b709d71b66eebf0d1e10637 Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Thu, 27 Jun 2019 16:13:13 -0700 Subject: [PATCH 01/66] draft --- .../SampleEphReceiver/Program.cs | 10 +- .../DotNet/Rbac/CustomRole/CustomRole.csproj | 21 +++++ samples/DotNet/Rbac/CustomRole/CustomRole.sln | 25 +++++ samples/DotNet/Rbac/CustomRole/Program.cs | 94 +++++++++++++++++++ .../CustomRole/Properties/AssemblyInfo.cs | 21 +++++ .../Rbac/CustomRole/SimpleEventProcessor.cs | 44 +++++++++ samples/DotNet/Rbac/CustomRole/readme.md | 36 +++++++ .../App - Copy.config | 69 ++++++++++++++ .../README - Copy.md | 3 + 9 files changed, 318 insertions(+), 5 deletions(-) create mode 100644 samples/DotNet/Rbac/CustomRole/CustomRole.csproj create mode 100644 samples/DotNet/Rbac/CustomRole/CustomRole.sln create mode 100644 samples/DotNet/Rbac/CustomRole/Program.cs create mode 100644 samples/DotNet/Rbac/CustomRole/Properties/AssemblyInfo.cs create mode 100644 samples/DotNet/Rbac/CustomRole/SimpleEventProcessor.cs create mode 100644 samples/DotNet/Rbac/CustomRole/readme.md create mode 100644 samples/DotNet/Rbac/EventHubsSenderReceiverRbac/App - Copy.config create mode 100644 samples/DotNet/Rbac/EventHubsSenderReceiverRbac/README - Copy.md diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/Program.cs b/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/Program.cs index 75d50e116..8754c6bea 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/Program.cs +++ b/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/Program.cs @@ -10,11 +10,11 @@ namespace SampleEphReceiver public class Program { - private const string EventHubConnectionString = "Event Hubs connection string"; - private const string EventHubName = "event hub name"; - private const string StorageContainerName = "Storage account container name"; - private const string StorageAccountName = "Storage account name"; - private const string StorageAccountKey = "Storage account key"; + private const string EventHubConnectionString = "Endpoint=sb://serkant-demo.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=y2w71RLNTpUjrFA6OM83v55/e0pcY+R5VqjKnXn57nc="; + private const string EventHubName = "myeh"; + private const string StorageAccountName = "serkantdemo"; + private const string StorageAccountKey = "cShMcVIyns73iJ6yN/a2/OMPc7SmIJiPO7jIrgg1zkdYZzXD92WCrJGLyeg5e0z/u+HqrFaGB2VJwXO1uxaF0A=="; + private const string StorageContainerName = "democontainer"; private static readonly string StorageConnectionString = string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", StorageAccountName, StorageAccountKey); diff --git a/samples/DotNet/Rbac/CustomRole/CustomRole.csproj b/samples/DotNet/Rbac/CustomRole/CustomRole.csproj new file mode 100644 index 000000000..ee3a65900 --- /dev/null +++ b/samples/DotNet/Rbac/CustomRole/CustomRole.csproj @@ -0,0 +1,21 @@ + + + + netcoreapp2.2 + CustomRole + Exe + CustomRole + 2.2.0 + false + false + false + + + + + + + + + + diff --git a/samples/DotNet/Rbac/CustomRole/CustomRole.sln b/samples/DotNet/Rbac/CustomRole/CustomRole.sln new file mode 100644 index 000000000..db916e045 --- /dev/null +++ b/samples/DotNet/Rbac/CustomRole/CustomRole.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.10 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomRole", "CustomRole.csproj", "{679DFCC5-76BD-4725-A51E-AFBB01565401}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {679DFCC5-76BD-4725-A51E-AFBB01565401}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {679DFCC5-76BD-4725-A51E-AFBB01565401}.Debug|Any CPU.Build.0 = Debug|Any CPU + {679DFCC5-76BD-4725-A51E-AFBB01565401}.Release|Any CPU.ActiveCfg = Release|Any CPU + {679DFCC5-76BD-4725-A51E-AFBB01565401}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4190FE18-2881-43ED-9A45-6AECB8D3314A} + EndGlobalSection +EndGlobal diff --git a/samples/DotNet/Rbac/CustomRole/Program.cs b/samples/DotNet/Rbac/CustomRole/Program.cs new file mode 100644 index 000000000..78b44ee00 --- /dev/null +++ b/samples/DotNet/Rbac/CustomRole/Program.cs @@ -0,0 +1,94 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace CustomRole +{ + using System; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.Azure.EventHubs; + using Microsoft.Azure.EventHubs.Processor; + using Microsoft.Azure.Storage; + using Microsoft.Azure.Storage.Auth; + using Microsoft.Identity.Client; + + public class Program + { + static readonly string TenantId = ""; + static readonly string ClientId = ""; + static readonly string ClientSecret = ""; + static readonly string EventHubNamespace = ""; + static readonly string EventHubName = ""; + static readonly string StorageContainerName = ""; + + public static void Main(string[] args) + { + MainAsync(args).GetAwaiter().GetResult(); + } + + private static async Task MainAsync(string[] args) + { + // Create Azure Storage Client with token provider. + var tokenAndFrequency = await StorageTokenRenewerAsync(null, CancellationToken.None); + var tokenCredential = new TokenCredential(tokenAndFrequency.Token, StorageTokenRenewerAsync, null, tokenAndFrequency.Frequency.Value); + var storageCredentials = new StorageCredentials(tokenCredential); + var cloudStorageAccount = new CloudStorageAccount(storageCredentials, false); + + // Create Azure Active Directory token provider for Event Hubs access. + TokenProvider tokenProvider = TokenProvider.CreateAzureActiveDirectoryTokenProvider( + async (audience, authority, state) => + { + IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(ClientId) + .WithTenantId(TenantId) + .WithClientSecret(ClientSecret) + .Build(); + + var authResult = await app.AcquireTokenForClient(new string[] { $"{audience}/.default" }).ExecuteAsync(); + return authResult.AccessToken; + }); + + Console.WriteLine("Registering EventProcessor..."); + + var eventProcessorHost = new EventProcessorHost( + new Uri(EventHubNamespace), + EventHubName, + PartitionReceiver.DefaultConsumerGroupName, + tokenProvider, + null, + StorageContainerName); + + // Registers the Event Processor Host and starts receiving messages + await eventProcessorHost.RegisterEventProcessorAsync(); + + Console.WriteLine("Receiving. Press enter key to stop worker."); + Console.ReadLine(); + + // Disposes of the Event Processor Host + await eventProcessorHost.UnregisterEventProcessorAsync(); + } + + static async Task StorageTokenRenewerAsync(object state, CancellationToken cancellationToken) + { + // Specify the resource ID for requesting Azure AD tokens for Azure Storage. + const string StorageResource = "https://storage.azure.com/"; + + IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(ClientId) + .WithTenantId(TenantId) + .WithClientSecret(ClientSecret) + .Build(); + + var authResult = await app.AcquireTokenForClient(new string[] { $"{StorageResource}/.default" }).ExecuteAsync(cancellationToken); + + // Renew the token 5 minutes before it expires. + var next = (authResult.ExpiresOn - DateTimeOffset.UtcNow) - TimeSpan.FromMinutes(5); + if (next.Ticks < 0) + { + next = default(TimeSpan); + Console.WriteLine("Renewing token..."); + } + + // Return the new token and the next refresh time. + return new NewTokenAndFrequency(authResult.AccessToken, next); + } + } +} diff --git a/samples/DotNet/Rbac/CustomRole/Properties/AssemblyInfo.cs b/samples/DotNet/Rbac/CustomRole/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..9e4abd7a3 --- /dev/null +++ b/samples/DotNet/Rbac/CustomRole/Properties/AssemblyInfo.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SampleReceiver")] +[assembly: AssemblyTrademark("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("679dfcc5-76bd-4725-a51e-afbb01565401")] diff --git a/samples/DotNet/Rbac/CustomRole/SimpleEventProcessor.cs b/samples/DotNet/Rbac/CustomRole/SimpleEventProcessor.cs new file mode 100644 index 000000000..ce88857e6 --- /dev/null +++ b/samples/DotNet/Rbac/CustomRole/SimpleEventProcessor.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace CustomRole +{ + using System; + using System.Collections.Generic; + using System.Text; + using System.Threading.Tasks; + using Microsoft.Azure.EventHubs; + using Microsoft.Azure.EventHubs.Processor; + + public class SimpleEventProcessor : IEventProcessor + { + public Task CloseAsync(PartitionContext context, CloseReason reason) + { + Console.WriteLine($"Processor Shutting Down. Partition '{context.PartitionId}', Reason: '{reason}'."); + return Task.CompletedTask; + } + + public Task OpenAsync(PartitionContext context) + { + Console.WriteLine($"SimpleEventProcessor initialized. Partition: '{context.PartitionId}'"); + return Task.CompletedTask; + } + + public Task ProcessErrorAsync(PartitionContext context, Exception error) + { + Console.WriteLine($"Error on Partition: {context.PartitionId}, Error: {error.Message}"); + return Task.CompletedTask; + } + + public Task ProcessEventsAsync(PartitionContext context, IEnumerable messages) + { + foreach (var eventData in messages) + { + var data = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count); + Console.WriteLine($"Message received. Partition: '{context.PartitionId}', Data: '{data}', Partition Key: '{eventData.SystemProperties.PartitionKey}'"); + } + + return context.CheckpointAsync(); + } + } +} diff --git a/samples/DotNet/Rbac/CustomRole/readme.md b/samples/DotNet/Rbac/CustomRole/readme.md new file mode 100644 index 000000000..efecf5b65 --- /dev/null +++ b/samples/DotNet/Rbac/CustomRole/readme.md @@ -0,0 +1,36 @@ +# Receive events with the Event Processor Host in .NET Standard + +This sample shows how to write a .NET Core console application that receives a set of events from an event hub by using the **Event Processor Host** library. You can run the solution as-is, replacing the strings with your event hub and storage account values. The sample is also [available as a tutorial](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-dotnet-standard-getstarted-receive-eph). + +## Prerequisites + +* [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). +* [.NET Core Visual Studio 2015 or 2017 tools](http://www.microsoft.com/net/core). +* An Azure subscription. +* [An event hub namespace and an event hub](event-hubs-quickstart-namespace-portal.md). +* An Azure Storage account. + +## Run the sample + +To run the sample, follow these steps: + +1. Clone or download this GitHub repo. +2. [Create an Event Hubs namespace and an event hub](event-hubs-quickstart-namespace-portal.md). +3. In Visual Studio, select **File**, then **Open Project/Solution**. Navigate to the \azure-event-hubs\samples\DotNet\Microsoft.Azure.EventHubs\SampleEphReceiver folder. +4. Load the SampleEphReceiver.sln solution file into Visual Studio. +5. Add the [Microsoft.Azure.EventHubs](https://www.nuget.org/packages/Microsoft.Azure.EventHubs/) and [Microsoft.Azure.EventHubs.Processor](https://www.nuget.org/packages/Microsoft.Azure.EventHubs.Processor/) NuGet packages to the project. +6. In Program.cs, replace the following constants with the corresponding values for the event hub connection string, event hub name: + ```csharp + private const string EventHubConnectionString = "Event Hubs connection string"; + private const string EventHubName = "Event Hub name"; + ``` +7. Create a Storage account to host a blob container, needed for lease management by the Event Processor Host. +8. In Program.cs, replace the storage account container name, storage account name, and storage account key (the container will be created if not present): +``` + private const string StorageContainerName = "Storage account container name"; + private const string StorageAccountName = "Storage account name"; + private const string StorageAccountKey = "Storage account key"; +``` +9. Run the program, and ensure that there are no errors. + +Congratulations! You have now received events from an event hub by using the Event Processor Host. To send events, see the [SampleSender](https://github.com/Azure/azure-event-hubs/tree/master/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender) sample. diff --git a/samples/DotNet/Rbac/EventHubsSenderReceiverRbac/App - Copy.config b/samples/DotNet/Rbac/EventHubsSenderReceiverRbac/App - Copy.config new file mode 100644 index 000000000..2cfef78c5 --- /dev/null +++ b/samples/DotNet/Rbac/EventHubsSenderReceiverRbac/App - Copy.config @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/DotNet/Rbac/EventHubsSenderReceiverRbac/README - Copy.md b/samples/DotNet/Rbac/EventHubsSenderReceiverRbac/README - Copy.md new file mode 100644 index 000000000..9e4cd2c30 --- /dev/null +++ b/samples/DotNet/Rbac/EventHubsSenderReceiverRbac/README - Copy.md @@ -0,0 +1,3 @@ +# Role based access sample # + +For more information on Role based access (RBAC) and how to run this sample follow [this](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-role-based-access-control) link. From 037168ff6dc3fd4eac7eeb3945b606529788795b Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Thu, 27 Jun 2019 17:55:14 -0700 Subject: [PATCH 02/66] Adding control plane + data plane EH sample --- .../Rbac/ControlAndDataPlane/App.config | 12 ++ .../ControlAndDataPlane.csproj | 117 ++++++++++++++++++ .../ControlAndDataPlane.sln | 22 ++++ .../Rbac/ControlAndDataPlane/Program.cs | 105 ++++++++++++++++ .../Properties/AssemblyInfo.cs | 35 ++++++ .../DotNet/Rbac/ControlAndDataPlane/README.md | 3 + .../Rbac/ControlAndDataPlane/nuget.config | 6 + .../Rbac/ControlAndDataPlane/packages.config | 9 ++ 8 files changed, 309 insertions(+) create mode 100644 samples/DotNet/Rbac/ControlAndDataPlane/App.config create mode 100644 samples/DotNet/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj create mode 100644 samples/DotNet/Rbac/ControlAndDataPlane/ControlAndDataPlane.sln create mode 100644 samples/DotNet/Rbac/ControlAndDataPlane/Program.cs create mode 100644 samples/DotNet/Rbac/ControlAndDataPlane/Properties/AssemblyInfo.cs create mode 100644 samples/DotNet/Rbac/ControlAndDataPlane/README.md create mode 100644 samples/DotNet/Rbac/ControlAndDataPlane/nuget.config create mode 100644 samples/DotNet/Rbac/ControlAndDataPlane/packages.config diff --git a/samples/DotNet/Rbac/ControlAndDataPlane/App.config b/samples/DotNet/Rbac/ControlAndDataPlane/App.config new file mode 100644 index 000000000..a515cf233 --- /dev/null +++ b/samples/DotNet/Rbac/ControlAndDataPlane/App.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/DotNet/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj b/samples/DotNet/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj new file mode 100644 index 000000000..a386a3a85 --- /dev/null +++ b/samples/DotNet/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj @@ -0,0 +1,117 @@ + + + + + Debug + AnyCPU + {1485E9E2-11C3-4601-929D-04618277EB9D} + Exe + Properties + ControlAndDataPlane + ControlAndDataPlane + v4.7.2 + 512 + true + + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + latest + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\..\..\CxCache\Microsoft.Identity.Client.4.0.0\lib\net45\Microsoft.Identity.Client.dll + + + ..\..\..\..\..\..\CxCache\Microsoft.IdentityModel.JsonWebTokens.5.5.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll + + + ..\..\..\..\..\..\CxCache\Microsoft.IdentityModel.Logging.5.5.0\lib\net461\Microsoft.IdentityModel.Logging.dll + + + ..\..\..\..\..\..\CxCache\Microsoft.IdentityModel.Tokens.5.5.0\lib\net461\Microsoft.IdentityModel.Tokens.dll + + + ..\..\..\..\..\ServiceBus\Messaging\out\debug-amd64\AppServer\Microsoft.ServiceBus.dll + + + ..\..\..\..\..\..\CxCache\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll + + + + + + + + + + + ..\..\..\..\..\..\CxCache\System.IdentityModel.Tokens.Jwt.4.0.4.403061554\lib\net45\System.IdentityModel.Tokens.Jwt.dll + + + + + + + + + + + + + + Designer + + + Designer + + + + + + False + Microsoft .NET Framework 4.7.2 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + \ No newline at end of file diff --git a/samples/DotNet/Rbac/ControlAndDataPlane/ControlAndDataPlane.sln b/samples/DotNet/Rbac/ControlAndDataPlane/ControlAndDataPlane.sln new file mode 100644 index 000000000..5d25c2075 --- /dev/null +++ b/samples/DotNet/Rbac/ControlAndDataPlane/ControlAndDataPlane.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlAndDataPlane", "ControlAndDataPlane.csproj", "{1485E9E2-11C3-4601-929D-04618277EB9D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1485E9E2-11C3-4601-929D-04618277EB9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1485E9E2-11C3-4601-929D-04618277EB9D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1485E9E2-11C3-4601-929D-04618277EB9D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1485E9E2-11C3-4601-929D-04618277EB9D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/samples/DotNet/Rbac/ControlAndDataPlane/Program.cs b/samples/DotNet/Rbac/ControlAndDataPlane/Program.cs new file mode 100644 index 000000000..400dce82d --- /dev/null +++ b/samples/DotNet/Rbac/ControlAndDataPlane/Program.cs @@ -0,0 +1,105 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace ControlAndDataPlane +{ + using System; + using System.Configuration; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + using Microsoft.Identity.Client; + using Microsoft.ServiceBus; + using Microsoft.ServiceBus.Messaging; + + class Program + { + static readonly string TenantId = ConfigurationManager.AppSettings["tenantId"]; + static readonly string ClientId = ConfigurationManager.AppSettings["clientId"]; + static readonly string ClientSecret = ConfigurationManager.AppSettings["clientSecret"]; + static readonly string EventHubNamespace = ConfigurationManager.AppSettings["eventHubNamespaceFQDN"]; + + public static async Task Main(string[] args) + { + // Create token provider so that we can use it at both management and runtime clients. + TokenProvider tokenProvider = TokenProvider.CreateAzureActiveDirectoryTokenProvider( + async (audience, authority, state) => + { + IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(ClientId) + .WithAuthority(authority) + .WithClientSecret(ClientSecret) + .Build(); + + var authResult = await app.AcquireTokenForClient(new string[] { $"{audience}/.default" }).ExecuteAsync(); + return authResult.AccessToken; + }, + ServiceAudience.EventHubsAudience, + $"https://login.microsoftonline.com/{TenantId}"); + + var eventHubName = "testeh-" + Guid.NewGuid().ToString(); + + // Create NamespaceManger and EventHubClient with Azure Active Directory token provider. + var ehUri = new Uri($"sb://{EventHubNamespace}/"); + var namespaceManager = new NamespaceManager(ehUri, tokenProvider); + var messagingFactory = MessagingFactory.Create(ehUri, + new MessagingFactorySettings() + { + TokenProvider = tokenProvider, + TransportType = TransportType.Amqp + }); + var ehClient = messagingFactory.CreateEventHubClient(eventHubName); + + // Create a new event hub. + Console.WriteLine($"Creating event hub {eventHubName}"); + await namespaceManager.CreateEventHubAsync(eventHubName); + + // Send and receive a message. + await SendReceiveAsync(ehClient); + + // Delete event hub. + Console.WriteLine($"Deleting event hub {eventHubName}"); + await namespaceManager.DeleteEventHubAsync(eventHubName); + + Console.WriteLine("Press enter to exit"); + Console.ReadLine(); + } + + static async Task SendReceiveAsync(EventHubClient ehClient) + { + Console.WriteLine("Fetching eventhub description to discover partitions"); + var ehDesc = await ehClient.GetRuntimeInformationAsync(); + Console.WriteLine($"Discovered partitions as {string.Join(",", ehDesc.PartitionIds)}"); + + var defaultConsumerGroup = ehClient.GetDefaultConsumerGroup(); + var receiveTasks = ehDesc.PartitionIds.Select(async partitionId => + { + Console.WriteLine($"Initiating receiver on partition {partitionId}"); + var receiver = await defaultConsumerGroup.CreateReceiverAsync(partitionId, EventPosition.FromStart()); + + while(true) + { + var events = await receiver.ReceiveAsync(1, TimeSpan.FromSeconds(15)); + if (events == null || events.Count() == 0) + { + break; + } + + Console.WriteLine($"Received from partition {partitionId} with message content '" + + Encoding.UTF8.GetString(events.First().GetBytes()) + "'"); + } + + await receiver.CloseAsync(); + }).ToList(); + + await Task.Delay(5000); + + Console.WriteLine("Sending single event"); + await ehClient.SendAsync(new EventData(Encoding.UTF8.GetBytes("Hello!"))); + Console.WriteLine("Send done"); + + Console.WriteLine("Waiting for receivers to complete"); + await Task.WhenAll(receiveTasks); + Console.WriteLine("All receivers completed"); + } + } +} diff --git a/samples/DotNet/Rbac/ControlAndDataPlane/Properties/AssemblyInfo.cs b/samples/DotNet/Rbac/ControlAndDataPlane/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..e82f585be --- /dev/null +++ b/samples/DotNet/Rbac/ControlAndDataPlane/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ControlAndDataPlane")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ControlAndDataPlane")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("5c908c55-400f-4041-99ff-eb2ead0ae8d3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/samples/DotNet/Rbac/ControlAndDataPlane/README.md b/samples/DotNet/Rbac/ControlAndDataPlane/README.md new file mode 100644 index 000000000..6a3556155 --- /dev/null +++ b/samples/DotNet/Rbac/ControlAndDataPlane/README.md @@ -0,0 +1,3 @@ +# Role based access sample with WindowsAzure.ServiceBus SDK # + +For more information on Role based access (RBAC) and how to run this sample follow [this](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-role-based-access-control) link. diff --git a/samples/DotNet/Rbac/ControlAndDataPlane/nuget.config b/samples/DotNet/Rbac/ControlAndDataPlane/nuget.config new file mode 100644 index 000000000..69c28cc18 --- /dev/null +++ b/samples/DotNet/Rbac/ControlAndDataPlane/nuget.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/samples/DotNet/Rbac/ControlAndDataPlane/packages.config b/samples/DotNet/Rbac/ControlAndDataPlane/packages.config new file mode 100644 index 000000000..dd4f229ce --- /dev/null +++ b/samples/DotNet/Rbac/ControlAndDataPlane/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file From 37cf05a10e34164ef158e3e272ae4302430da2ed Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Thu, 27 Jun 2019 22:12:33 -0700 Subject: [PATCH 03/66] SDK ref fixes for EH RBAC sample --- .../ControlAndDataPlane.csproj | 87 +++++++------------ .../Rbac/ControlAndDataPlane/nuget.config | 6 -- .../Rbac/ControlAndDataPlane/packages.config | 7 +- 3 files changed, 32 insertions(+), 68 deletions(-) delete mode 100644 samples/DotNet/Rbac/ControlAndDataPlane/nuget.config diff --git a/samples/DotNet/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj b/samples/DotNet/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj index a386a3a85..945dcb3f0 100644 --- a/samples/DotNet/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj +++ b/samples/DotNet/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj @@ -1,35 +1,19 @@  - + Debug AnyCPU {1485E9E2-11C3-4601-929D-04618277EB9D} Exe - Properties ControlAndDataPlane ControlAndDataPlane v4.7.2 512 true + true - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true AnyCPU @@ -40,7 +24,6 @@ DEBUG;TRACE prompt 4 - false latest @@ -53,65 +36,53 @@ 4 - - ..\..\..\..\..\..\CxCache\Microsoft.Identity.Client.4.0.0\lib\net45\Microsoft.Identity.Client.dll - - - ..\..\..\..\..\..\CxCache\Microsoft.IdentityModel.JsonWebTokens.5.5.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll + + packages\Microsoft.Azure.Services.AppAuthentication.1.0.3\lib\net452\Microsoft.Azure.Services.AppAuthentication.dll - - ..\..\..\..\..\..\CxCache\Microsoft.IdentityModel.Logging.5.5.0\lib\net461\Microsoft.IdentityModel.Logging.dll + + packages\Microsoft.Identity.Client.4.0.0\lib\net45\Microsoft.Identity.Client.dll - - ..\..\..\..\..\..\CxCache\Microsoft.IdentityModel.Tokens.5.5.0\lib\net461\Microsoft.IdentityModel.Tokens.dll + + packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.8\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll - - ..\..\..\..\..\ServiceBus\Messaging\out\debug-amd64\AppServer\Microsoft.ServiceBus.dll + + packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.8\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll - - ..\..\..\..\..\..\CxCache\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll + + packages\WindowsAzure.ServiceBus.6.0.0\lib\net45\Microsoft.ServiceBus.dll - + - - - - ..\..\..\..\..\..\CxCache\System.IdentityModel.Tokens.Jwt.4.0.4.403061554\lib\net45\System.IdentityModel.Tokens.Jwt.dll + packages\System.IdentityModel.Tokens.Jwt.4.0.4.403061554\lib\net45\System.IdentityModel.Tokens.Jwt.dll - - + + - + + + + + - - Designer - - - Designer - + - - - False - Microsoft .NET Framework 4.7.2 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 - false - - + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + \ No newline at end of file diff --git a/samples/DotNet/Rbac/ControlAndDataPlane/nuget.config b/samples/DotNet/Rbac/ControlAndDataPlane/nuget.config deleted file mode 100644 index 69c28cc18..000000000 --- a/samples/DotNet/Rbac/ControlAndDataPlane/nuget.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/samples/DotNet/Rbac/ControlAndDataPlane/packages.config b/samples/DotNet/Rbac/ControlAndDataPlane/packages.config index dd4f229ce..768225688 100644 --- a/samples/DotNet/Rbac/ControlAndDataPlane/packages.config +++ b/samples/DotNet/Rbac/ControlAndDataPlane/packages.config @@ -1,9 +1,8 @@  + - - - - + + \ No newline at end of file From 118133bc4c76f216a568eafdbb57f47a2c5517e0 Mon Sep 17 00:00:00 2001 From: James Birdsall Date: Mon, 1 Jul 2019 15:43:19 -0700 Subject: [PATCH 04/66] Updates for 3.0.0 RBAC release --- .../Java/Basic/AdvancedSendOptions/pom.xml | 2 +- .../AdvancedSendOptions.java | 2 +- .../Basic/EventProcessorSample/.classpath | 28 ---- .../Java/Basic/EventProcessorSample/.project | 23 --- .../Java/Basic/EventProcessorSample/pom.xml | 4 +- .../EventProcessorSample.java | 14 +- samples/Java/Basic/ReceiveByDateTime/pom.xml | 2 +- .../receivebydatetime/ReceiveByDateTime.java | 2 +- .../Basic/ReceiveUsingSequenceNumber/pom.xml | 2 +- .../ReceiveUsingSequenceNumber.java | 2 +- samples/Java/Basic/SendBatch/pom.xml | 2 +- .../samples/sendbatch/SendBatch.java | 2 +- samples/Java/Basic/SimpleProxy/pom.xml | 2 +- .../SimpleProxy.java | 137 ------------------ samples/Java/Basic/SimpleSend/pom.xml | 2 +- .../samples/SimpleSend/SimpleSend.java | 2 +- .../Benchmarks/AutoScaleOnIngress/pom.xml | 2 +- .../EventHubClientPool.java | 2 +- .../Java/Benchmarks/IngressBenchmark/pom.xml | 2 +- .../ingressbenchmark/EventHubClientPool.java | 2 +- 20 files changed, 23 insertions(+), 213 deletions(-) delete mode 100644 samples/Java/Basic/EventProcessorSample/.classpath delete mode 100644 samples/Java/Basic/EventProcessorSample/.project delete mode 100644 samples/Java/Basic/SimpleProxy/src/main/java/com.microsoft.azure.eventhubs.samples.SimpleProxy/SimpleProxy.java diff --git a/samples/Java/Basic/AdvancedSendOptions/pom.xml b/samples/Java/Basic/AdvancedSendOptions/pom.xml index b0bde814f..6b9c1d9c1 100644 --- a/samples/Java/Basic/AdvancedSendOptions/pom.xml +++ b/samples/Java/Basic/AdvancedSendOptions/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 2.3.0 + 3.0.0 com.google.code.gson diff --git a/samples/Java/Basic/AdvancedSendOptions/src/main/java/com/microsoft/azure/eventhubs/samples/AdvancedSendOptions/AdvancedSendOptions.java b/samples/Java/Basic/AdvancedSendOptions/src/main/java/com/microsoft/azure/eventhubs/samples/AdvancedSendOptions/AdvancedSendOptions.java index 4d5fedc7b..b7e6a77a7 100644 --- a/samples/Java/Basic/AdvancedSendOptions/src/main/java/com/microsoft/azure/eventhubs/samples/AdvancedSendOptions/AdvancedSendOptions.java +++ b/samples/Java/Basic/AdvancedSendOptions/src/main/java/com/microsoft/azure/eventhubs/samples/AdvancedSendOptions/AdvancedSendOptions.java @@ -46,7 +46,7 @@ public static void main(String[] args) // Each EventHubClient instance spins up a new TCP/SSL connection, which is expensive. // It is always a best practice to reuse these instances. The following sample shows the same. - final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); PartitionSender sender = null; try { diff --git a/samples/Java/Basic/EventProcessorSample/.classpath b/samples/Java/Basic/EventProcessorSample/.classpath deleted file mode 100644 index db2a016f9..000000000 --- a/samples/Java/Basic/EventProcessorSample/.classpath +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/Java/Basic/EventProcessorSample/.project b/samples/Java/Basic/EventProcessorSample/.project deleted file mode 100644 index 03043695d..000000000 --- a/samples/Java/Basic/EventProcessorSample/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - EventProcessorSample - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/samples/Java/Basic/EventProcessorSample/pom.xml b/samples/Java/Basic/EventProcessorSample/pom.xml index 7f8149c0d..e34f13b7d 100644 --- a/samples/Java/Basic/EventProcessorSample/pom.xml +++ b/samples/Java/Basic/EventProcessorSample/pom.xml @@ -47,12 +47,12 @@ com.microsoft.azure azure-eventhubs - 2.3.0 + 3.0.0 com.microsoft.azure azure-eventhubs-eph - 2.5.0 + 3.0.0 log4j diff --git a/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java b/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java index d46b88eb8..18f57aced 100644 --- a/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java +++ b/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java @@ -12,6 +12,7 @@ import com.microsoft.azure.eventprocessorhost.ExceptionReceivedEventArgs; import com.microsoft.azure.eventprocessorhost.IEventProcessor; import com.microsoft.azure.eventprocessorhost.PartitionContext; +import com.microsoft.azure.eventprocessorhost.EventProcessorHost.EventProcessorHostBuilder; import java.util.concurrent.ExecutionException; import java.util.function.Consumer; @@ -43,16 +44,13 @@ public static void main(String args[]) throws InterruptedException, ExecutionExc .setSasKeyName(sasKeyName) .setSasKey(sasKey); - // Create the instance of EventProcessorHost using the most basic constructor. This constructor uses Azure Storage for + // Create the instance of EventProcessorHost using the builder. This sample uses Azure Storage for // persisting partition leases and checkpoints. The host name, which identifies the instance of EventProcessorHost, must be unique. // You can use a plain UUID, or use the createHostName utility method which appends a UUID to a supplied string. - EventProcessorHost host = new EventProcessorHost( - EventProcessorHost.createHostName(hostNamePrefix), - eventHubName, - consumerGroupName, - eventHubConnectionString.toString(), - storageConnectionString, - storageContainerName); + EventProcessorHost host = EventProcessorHostBuilder.newBuilder(EventProcessorHost.createHostName(hostNamePrefix), consumerGroupName) + .useAzureStorageCheckpointLeaseManager(storageConnectionString, storageContainerName, "") + .useEventHubConnectionString(eventHubConnectionString.toString(), eventHubName) + .build(); // Registering an event processor class with an instance of EventProcessorHost starts event processing. The host instance // obtains leases on some partitions of the Event Hub, possibly stealing some from other host instances, in a way that diff --git a/samples/Java/Basic/ReceiveByDateTime/pom.xml b/samples/Java/Basic/ReceiveByDateTime/pom.xml index 3108cd866..f81e8db50 100644 --- a/samples/Java/Basic/ReceiveByDateTime/pom.xml +++ b/samples/Java/Basic/ReceiveByDateTime/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 2.3.0 + 3.0.0 diff --git a/samples/Java/Basic/ReceiveByDateTime/src/main/java/com/microsoft/azure/eventhubs/samples/receivebydatetime/ReceiveByDateTime.java b/samples/Java/Basic/ReceiveByDateTime/src/main/java/com/microsoft/azure/eventhubs/samples/receivebydatetime/ReceiveByDateTime.java index bb73e1af2..57f72ce6b 100644 --- a/samples/Java/Basic/ReceiveByDateTime/src/main/java/com/microsoft/azure/eventhubs/samples/receivebydatetime/ReceiveByDateTime.java +++ b/samples/Java/Basic/ReceiveByDateTime/src/main/java/com/microsoft/azure/eventhubs/samples/receivebydatetime/ReceiveByDateTime.java @@ -31,7 +31,7 @@ public static void main(String[] args) .setSasKey("---SharedAccessSignatureKey----"); final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); - final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); final EventHubRuntimeInformation eventHubInfo = ehClient.getRuntimeInformation().get(); final String partitionId = eventHubInfo.getPartitionIds()[0]; // get first partition's id diff --git a/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml b/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml index 82e583349..812191033 100644 --- a/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml +++ b/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 2.3.0 + 3.0.0 diff --git a/samples/Java/Basic/ReceiveUsingSequenceNumber/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingsequencenumber/ReceiveUsingSequenceNumber.java b/samples/Java/Basic/ReceiveUsingSequenceNumber/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingsequencenumber/ReceiveUsingSequenceNumber.java index 8027db35a..77de83a5c 100644 --- a/samples/Java/Basic/ReceiveUsingSequenceNumber/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingsequencenumber/ReceiveUsingSequenceNumber.java +++ b/samples/Java/Basic/ReceiveUsingSequenceNumber/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingsequencenumber/ReceiveUsingSequenceNumber.java @@ -30,7 +30,7 @@ public static void main(String[] args) .setSasKey("---SharedAccessSignatureKey----"); final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); - final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); final EventHubRuntimeInformation eventHubInfo = ehClient.getRuntimeInformation().get(); final String partitionId = eventHubInfo.getPartitionIds()[0]; // get first partition's id diff --git a/samples/Java/Basic/SendBatch/pom.xml b/samples/Java/Basic/SendBatch/pom.xml index e4df26e64..03d8e3a6b 100644 --- a/samples/Java/Basic/SendBatch/pom.xml +++ b/samples/Java/Basic/SendBatch/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 2.3.0 + 3.0.0 com.google.code.gson diff --git a/samples/Java/Basic/SendBatch/src/main/java/com/microsoft/azure/eventhubs/samples/sendbatch/SendBatch.java b/samples/Java/Basic/SendBatch/src/main/java/com/microsoft/azure/eventhubs/samples/sendbatch/SendBatch.java index 686eb4a21..899034ca5 100644 --- a/samples/Java/Basic/SendBatch/src/main/java/com/microsoft/azure/eventhubs/samples/sendbatch/SendBatch.java +++ b/samples/Java/Basic/SendBatch/src/main/java/com/microsoft/azure/eventhubs/samples/sendbatch/SendBatch.java @@ -31,7 +31,7 @@ public static void main(String[] args) final Gson gson = new GsonBuilder().create(); final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); - final EventHubClient sender = EventHubClient.createSync(connStr.toString(), executorService); + final EventHubClient sender = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); try { for (int batchNumber = 0; batchNumber < 10; batchNumber++) { diff --git a/samples/Java/Basic/SimpleProxy/pom.xml b/samples/Java/Basic/SimpleProxy/pom.xml index baf58c6e6..f6b021389 100644 --- a/samples/Java/Basic/SimpleProxy/pom.xml +++ b/samples/Java/Basic/SimpleProxy/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 2.3.0 + 3.0.0 com.google.code.gson diff --git a/samples/Java/Basic/SimpleProxy/src/main/java/com.microsoft.azure.eventhubs.samples.SimpleProxy/SimpleProxy.java b/samples/Java/Basic/SimpleProxy/src/main/java/com.microsoft.azure.eventhubs.samples.SimpleProxy/SimpleProxy.java deleted file mode 100644 index 83b9bf864..000000000 --- a/samples/Java/Basic/SimpleProxy/src/main/java/com.microsoft.azure.eventhubs.samples.SimpleProxy/SimpleProxy.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ -package com.microsoft.azure.eventhubs.samples.SimpleProxy; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.microsoft.azure.eventhubs.*; - -import java.io.IOException; -import java.net.*; -import java.nio.charset.Charset; -import java.time.Instant; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; - - -public class SimpleProxy { - - public static void main(String[] args) - throws EventHubException, ExecutionException, InterruptedException, IOException { - - String proxyIpAddressStr = "---proxyhostname---"; - int proxyPort = 3128; - - //set the ProxySelector API; which offers the flexibility to select Proxy Server based on the Target URI. - ProxySelector systemDefaultSelector = ProxySelector.getDefault(); - ProxySelector.setDefault(new ProxySelector() { - @Override - public List select(URI uri) { - if (uri != null - && uri.getHost() != null - && uri.getHost().equalsIgnoreCase("youreventbushost.servicebus.windows.net")) { - LinkedList proxies = new LinkedList<>(); - proxies.add(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIpAddressStr, proxyPort))); - return proxies; - } - - // preserve system default selector for the rest - return systemDefaultSelector.select(uri); - } - @Override - public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { - // trace and follow up on why proxy server is down - if (uri == null || sa == null || ioe == null) { - throw new IllegalArgumentException("Arguments can't be null."); - } - - systemDefaultSelector.connectFailed(uri, sa, ioe); - - } - }); - - // if the proxy being used, doesn't need any Authentication - "setting Authenticator" step may be omitted - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - if (this.getRequestorType() == RequestorType.PROXY - && this.getRequestingScheme().equalsIgnoreCase("basic") - && this.getRequestingHost().equals(proxyIpAddressStr) - && this.getRequestingPort() == proxyPort) { - return new PasswordAuthentication("userName", "password".toCharArray()); - } - - return super.getPasswordAuthentication(); - } - }); - - final ConnectionStringBuilder connStr = new ConnectionStringBuilder() - .setNamespaceName("----NamespaceName-----") // to target National clouds - use .setEndpoint(URI) - .setEventHubName("----EventHubName-----") - .setSasKeyName("-----SharedAccessSignatureKeyName-----") - .setSasKey("---SharedAccessSignatureKey---"); - - connStr.setTransportType(TransportType.AMQP_WEB_SOCKETS); - - final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); - final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); - final Gson gson = new GsonBuilder().create(); - PartitionSender sender = null; - - //sending events - try { - - String payload = "Message " + Integer.toString(1); - byte[] payloadBytes = gson.toJson(payload).getBytes(Charset.defaultCharset()); - EventData sendEvent = EventData.create(payloadBytes); - - sender = ehClient.createPartitionSenderSync("1"); - sender.sendSync(sendEvent); - - System.out.println(Instant.now() + ": Send Complete..."); - - } - finally { - - } - - final EventHubRuntimeInformation eventHubInfo = ehClient.getRuntimeInformation().get(); - final String partitionId = eventHubInfo.getPartitionIds()[1]; // get first partition's id - - final PartitionReceiver receiver = ehClient.createEpochReceiverSync( - EventHubClient.DEFAULT_CONSUMER_GROUP_NAME, - partitionId, - EventPosition.fromEnqueuedTime(Instant.EPOCH), - 2345); - - try { - Iterable receivedEvents = receiver.receiveSync(10); - - if (receivedEvents != null) { - for (final EventData receivedEvent : receivedEvents) { - if (receivedEvent.getBytes() != null) - System.out.println(String.format("Message Payload: %s", new String(receivedEvent.getBytes(), Charset.defaultCharset()))); - } - } - - } finally { - // cleaning up receivers is paramount; - // Quota limitation on maximum number of concurrent receivers per consumergroup per partition is 5 - receiver.close() - .thenComposeAsync(aVoid -> ehClient.close(), executorService) - .whenCompleteAsync((t, u) -> { - if (u != null) { - // wire-up this error to diagnostics infrastructure - System.out.println(String.format("closing failed with error: %s", u.toString())); - } - }, executorService).get(); - - executorService.shutdown(); - } - } -} diff --git a/samples/Java/Basic/SimpleSend/pom.xml b/samples/Java/Basic/SimpleSend/pom.xml index 3bdffea7a..6045b76f8 100644 --- a/samples/Java/Basic/SimpleSend/pom.xml +++ b/samples/Java/Basic/SimpleSend/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 2.3.0 + 3.0.0 com.google.code.gson diff --git a/samples/Java/Basic/SimpleSend/src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java b/samples/Java/Basic/SimpleSend/src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java index c4cccbb78..57908cd94 100644 --- a/samples/Java/Basic/SimpleSend/src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java +++ b/samples/Java/Basic/SimpleSend/src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java @@ -40,7 +40,7 @@ public static void main(String[] args) // Each EventHubClient instance spins up a new TCP/SSL connection, which is expensive. // It is always a best practice to reuse these instances. The following sample shows this. - final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); try { for (int i = 0; i < 100; i++) { diff --git a/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml b/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml index 7c70ccad6..cf856c454 100644 --- a/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml +++ b/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 2.3.0 + 3.0.0 diff --git a/samples/Java/Benchmarks/AutoScaleOnIngress/src/main/java/com/microsoft/azure/eventhubs/samples/autoscaleoningress/EventHubClientPool.java b/samples/Java/Benchmarks/AutoScaleOnIngress/src/main/java/com/microsoft/azure/eventhubs/samples/autoscaleoningress/EventHubClientPool.java index e78718105..702123e13 100644 --- a/samples/Java/Benchmarks/AutoScaleOnIngress/src/main/java/com/microsoft/azure/eventhubs/samples/autoscaleoningress/EventHubClientPool.java +++ b/samples/Java/Benchmarks/AutoScaleOnIngress/src/main/java/com/microsoft/azure/eventhubs/samples/autoscaleoningress/EventHubClientPool.java @@ -34,7 +34,7 @@ public CompletableFuture initialize() throws IOException, EventHubExceptio final CompletableFuture[] createSenders = new CompletableFuture[this.poolSize]; for (int count = 0; count < poolSize; count++) { final int clientsIndex = count; - createSenders[count] = EventHubClient.create(this.connectionString, executorService).thenAccept(new Consumer() { + createSenders[count] = EventHubClient.createFromConnectionString(this.connectionString, executorService).thenAccept(new Consumer() { @Override public void accept(EventHubClient eventHubClient) { clients[clientsIndex] = eventHubClient; diff --git a/samples/Java/Benchmarks/IngressBenchmark/pom.xml b/samples/Java/Benchmarks/IngressBenchmark/pom.xml index 3d4d04917..07456532b 100644 --- a/samples/Java/Benchmarks/IngressBenchmark/pom.xml +++ b/samples/Java/Benchmarks/IngressBenchmark/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 2.3.0 + 3.0.0 diff --git a/samples/Java/Benchmarks/IngressBenchmark/src/main/java/com/microsoft/azure/eventhubs/samples/ingressbenchmark/EventHubClientPool.java b/samples/Java/Benchmarks/IngressBenchmark/src/main/java/com/microsoft/azure/eventhubs/samples/ingressbenchmark/EventHubClientPool.java index b8a2dc128..8ec98807a 100644 --- a/samples/Java/Benchmarks/IngressBenchmark/src/main/java/com/microsoft/azure/eventhubs/samples/ingressbenchmark/EventHubClientPool.java +++ b/samples/Java/Benchmarks/IngressBenchmark/src/main/java/com/microsoft/azure/eventhubs/samples/ingressbenchmark/EventHubClientPool.java @@ -34,7 +34,7 @@ public CompletableFuture initialize() throws IOException, EventHubExceptio final CompletableFuture[] createSenders = new CompletableFuture[this.poolSize]; for (int count = 0; count < poolSize; count++) { final int clientsIndex = count; - createSenders[count] = EventHubClient.create(this.connectionString, executorService).thenAccept(new Consumer() { + createSenders[count] = EventHubClient.createFromConnectionString(this.connectionString, executorService).thenAccept(new Consumer() { @Override public void accept(EventHubClient eventHubClient) { clients[clientsIndex] = eventHubClient; From 27c213b2e5d678f59f8395ea4fa6a8b0ed82e01f Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Tue, 2 Jul 2019 09:28:57 -0700 Subject: [PATCH 05/66] Adding RBAC custom role sample --- .../DotNet/Rbac/CustomRole/CustomRole.csproj | 11 +-- samples/DotNet/Rbac/CustomRole/Program.cs | 83 +++++++++---------- samples/DotNet/Rbac/CustomRole/readme.md | 54 +++++------- 3 files changed, 65 insertions(+), 83 deletions(-) diff --git a/samples/DotNet/Rbac/CustomRole/CustomRole.csproj b/samples/DotNet/Rbac/CustomRole/CustomRole.csproj index ee3a65900..0a73024d4 100644 --- a/samples/DotNet/Rbac/CustomRole/CustomRole.csproj +++ b/samples/DotNet/Rbac/CustomRole/CustomRole.csproj @@ -1,20 +1,21 @@ - netcoreapp2.2 + netcoreapp2.1 CustomRole Exe CustomRole - 2.2.0 + 2.1.0 false false false + latest - - - + + + diff --git a/samples/DotNet/Rbac/CustomRole/Program.cs b/samples/DotNet/Rbac/CustomRole/Program.cs index 78b44ee00..58fd27614 100644 --- a/samples/DotNet/Rbac/CustomRole/Program.cs +++ b/samples/DotNet/Rbac/CustomRole/Program.cs @@ -8,53 +8,50 @@ namespace CustomRole using System.Threading.Tasks; using Microsoft.Azure.EventHubs; using Microsoft.Azure.EventHubs.Processor; - using Microsoft.Azure.Storage; - using Microsoft.Azure.Storage.Auth; using Microsoft.Identity.Client; + using Microsoft.WindowsAzure.Storage; + using Microsoft.WindowsAzure.Storage.Auth; public class Program { - static readonly string TenantId = ""; - static readonly string ClientId = ""; - static readonly string ClientSecret = ""; - static readonly string EventHubNamespace = ""; - static readonly string EventHubName = ""; - static readonly string StorageContainerName = ""; - - public static void Main(string[] args) - { - MainAsync(args).GetAwaiter().GetResult(); - } + private const string Authority = "Authority of tenant"; + private const string ClientId = "AAD app id"; + private const string ClientSecret = "AAD app secret"; + private const string EventHubNamespace = "FQDN of Event Hubs namespace"; + private const string EventHubName = "Event hub name"; + private const string StorageAccountName = "Storage account name"; + private const string StorageContainerName = "Storage account container name"; - private static async Task MainAsync(string[] args) + static IConfidentialClientApplication tokenClient; + + public static async Task Main(string[] args) { - // Create Azure Storage Client with token provider. - var tokenAndFrequency = await StorageTokenRenewerAsync(null, CancellationToken.None); - var tokenCredential = new TokenCredential(tokenAndFrequency.Token, StorageTokenRenewerAsync, null, tokenAndFrequency.Frequency.Value); - var storageCredentials = new StorageCredentials(tokenCredential); - var cloudStorageAccount = new CloudStorageAccount(storageCredentials, false); + // Use the same identity client for both Event Hubs and Storage + tokenClient = ConfidentialClientApplicationBuilder.Create(ClientId) + .WithAuthority(Authority) + .WithClientSecret(ClientSecret) + .Build(); - // Create Azure Active Directory token provider for Event Hubs access. - TokenProvider tokenProvider = TokenProvider.CreateAzureActiveDirectoryTokenProvider( - async (audience, authority, state) => - { - IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(ClientId) - .WithTenantId(TenantId) - .WithClientSecret(ClientSecret) - .Build(); + // Create Storage client with access token provider + var tokenAndFrequency = await TokenRenewerAsync(tokenClient, CancellationToken.None); + var tokenCredential = new TokenCredential(tokenAndFrequency.Token, + TokenRenewerAsync, + tokenClient, + tokenAndFrequency.Frequency.Value); + var storageCredentials = new StorageCredentials(tokenCredential); + CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(storageCredentials, StorageAccountName, string.Empty, true); - var authResult = await app.AcquireTokenForClient(new string[] { $"{audience}/.default" }).ExecuteAsync(); - return authResult.AccessToken; - }); + // Create Event Hubs account with access token provider + TokenProvider tp = TokenProvider.CreateAzureActiveDirectoryTokenProvider( + new AzureActiveDirectoryTokenProvider.AuthenticationCallback(GetAccessToken), Authority, tokenClient); Console.WriteLine("Registering EventProcessor..."); - var eventProcessorHost = new EventProcessorHost( new Uri(EventHubNamespace), EventHubName, PartitionReceiver.DefaultConsumerGroupName, - tokenProvider, - null, + tp, + cloudStorageAccount, StorageContainerName); // Registers the Event Processor Host and starts receiving messages @@ -67,17 +64,10 @@ private static async Task MainAsync(string[] args) await eventProcessorHost.UnregisterEventProcessorAsync(); } - static async Task StorageTokenRenewerAsync(object state, CancellationToken cancellationToken) + private static async Task TokenRenewerAsync(Object state, CancellationToken cancellationToken) { - // Specify the resource ID for requesting Azure AD tokens for Azure Storage. - const string StorageResource = "https://storage.azure.com/"; - - IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(ClientId) - .WithTenantId(TenantId) - .WithClientSecret(ClientSecret) - .Build(); - - var authResult = await app.AcquireTokenForClient(new string[] { $"{StorageResource}/.default" }).ExecuteAsync(cancellationToken); + var authResult = await ((IConfidentialClientApplication)state) + .AcquireTokenForClient(new string[] { $"https://storage.azure.com/.default" }).ExecuteAsync(); // Renew the token 5 minutes before it expires. var next = (authResult.ExpiresOn - DateTimeOffset.UtcNow) - TimeSpan.FromMinutes(5); @@ -90,5 +80,12 @@ static async Task StorageTokenRenewerAsync(object state, C // Return the new token and the next refresh time. return new NewTokenAndFrequency(authResult.AccessToken, next); } + + static async Task GetAccessToken(string audience, string authority, object state) + { + var authResult = await tokenClient + .AcquireTokenForClient(new string[] { $"{audience}/.default" }).ExecuteAsync(); + return authResult.AccessToken; + } } } diff --git a/samples/DotNet/Rbac/CustomRole/readme.md b/samples/DotNet/Rbac/CustomRole/readme.md index efecf5b65..8f58db833 100644 --- a/samples/DotNet/Rbac/CustomRole/readme.md +++ b/samples/DotNet/Rbac/CustomRole/readme.md @@ -1,36 +1,20 @@ -# Receive events with the Event Processor Host in .NET Standard +# Receive events with the Event Processor Host in .NET Standard with a custom role which grants Listen claim for Event Hubs and blob claims for Storage accounts. -This sample shows how to write a .NET Core console application that receives a set of events from an event hub by using the **Event Processor Host** library. You can run the solution as-is, replacing the strings with your event hub and storage account values. The sample is also [available as a tutorial](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-dotnet-standard-getstarted-receive-eph). - -## Prerequisites - -* [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). -* [.NET Core Visual Studio 2015 or 2017 tools](http://www.microsoft.com/net/core). -* An Azure subscription. -* [An event hub namespace and an event hub](event-hubs-quickstart-namespace-portal.md). -* An Azure Storage account. - -## Run the sample - -To run the sample, follow these steps: - -1. Clone or download this GitHub repo. -2. [Create an Event Hubs namespace and an event hub](event-hubs-quickstart-namespace-portal.md). -3. In Visual Studio, select **File**, then **Open Project/Solution**. Navigate to the \azure-event-hubs\samples\DotNet\Microsoft.Azure.EventHubs\SampleEphReceiver folder. -4. Load the SampleEphReceiver.sln solution file into Visual Studio. -5. Add the [Microsoft.Azure.EventHubs](https://www.nuget.org/packages/Microsoft.Azure.EventHubs/) and [Microsoft.Azure.EventHubs.Processor](https://www.nuget.org/packages/Microsoft.Azure.EventHubs.Processor/) NuGet packages to the project. -6. In Program.cs, replace the following constants with the corresponding values for the event hub connection string, event hub name: - ```csharp - private const string EventHubConnectionString = "Event Hubs connection string"; - private const string EventHubName = "Event Hub name"; - ``` -7. Create a Storage account to host a blob container, needed for lease management by the Event Processor Host. -8. In Program.cs, replace the storage account container name, storage account name, and storage account key (the container will be created if not present): -``` - private const string StorageContainerName = "Storage account container name"; - private const string StorageAccountName = "Storage account name"; - private const string StorageAccountKey = "Storage account key"; -``` -9. Run the program, and ensure that there are no errors. - -Congratulations! You have now received events from an event hub by using the Event Processor Host. To send events, see the [SampleSender](https://github.com/Azure/azure-event-hubs/tree/master/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender) sample. +{ + "Name": "Custom role for RBAC sample", + "Id": "8ddab47f-cf99-4b04-8fc3-1d2d857fb931", + "Description": "Test role", + "IsCustom": true, + "Actions": [ + "Microsoft.Storage/*" +], + "NotActions": [], + "DataActions": [ + "Microsoft.EventHub/namespaces/messages/receive/action", + "Microsoft.Storage/*" +], + "NotDataActions": [], + "AssignableScopes": [ + "/subscriptions/your-subscription-id" + ] +} From 51587c89487174a6171039bea12afd70df8cac2d Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Tue, 2 Jul 2019 09:31:39 -0700 Subject: [PATCH 06/66] Remove unintented files --- .../App - Copy.config | 69 ------------------- .../README - Copy.md | 3 - 2 files changed, 72 deletions(-) delete mode 100644 samples/DotNet/Rbac/EventHubsSenderReceiverRbac/App - Copy.config delete mode 100644 samples/DotNet/Rbac/EventHubsSenderReceiverRbac/README - Copy.md diff --git a/samples/DotNet/Rbac/EventHubsSenderReceiverRbac/App - Copy.config b/samples/DotNet/Rbac/EventHubsSenderReceiverRbac/App - Copy.config deleted file mode 100644 index 2cfef78c5..000000000 --- a/samples/DotNet/Rbac/EventHubsSenderReceiverRbac/App - Copy.config +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/DotNet/Rbac/EventHubsSenderReceiverRbac/README - Copy.md b/samples/DotNet/Rbac/EventHubsSenderReceiverRbac/README - Copy.md deleted file mode 100644 index 9e4cd2c30..000000000 --- a/samples/DotNet/Rbac/EventHubsSenderReceiverRbac/README - Copy.md +++ /dev/null @@ -1,3 +0,0 @@ -# Role based access sample # - -For more information on Role based access (RBAC) and how to run this sample follow [this](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-role-based-access-control) link. From 10ec29a21907c96477cede128c9fb279e90d3c35 Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Tue, 2 Jul 2019 09:33:53 -0700 Subject: [PATCH 07/66] Reverting unintended changes --- .../SampleEphReceiver/Program.cs | 12 ++++++------ .../Rbac/CustomRole/Properties/AssemblyInfo.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/Program.cs b/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/Program.cs index 8754c6bea..853e17449 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/Program.cs +++ b/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/Program.cs @@ -10,12 +10,12 @@ namespace SampleEphReceiver public class Program { - private const string EventHubConnectionString = "Endpoint=sb://serkant-demo.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=y2w71RLNTpUjrFA6OM83v55/e0pcY+R5VqjKnXn57nc="; - private const string EventHubName = "myeh"; - private const string StorageAccountName = "serkantdemo"; - private const string StorageAccountKey = "cShMcVIyns73iJ6yN/a2/OMPc7SmIJiPO7jIrgg1zkdYZzXD92WCrJGLyeg5e0z/u+HqrFaGB2VJwXO1uxaF0A=="; - private const string StorageContainerName = "democontainer"; - + private const string EventHubConnectionString = "Event Hubs connection string"; + private const string EventHubName = "event hub name"; + private const string StorageContainerName = "Storage account container name"; + private const string StorageAccountName = "Storage account name"; + private const string StorageAccountKey = "Storage account key"; + private static readonly string StorageConnectionString = string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", StorageAccountName, StorageAccountKey); public static void Main(string[] args) diff --git a/samples/DotNet/Rbac/CustomRole/Properties/AssemblyInfo.cs b/samples/DotNet/Rbac/CustomRole/Properties/AssemblyInfo.cs index 9e4abd7a3..a2a95c726 100644 --- a/samples/DotNet/Rbac/CustomRole/Properties/AssemblyInfo.cs +++ b/samples/DotNet/Rbac/CustomRole/Properties/AssemblyInfo.cs @@ -9,7 +9,7 @@ // associated with an assembly. [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SampleReceiver")] +[assembly: AssemblyProduct("CustomRole")] [assembly: AssemblyTrademark("")] // Setting ComVisible to false makes the types in this assembly not visible From c030b6d5c104ab676cee359ec67e7e50948648a2 Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Tue, 2 Jul 2019 09:37:15 -0700 Subject: [PATCH 08/66] readme changes --- samples/DotNet/Rbac/CustomRole/readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/DotNet/Rbac/CustomRole/readme.md b/samples/DotNet/Rbac/CustomRole/readme.md index 8f58db833..d7e2ee12d 100644 --- a/samples/DotNet/Rbac/CustomRole/readme.md +++ b/samples/DotNet/Rbac/CustomRole/readme.md @@ -1,8 +1,10 @@ # Receive events with the Event Processor Host in .NET Standard with a custom role which grants Listen claim for Event Hubs and blob claims for Storage accounts. +Here is the custom role definition you can use to run this sample. Once created, assign your custom role to Storage and Event Hubs resources. + { "Name": "Custom role for RBAC sample", - "Id": "8ddab47f-cf99-4b04-8fc3-1d2d857fb931", + "Id": "8ddab47f-cf99-4b04-8fc3-1d2d857fb931", "Description": "Test role", "IsCustom": true, "Actions": [ From 1306652fa8ca26e90b1824e34ee48cd10dd6204e Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Tue, 2 Jul 2019 09:39:13 -0700 Subject: [PATCH 09/66] minor changes --- samples/DotNet/Rbac/CustomRole/Program.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/samples/DotNet/Rbac/CustomRole/Program.cs b/samples/DotNet/Rbac/CustomRole/Program.cs index 58fd27614..34f4a0b5c 100644 --- a/samples/DotNet/Rbac/CustomRole/Program.cs +++ b/samples/DotNet/Rbac/CustomRole/Program.cs @@ -41,11 +41,9 @@ public static async Task Main(string[] args) var storageCredentials = new StorageCredentials(tokenCredential); CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(storageCredentials, StorageAccountName, string.Empty, true); - // Create Event Hubs account with access token provider + // Create Event Hubs access token provider and processor host TokenProvider tp = TokenProvider.CreateAzureActiveDirectoryTokenProvider( new AzureActiveDirectoryTokenProvider.AuthenticationCallback(GetAccessToken), Authority, tokenClient); - - Console.WriteLine("Registering EventProcessor..."); var eventProcessorHost = new EventProcessorHost( new Uri(EventHubNamespace), EventHubName, @@ -55,6 +53,7 @@ public static async Task Main(string[] args) StorageContainerName); // Registers the Event Processor Host and starts receiving messages + Console.WriteLine("Registering EventProcessor..."); await eventProcessorHost.RegisterEventProcessorAsync(); Console.WriteLine("Receiving. Press enter key to stop worker."); From eda4dbd4e9da0d52aa748a132f7055099eda6eb6 Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Tue, 2 Jul 2019 09:45:51 -0700 Subject: [PATCH 10/66] Refactoring token acquisition --- samples/DotNet/Rbac/CustomRole/Program.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/samples/DotNet/Rbac/CustomRole/Program.cs b/samples/DotNet/Rbac/CustomRole/Program.cs index 34f4a0b5c..d350e2b52 100644 --- a/samples/DotNet/Rbac/CustomRole/Program.cs +++ b/samples/DotNet/Rbac/CustomRole/Program.cs @@ -43,7 +43,7 @@ public static async Task Main(string[] args) // Create Event Hubs access token provider and processor host TokenProvider tp = TokenProvider.CreateAzureActiveDirectoryTokenProvider( - new AzureActiveDirectoryTokenProvider.AuthenticationCallback(GetAccessToken), Authority, tokenClient); + new AzureActiveDirectoryTokenProvider.AuthenticationCallback(GetAccessTokenAsync), Authority, tokenClient); var eventProcessorHost = new EventProcessorHost( new Uri(EventHubNamespace), EventHubName, @@ -65,8 +65,7 @@ public static async Task Main(string[] args) private static async Task TokenRenewerAsync(Object state, CancellationToken cancellationToken) { - var authResult = await ((IConfidentialClientApplication)state) - .AcquireTokenForClient(new string[] { $"https://storage.azure.com/.default" }).ExecuteAsync(); + var authResult = await AcquireTokenAsync("https://storage.azure.com/"); // Renew the token 5 minutes before it expires. var next = (authResult.ExpiresOn - DateTimeOffset.UtcNow) - TimeSpan.FromMinutes(5); @@ -80,11 +79,17 @@ private static async Task TokenRenewerAsync(Object state, return new NewTokenAndFrequency(authResult.AccessToken, next); } - static async Task GetAccessToken(string audience, string authority, object state) + static async Task GetAccessTokenAsync(string audience, string authority, object state) { - var authResult = await tokenClient - .AcquireTokenForClient(new string[] { $"{audience}/.default" }).ExecuteAsync(); + var authResult = await AcquireTokenAsync(audience); + return authResult.AccessToken; } + + static async Task AcquireTokenAsync(string audience) + { + return await tokenClient + .AcquireTokenForClient(new string[] { $"{audience}/.default" }).ExecuteAsync(); + } } } From 4a87ed480ec9d0665c4e0cdd0450e92566535f61 Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Tue, 2 Jul 2019 14:22:22 -0700 Subject: [PATCH 11/66] Update readme.md --- samples/DotNet/Rbac/CustomRole/readme.md | 31 ++++++++++++++++++++---- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/samples/DotNet/Rbac/CustomRole/readme.md b/samples/DotNet/Rbac/CustomRole/readme.md index d7e2ee12d..aabfe3294 100644 --- a/samples/DotNet/Rbac/CustomRole/readme.md +++ b/samples/DotNet/Rbac/CustomRole/readme.md @@ -1,10 +1,27 @@ # Receive events with the Event Processor Host in .NET Standard with a custom role which grants Listen claim for Event Hubs and blob claims for Storage accounts. -Here is the custom role definition you can use to run this sample. Once created, assign your custom role to Storage and Event Hubs resources. +## Prerequisites -{ - "Name": "Custom role for RBAC sample", - "Id": "8ddab47f-cf99-4b04-8fc3-1d2d857fb931", +* [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). +* [.NET Core Visual Studio 2015 or 2017 tools](http://www.microsoft.com/net/core). +* An Azure subscription. +* [An event hub namespace and an event hub](event-hubs-quickstart-namespace-portal.md). +* An Azure Storage account. + +## Run the sample + +To run the sample, follow these steps: + +1. Clone or download this GitHub repo. +2. [Create an Event Hubs namespace and an event hub](https://docs.microsoft.com/azure/event-hubs/event-hubs-create). +3. Create a Storage account to host a blob container, needed for lease management by the Event Processor Host. +3. [Create a new custom role](https://docs.microsoft.com/en-us/azure/role-based-access-control/custom-roles) with the definition below. +4. [Create a new AAD (Azure Active Directory) application](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal). +5. Assign AAD application to both Event Hubs namespace and Storage account with the custom role you just created. + +```{ + "Name": "Custom role for RBAC sample", + "Id": "8ddab47f-cf99-4b04-8fc3-1d2d857fb931", "Description": "Test role", "IsCustom": true, "Actions": [ @@ -19,4 +36,8 @@ Here is the custom role definition you can use to run this sample. Once created, "AssignableScopes": [ "/subscriptions/your-subscription-id" ] -} +}``` + +6. Update the sample with Event Hubs namespace and Storage account name. +7. Run [Sender application](https://github.com/Azure/azure-event-hubs/tree/serkar.AddCustomRbacEhSample/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender) to send some number of messages to your event hub. +8. Run the CustomRole sample to receive those events back. From 333774188e2e3f4a27ddcfc4b88d4b5d4b09ba7f Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Tue, 2 Jul 2019 14:26:27 -0700 Subject: [PATCH 12/66] Update readme.md --- samples/DotNet/Rbac/CustomRole/readme.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/samples/DotNet/Rbac/CustomRole/readme.md b/samples/DotNet/Rbac/CustomRole/readme.md index aabfe3294..3a467485b 100644 --- a/samples/DotNet/Rbac/CustomRole/readme.md +++ b/samples/DotNet/Rbac/CustomRole/readme.md @@ -19,7 +19,8 @@ To run the sample, follow these steps: 4. [Create a new AAD (Azure Active Directory) application](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal). 5. Assign AAD application to both Event Hubs namespace and Storage account with the custom role you just created. -```{ +``` +{ "Name": "Custom role for RBAC sample", "Id": "8ddab47f-cf99-4b04-8fc3-1d2d857fb931", "Description": "Test role", @@ -36,7 +37,8 @@ To run the sample, follow these steps: "AssignableScopes": [ "/subscriptions/your-subscription-id" ] -}``` +} +``` 6. Update the sample with Event Hubs namespace and Storage account name. 7. Run [Sender application](https://github.com/Azure/azure-event-hubs/tree/serkar.AddCustomRbacEhSample/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender) to send some number of messages to your event hub. From 8caf26245c71da3177e8faefd14d9c677e361e0c Mon Sep 17 00:00:00 2001 From: shvija Date: Tue, 2 Jul 2019 22:32:42 -0700 Subject: [PATCH 13/66] Adding sender sample for rbac --- samples/DotNet/Rbac/SampleSender/App.config | 46 ++++++++++ samples/DotNet/Rbac/SampleSender/Program.cs | 92 +++++++++++++++++++ .../SampleSender/Properties/AssemblyInfo.cs | 21 +++++ .../Rbac/SampleSender/SampleSender.csproj | 23 +++++ .../DotNet/Rbac/SampleSender/SampleSender.sln | 25 +++++ samples/DotNet/Rbac/SampleSender/readme.md | 29 ++++++ 6 files changed, 236 insertions(+) create mode 100644 samples/DotNet/Rbac/SampleSender/App.config create mode 100644 samples/DotNet/Rbac/SampleSender/Program.cs create mode 100644 samples/DotNet/Rbac/SampleSender/Properties/AssemblyInfo.cs create mode 100644 samples/DotNet/Rbac/SampleSender/SampleSender.csproj create mode 100644 samples/DotNet/Rbac/SampleSender/SampleSender.sln create mode 100644 samples/DotNet/Rbac/SampleSender/readme.md diff --git a/samples/DotNet/Rbac/SampleSender/App.config b/samples/DotNet/Rbac/SampleSender/App.config new file mode 100644 index 000000000..16e5b0fb3 --- /dev/null +++ b/samples/DotNet/Rbac/SampleSender/App.config @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/DotNet/Rbac/SampleSender/Program.cs b/samples/DotNet/Rbac/SampleSender/Program.cs new file mode 100644 index 000000000..b6d60a7ae --- /dev/null +++ b/samples/DotNet/Rbac/SampleSender/Program.cs @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace SampleSender +{ + using System; + using System.Text; + using System.Threading.Tasks; + using Microsoft.Azure.EventHubs; + using Microsoft.Identity.Client; + using System.Configuration; + + public class Program + { + + private static bool SetRandomPartitionKey = false; + + public static void Main(string[] args) + { + MainAsync(args).GetAwaiter().GetResult(); + } + + private static async Task MainAsync(string[] args) + { + + string clientId = ConfigurationManager.AppSettings["clientId"]; + string tenantId = ConfigurationManager.AppSettings["tenantId"]; + string eventHubsNamespace = ConfigurationManager.AppSettings["eventHubNamespaceFQDN"]; + string eventHubName = ConfigurationManager.AppSettings["eventHubName"]; + string clientSecret = ConfigurationManager.AppSettings["clientSecret"]; + + TokenProvider tp = TokenProvider.CreateAzureActiveDirectoryTokenProvider( + async (audience, authority, state) => + { + IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(clientId) + .WithTenantId(tenantId) + .WithClientSecret(ConfigurationManager.AppSettings["clientSecret"]) + .Build(); + + var authResult = await app.AcquireTokenForClient(new string[] { $"{audience}/.default" }).ExecuteAsync(); + return authResult.AccessToken; + }); + + var ehClient = EventHubClient.CreateWithTokenProvider(new Uri($"sb://{eventHubsNamespace}/"), eventHubName, tp); + await SendMessagesToEventHub(ehClient); + + Console.WriteLine("Press any key to exit."); + Console.ReadLine(); + } + + + // Creates an Event Hub client and sends 1000 messages to the event hub. + private static async Task SendMessagesToEventHub (EventHubClient ehClient) + { + var numMessagesToSend = 1000; + var rnd = new Random(); + + for (var i = 0; i < numMessagesToSend; i++) + { + try + { + var message = $"Message {i}"; + + // Set random partition key? + if (SetRandomPartitionKey) + { + var pKey = Guid.NewGuid().ToString(); + await ehClient.SendAsync(new EventData(Encoding.UTF8.GetBytes(message)), pKey); + Console.WriteLine($"Sent message: '{message}' Partition Key: '{pKey}'"); + } + else + { + await ehClient.SendAsync(new EventData(Encoding.UTF8.GetBytes(message))); + Console.WriteLine($"Sent message: '{message}'"); + } + } + catch (Exception exception) + { + Console.WriteLine($"{DateTime.Now} > Exception: {exception.Message}"); + } + + await Task.Delay(10); + } + + await ehClient.CloseAsync(); + + Console.WriteLine($"{numMessagesToSend} messages sent."); + } + + + } +} diff --git a/samples/DotNet/Rbac/SampleSender/Properties/AssemblyInfo.cs b/samples/DotNet/Rbac/SampleSender/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..2aebac99b --- /dev/null +++ b/samples/DotNet/Rbac/SampleSender/Properties/AssemblyInfo.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SampleSender")] +[assembly: AssemblyTrademark("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("940bca4a-b154-4667-8a03-57e6b689866d")] diff --git a/samples/DotNet/Rbac/SampleSender/SampleSender.csproj b/samples/DotNet/Rbac/SampleSender/SampleSender.csproj new file mode 100644 index 000000000..a5fd65e6d --- /dev/null +++ b/samples/DotNet/Rbac/SampleSender/SampleSender.csproj @@ -0,0 +1,23 @@ + + + + netcoreapp2.1 + SampleSender + Exe + SampleSender + 2.1.0 + false + false + false + + + + + + + + + + + + diff --git a/samples/DotNet/Rbac/SampleSender/SampleSender.sln b/samples/DotNet/Rbac/SampleSender/SampleSender.sln new file mode 100644 index 000000000..605104401 --- /dev/null +++ b/samples/DotNet/Rbac/SampleSender/SampleSender.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.10 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleSender", "SampleSender.csproj", "{940BCA4A-B154-4667-8A03-57E6B689866D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {940BCA4A-B154-4667-8A03-57E6B689866D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {940BCA4A-B154-4667-8A03-57E6B689866D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {940BCA4A-B154-4667-8A03-57E6B689866D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {940BCA4A-B154-4667-8A03-57E6B689866D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {85AFEF9E-A513-4DB5-8336-ED9024AC5407} + EndGlobalSection +EndGlobal diff --git a/samples/DotNet/Rbac/SampleSender/readme.md b/samples/DotNet/Rbac/SampleSender/readme.md new file mode 100644 index 000000000..0054911dc --- /dev/null +++ b/samples/DotNet/Rbac/SampleSender/readme.md @@ -0,0 +1,29 @@ +# Send events to Azure Event Hubs in .NET Standard + +This sample shows how to write a .NET Core console application that sends a set of events to an event hub. You can run the solution as-is, replacing the `EhConnectionString` and `EhEntityPath` strings with your event hub values. The sample is also [available as a tutorial](https://docs.microsoft.com/azure/event-hubs/event-hubs-dotnet-standard-getstarted-send). + +## Prerequisites + +* [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). +* [.NET Core Visual Studio 2015 or 2017 tools](http://www.microsoft.com/net/core). +* An Azure subscription. +* [An event hub namespace and an event hub](event-hubs-quickstart-namespace-portal.md). + +## Run the sample + +To run the sample, follow these steps: + +1. Clone or download this GitHub repo. +2. [Create an Event Hubs namespace and an event hub](https://docs.microsoft.com/azure/event-hubs/event-hubs-create). +3. In Visual Studio, select **File**, then **Open Project/Soultion**. Navigate to the \azure-event-hubs\samples\DotNet\Microsoft.Azure.EventHubs\SampleSender folder. +4. Load the SampleSender.sln solution file into Visual Studio. +5. Add the [Microsoft.Azure.EventHubs](https://www.nuget.org/packages/Microsoft.Azure.EventHubs/) NuGet package to the project. +6. In Program.cs, replace the placeholders in brackets with the proper values that were obtained when creating the event hub. Make sure that the `Event Hubs connection string` is the namespace-level connection string, and not the event hub string: + ```csharp + private const string EhConnectionString = "Event Hubs connection string"; + private const string EhEntityPath = "Event Hub name"; + ``` +7. Run the program, and ensure that there are no errors. + +Congratulations! You have now sent events to an event hub. To receive these events, see the [SampleEphReceiver](https://github.com/Azure/azure-event-hubs/tree/master/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver) sample. + From 23d3eaa45b73b234f4b3b12f39cab21087acc9c3 Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Thu, 18 Jul 2019 14:36:13 -0700 Subject: [PATCH 14/66] Moving Managed Identity sample to .NET Standard SDK --- .../EventHubsMSIDemo.aspx | 35 --- .../EventHubsMSIDemo.aspx.cs | 78 ------- .../EventHubsMSIDemoWebApp.csproj | 170 -------------- .../EventHubsMSIDemoWebApp/Global.asax | 1 - .../EventHubsMSIDemoWebApp/packages.config | 10 - .../Rbac/ManagedIdentityWebApp/Global.asax | 1 + .../ManagedIdentityWebApp}/Global.asax.cs | 2 +- .../ManagedIdentityWebApp.csproj | 220 ++++++++++++++++++ .../ManagedIdentityWebApp.sln} | 2 +- .../Properties/AssemblyInfo.cs | 4 +- .../ManagedIdentityWebApp}/README.md | 0 .../ManagedIdentityWebApp/SendReceive.aspx | 35 +++ .../ManagedIdentityWebApp/SendReceive.aspx.cs | 69 ++++++ .../SendReceive.aspx.designer.cs} | 8 +- .../ManagedIdentityWebApp}/StyleSheet.css | 2 +- .../ManagedIdentityWebApp}/Web.Debug.config | 0 .../ManagedIdentityWebApp}/Web.Release.config | 0 .../ManagedIdentityWebApp}/Web.config | 34 ++- .../ManagedIdentityWebApp/packages.config | 23 ++ 19 files changed, 384 insertions(+), 310 deletions(-) delete mode 100644 samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemo.aspx delete mode 100644 samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemo.aspx.cs delete mode 100644 samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp.csproj delete mode 100644 samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Global.asax delete mode 100644 samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/packages.config create mode 100644 samples/DotNet/Rbac/ManagedIdentityWebApp/Global.asax rename samples/DotNet/{MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp => Rbac/ManagedIdentityWebApp}/Global.asax.cs (90%) create mode 100644 samples/DotNet/Rbac/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj rename samples/DotNet/{MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp.sln => Rbac/ManagedIdentityWebApp/ManagedIdentityWebApp.sln} (84%) rename samples/DotNet/{MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp => Rbac/ManagedIdentityWebApp}/Properties/AssemblyInfo.cs (92%) rename samples/DotNet/{MSI/EventHubsMSIDemoWebApp => Rbac/ManagedIdentityWebApp}/README.md (100%) create mode 100644 samples/DotNet/Rbac/ManagedIdentityWebApp/SendReceive.aspx create mode 100644 samples/DotNet/Rbac/ManagedIdentityWebApp/SendReceive.aspx.cs rename samples/DotNet/{MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemo.aspx.designer.cs => Rbac/ManagedIdentityWebApp/SendReceive.aspx.designer.cs} (94%) rename samples/DotNet/{MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp => Rbac/ManagedIdentityWebApp}/StyleSheet.css (88%) rename samples/DotNet/{MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp => Rbac/ManagedIdentityWebApp}/Web.Debug.config (100%) rename samples/DotNet/{MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp => Rbac/ManagedIdentityWebApp}/Web.Release.config (100%) rename samples/DotNet/{MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp => Rbac/ManagedIdentityWebApp}/Web.config (53%) create mode 100644 samples/DotNet/Rbac/ManagedIdentityWebApp/packages.config diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemo.aspx b/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemo.aspx deleted file mode 100644 index e61820b6f..000000000 --- a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemo.aspx +++ /dev/null @@ -1,35 +0,0 @@ -<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="EventHubsMSIDemo.aspx.cs" Inherits="EventHubsMSIDemoWebApp.EventHubsMSIDemo" %> - - - - - - EventHubs MSI Demo - - - -
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
-
- - diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemo.aspx.cs b/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemo.aspx.cs deleted file mode 100644 index cd076841b..000000000 --- a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemo.aspx.cs +++ /dev/null @@ -1,78 +0,0 @@ -using Microsoft.ServiceBus; -using Microsoft.ServiceBus.Messaging; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Web; -using System.Web.UI; -using System.Web.UI.WebControls; - -// Always add app to IAM roles -// Don't use on deployment slots but only on root -namespace EventHubsMSIDemoWebApp -{ - public partial class EventHubsMSIDemo : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - - } - - protected void btnSend_Click(object sender, EventArgs e) - { - MessagingFactorySettings messagingFactorySettings = new MessagingFactorySettings - { - TokenProvider = TokenProvider.CreateManagedServiceIdentityTokenProvider(ServiceAudience.EventHubsAudience), - TransportType = TransportType.Amqp - }; - - MessagingFactory messagingFactory = MessagingFactory.Create($"sb://{txtNamespace.Text}.servicebus.windows.net/", - messagingFactorySettings); - - EventHubClient ehClient = messagingFactory.CreateEventHubClient(txtEventHub.Text); - ehClient.Send(new EventData(Encoding.UTF8.GetBytes(txtData.Text))); - ehClient.Close(); - messagingFactory.Close(); - } - - protected void btnReceive_Click(object sender, EventArgs e) - { - MessagingFactorySettings messagingFactorySettings = new MessagingFactorySettings - { - TokenProvider = TokenProvider.CreateManagedServiceIdentityTokenProvider(ServiceAudience.EventHubsAudience), - TransportType = TransportType.Amqp - }; - - messagingFactorySettings.AmqpTransportSettings.EnableLinkRedirect = false; - - MessagingFactory messagingFactory = MessagingFactory.Create($"sb://{txtNamespace.Text}.servicebus.windows.net/", - messagingFactorySettings); - - EventHubClient ehClient = messagingFactory.CreateEventHubClient(txtEventHub.Text); - EventHubConsumerGroup consumerGroup = ehClient.GetDefaultConsumerGroup(); - int partitions = int.Parse(txtPartitions.Text); - string[] Offsets = new string[partitions]; - if (!string.IsNullOrEmpty(hiddenStartingOffset.Value)) - { - Offsets = hiddenStartingOffset.Value.Split(','); - } - System.Threading.Tasks.Parallel.ForEach(Enumerable.Range(0, int.Parse(txtPartitions.Text)), partitionId => - { - EventHubReceiver receiver = consumerGroup.CreateReceiver($"{partitionId}", Offsets[partitionId] == null ? "-1" : Offsets[partitionId]); - EventData data = receiver.Receive(TimeSpan.FromSeconds(1)); - if (data != null) - { - Offsets[partitionId] = data.Offset; - txtReceivedData.Text += $"PartitionId: {partitionId} Seq#:{data.SequenceNumber} data:{Encoding.UTF8.GetString(data.GetBytes())}{Environment.NewLine}"; - } - receiver.Close(); - }); - - hiddenStartingOffset.Value = string.Join(",", Offsets); - ehClient.Close(); - messagingFactory.Close(); - } - } -} \ No newline at end of file diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp.csproj b/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp.csproj deleted file mode 100644 index 11622983d..000000000 --- a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp.csproj +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - Debug - AnyCPU - - - 2.0 - {476F98B4-05BF-42B6-B0B4-E50CD5B71635} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - EventHubsMSIDemoWebApp - EventHubsMSIDemoWebApp - v4.6.1 - true - - - - - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - true - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - ..\packages\Microsoft.Azure.Services.AppAuthentication.1.1.0-preview\lib\net452\Microsoft.Azure.Services.AppAuthentication.dll - - - ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.7\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll - - - - ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.14.2\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll - - - ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.14.2\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll - - - ..\packages\WindowsAzure.ServiceBus.4.1.6\lib\net45\Microsoft.ServiceBus.dll - - - ..\packages\Newtonsoft.Json.11.0.1-beta1\lib\net45\Newtonsoft.Json.dll - - - ..\packages\System.IdentityModel.Tokens.Jwt.4.0.4.403061554\lib\net45\System.IdentityModel.Tokens.Jwt.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Web.config - - - Web.config - - - - - - - - Designer - - - - - EventHubsMSIDemo.aspx - ASPXCodeBehind - - - EventHubsMSIDemo.aspx - - - Global.asax - - - - - - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - True - True - 56779 - / - http://localhost:56779/ - False - False - - - False - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - \ No newline at end of file diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Global.asax b/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Global.asax deleted file mode 100644 index 6245438a1..000000000 --- a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Global.asax +++ /dev/null @@ -1 +0,0 @@ -<%@ Application Codebehind="Global.asax.cs" Inherits="EventHubsMSIDemoWebApp.Global" Language="C#" %> diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/packages.config b/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/packages.config deleted file mode 100644 index aab789b1a..000000000 --- a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/packages.config +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/samples/DotNet/Rbac/ManagedIdentityWebApp/Global.asax b/samples/DotNet/Rbac/ManagedIdentityWebApp/Global.asax new file mode 100644 index 000000000..21d85acb9 --- /dev/null +++ b/samples/DotNet/Rbac/ManagedIdentityWebApp/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="ManagedIdentityWebApp.Global" Language="C#" %> diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Global.asax.cs b/samples/DotNet/Rbac/ManagedIdentityWebApp/Global.asax.cs similarity index 90% rename from samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Global.asax.cs rename to samples/DotNet/Rbac/ManagedIdentityWebApp/Global.asax.cs index 8e8cf42b3..e483b9141 100644 --- a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Global.asax.cs +++ b/samples/DotNet/Rbac/ManagedIdentityWebApp/Global.asax.cs @@ -5,7 +5,7 @@ using System.Web.Security; using System.Web.SessionState; -namespace EventHubsMSIDemoWebApp +namespace ManagedIdentityWebApp { public class Global : System.Web.HttpApplication { diff --git a/samples/DotNet/Rbac/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj b/samples/DotNet/Rbac/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj new file mode 100644 index 000000000..a68708940 --- /dev/null +++ b/samples/DotNet/Rbac/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj @@ -0,0 +1,220 @@ + + + + + Debug + AnyCPU + + + 2.0 + {476F98B4-05BF-42B6-B0B4-E50CD5B71635} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + ManagedIdentityWebApp + ManagedIdentityWebApp + v4.7.2 + true + + + + + + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + true + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + packages\Microsoft.Azure.Amqp.2.4.3\lib\net45\Microsoft.Azure.Amqp.dll + + + packages\Microsoft.Azure.EventHubs.4.0.0\lib\net461\Microsoft.Azure.EventHubs.dll + True + + + packages\Microsoft.Azure.Services.AppAuthentication.1.2.1\lib\net472\Microsoft.Azure.Services.AppAuthentication.dll + + + packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll + + + + packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll + + + packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll + + + packages\Microsoft.IdentityModel.JsonWebTokens.5.5.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll + + + packages\Microsoft.IdentityModel.Logging.5.5.0\lib\net461\Microsoft.IdentityModel.Logging.dll + + + packages\Microsoft.IdentityModel.Tokens.5.5.0\lib\net461\Microsoft.IdentityModel.Tokens.dll + + + packages\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll + + + + packages\System.Diagnostics.DiagnosticSource.4.5.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + packages\System.IdentityModel.Tokens.Jwt.5.5.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll + + + packages\System.IO.4.3.0\lib\net462\System.IO.dll + True + True + + + + packages\System.Net.WebSockets.4.0.0\lib\net46\System.Net.WebSockets.dll + True + True + + + packages\System.Net.WebSockets.Client.4.0.2\lib\net46\System.Net.WebSockets.Client.dll + True + True + + + packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll + True + True + + + + packages\System.Runtime.Serialization.Primitives.4.1.1\lib\net46\System.Runtime.Serialization.Primitives.dll + True + True + + + packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll + True + True + + + packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll + True + True + + + packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + True + True + + + packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + True + True + + + + + + + + + + + + + + + + + + + + Web.config + + + Web.config + + + + + + + + Designer + + + + + SendReceive.aspx + ASPXCodeBehind + + + SendReceive.aspx + + + Global.asax + + + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + True + True + 56779 + / + http://localhost:56779/ + False + False + + + False + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp.sln b/samples/DotNet/Rbac/ManagedIdentityWebApp/ManagedIdentityWebApp.sln similarity index 84% rename from samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp.sln rename to samples/DotNet/Rbac/ManagedIdentityWebApp/ManagedIdentityWebApp.sln index aa57c11b9..99d261930 100644 --- a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp.sln +++ b/samples/DotNet/Rbac/ManagedIdentityWebApp/ManagedIdentityWebApp.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27004.2010 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventHubsMSIDemoWebApp", "EventHubsMSIDemoWebApp\EventHubsMSIDemoWebApp.csproj", "{476F98B4-05BF-42B6-B0B4-E50CD5B71635}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedIdentityWebApp", "ManagedIdentityWebApp.csproj", "{476F98B4-05BF-42B6-B0B4-E50CD5B71635}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Properties/AssemblyInfo.cs b/samples/DotNet/Rbac/ManagedIdentityWebApp/Properties/AssemblyInfo.cs similarity index 92% rename from samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Properties/AssemblyInfo.cs rename to samples/DotNet/Rbac/ManagedIdentityWebApp/Properties/AssemblyInfo.cs index 27de5cefb..eb184e7ac 100644 --- a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Properties/AssemblyInfo.cs +++ b/samples/DotNet/Rbac/ManagedIdentityWebApp/Properties/AssemblyInfo.cs @@ -5,11 +5,11 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("EventHubsMSIDemoWebApp")] +[assembly: AssemblyTitle("ManagedIdentityWebApp")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("EventHubsMSIDemoWebApp")] +[assembly: AssemblyProduct("ManagedIdentityWebApp")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/README.md b/samples/DotNet/Rbac/ManagedIdentityWebApp/README.md similarity index 100% rename from samples/DotNet/MSI/EventHubsMSIDemoWebApp/README.md rename to samples/DotNet/Rbac/ManagedIdentityWebApp/README.md diff --git a/samples/DotNet/Rbac/ManagedIdentityWebApp/SendReceive.aspx b/samples/DotNet/Rbac/ManagedIdentityWebApp/SendReceive.aspx new file mode 100644 index 000000000..afa25938d --- /dev/null +++ b/samples/DotNet/Rbac/ManagedIdentityWebApp/SendReceive.aspx @@ -0,0 +1,35 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SendReceive.aspx.cs" Inherits="ManagedIdentityWebApp.SendReceive" %> + + + + + + EventHubs Managed Identity Demo + + + +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+
+ + diff --git a/samples/DotNet/Rbac/ManagedIdentityWebApp/SendReceive.aspx.cs b/samples/DotNet/Rbac/ManagedIdentityWebApp/SendReceive.aspx.cs new file mode 100644 index 000000000..609913342 --- /dev/null +++ b/samples/DotNet/Rbac/ManagedIdentityWebApp/SendReceive.aspx.cs @@ -0,0 +1,69 @@ +using System; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Azure.EventHubs; + +// Always add app to IAM roles +// Don't use on deployment slots but only on root +namespace ManagedIdentityWebApp +{ + public partial class SendReceive : System.Web.UI.Page + { + protected void Page_Load(object sender, EventArgs e) + { + + } + + protected void btnSend_Click(object sender, EventArgs e) + { + EventHubClient ehClient = EventHubClient.CreateWithManagedIdentity(new Uri($"sb://{txtNamespace.Text}.servicebus.windows.net/"), txtEventHub.Text); + ehClient.SendAsync(new EventData(Encoding.UTF8.GetBytes(txtData.Text))).GetAwaiter().GetResult(); + txtOutput.Text = $"{DateTime.Now} - SENT{Environment.NewLine}" + txtOutput.Text; + ehClient.Close(); + } + + protected void btnReceive_Click(object sender, EventArgs e) + { + EventHubClient ehClient = EventHubClient.CreateWithManagedIdentity(new Uri($"sb://{txtNamespace.Text}.servicebus.windows.net/"), txtEventHub.Text); + int partitions = int.Parse(txtPartitions.Text); + string[] lastOffsets = new string[partitions]; + + if (!string.IsNullOrEmpty(hiddenStartingOffset.Value)) + { + lastOffsets = hiddenStartingOffset.Value.Split(','); + } + + var totalReceived = 0; + + Parallel.ForEach(Enumerable.Range(0, int.Parse(txtPartitions.Text)), partitionId => + { + var receiver = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, $"{partitionId}", lastOffsets[partitionId] == null ? EventPosition.FromStart() : EventPosition.FromOffset(lastOffsets[partitionId])); + var messages = receiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(15)).GetAwaiter().GetResult(); + + if (messages != null) + { + foreach (var message in messages) + { + txtOutput.Text = $"{DateTime.Now} - RECEIVED PartitionId: {partitionId} Seq#:{message.SystemProperties.SequenceNumber} data:{Encoding.UTF8.GetString(message.Body.Array)}{Environment.NewLine}" + txtOutput.Text; + lastOffsets[partitionId] = message.SystemProperties.Offset; + } + + Interlocked.Add(ref totalReceived, messages.Count()); + } + + receiver.Close(); + }); + + txtOutput.Text = $"{DateTime.Now} - RECEIVED TOTAL = {totalReceived}{Environment.NewLine}" + txtOutput.Text; + + if (totalReceived > 0) + { + hiddenStartingOffset.Value = string.Join(",", lastOffsets); + } + + ehClient.Close(); + } + } +} \ No newline at end of file diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemo.aspx.designer.cs b/samples/DotNet/Rbac/ManagedIdentityWebApp/SendReceive.aspx.designer.cs similarity index 94% rename from samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemo.aspx.designer.cs rename to samples/DotNet/Rbac/ManagedIdentityWebApp/SendReceive.aspx.designer.cs index 98a8eb487..00124e3c9 100644 --- a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/EventHubsMSIDemo.aspx.designer.cs +++ b/samples/DotNet/Rbac/ManagedIdentityWebApp/SendReceive.aspx.designer.cs @@ -7,10 +7,10 @@ // //------------------------------------------------------------------------------ -namespace EventHubsMSIDemoWebApp { +namespace ManagedIdentityWebApp { - public partial class EventHubsMSIDemo { + public partial class SendReceive { /// /// form1 control. @@ -76,13 +76,13 @@ public partial class EventHubsMSIDemo { protected global::System.Web.UI.WebControls.Button btnReceive; /// - /// txtReceivedData control. + /// txtOutput control. /// /// /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::System.Web.UI.WebControls.TextBox txtReceivedData; + protected global::System.Web.UI.WebControls.TextBox txtOutput; /// /// hiddenStartingOffset control. diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/StyleSheet.css b/samples/DotNet/Rbac/ManagedIdentityWebApp/StyleSheet.css similarity index 88% rename from samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/StyleSheet.css rename to samples/DotNet/Rbac/ManagedIdentityWebApp/StyleSheet.css index 9b0b73b9e..18b4dd479 100644 --- a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/StyleSheet.css +++ b/samples/DotNet/Rbac/ManagedIdentityWebApp/StyleSheet.css @@ -1,5 +1,5 @@ label { - width: 100px; + width: 200px; display: inline-block; } diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Web.Debug.config b/samples/DotNet/Rbac/ManagedIdentityWebApp/Web.Debug.config similarity index 100% rename from samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Web.Debug.config rename to samples/DotNet/Rbac/ManagedIdentityWebApp/Web.Debug.config diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Web.Release.config b/samples/DotNet/Rbac/ManagedIdentityWebApp/Web.Release.config similarity index 100% rename from samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Web.Release.config rename to samples/DotNet/Rbac/ManagedIdentityWebApp/Web.Release.config diff --git a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Web.config b/samples/DotNet/Rbac/ManagedIdentityWebApp/Web.config similarity index 53% rename from samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Web.config rename to samples/DotNet/Rbac/ManagedIdentityWebApp/Web.config index 245b26e30..635d14d02 100644 --- a/samples/DotNet/MSI/EventHubsMSIDemoWebApp/EventHubsMSIDemoWebApp/Web.config +++ b/samples/DotNet/Rbac/ManagedIdentityWebApp/Web.config @@ -4,23 +4,43 @@ https://go.microsoft.com/fwlink/?LinkId=169433 --> + - + - - - - - - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/DotNet/Rbac/ManagedIdentityWebApp/packages.config b/samples/DotNet/Rbac/ManagedIdentityWebApp/packages.config new file mode 100644 index 000000000..c5c4cbbc5 --- /dev/null +++ b/samples/DotNet/Rbac/ManagedIdentityWebApp/packages.config @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 566ef0c0e081488eea9083b12c829b75aab2cc64 Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Thu, 18 Jul 2019 14:40:22 -0700 Subject: [PATCH 15/66] Remove unintended SampleSender changes --- samples/DotNet/Rbac/SampleSender/App.config | 46 ---------- samples/DotNet/Rbac/SampleSender/Program.cs | 92 ------------------- .../SampleSender/Properties/AssemblyInfo.cs | 21 ----- .../Rbac/SampleSender/SampleSender.csproj | 23 ----- .../DotNet/Rbac/SampleSender/SampleSender.sln | 25 ----- samples/DotNet/Rbac/SampleSender/readme.md | 29 ------ 6 files changed, 236 deletions(-) delete mode 100644 samples/DotNet/Rbac/SampleSender/App.config delete mode 100644 samples/DotNet/Rbac/SampleSender/Program.cs delete mode 100644 samples/DotNet/Rbac/SampleSender/Properties/AssemblyInfo.cs delete mode 100644 samples/DotNet/Rbac/SampleSender/SampleSender.csproj delete mode 100644 samples/DotNet/Rbac/SampleSender/SampleSender.sln delete mode 100644 samples/DotNet/Rbac/SampleSender/readme.md diff --git a/samples/DotNet/Rbac/SampleSender/App.config b/samples/DotNet/Rbac/SampleSender/App.config deleted file mode 100644 index 16e5b0fb3..000000000 --- a/samples/DotNet/Rbac/SampleSender/App.config +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/DotNet/Rbac/SampleSender/Program.cs b/samples/DotNet/Rbac/SampleSender/Program.cs deleted file mode 100644 index b6d60a7ae..000000000 --- a/samples/DotNet/Rbac/SampleSender/Program.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace SampleSender -{ - using System; - using System.Text; - using System.Threading.Tasks; - using Microsoft.Azure.EventHubs; - using Microsoft.Identity.Client; - using System.Configuration; - - public class Program - { - - private static bool SetRandomPartitionKey = false; - - public static void Main(string[] args) - { - MainAsync(args).GetAwaiter().GetResult(); - } - - private static async Task MainAsync(string[] args) - { - - string clientId = ConfigurationManager.AppSettings["clientId"]; - string tenantId = ConfigurationManager.AppSettings["tenantId"]; - string eventHubsNamespace = ConfigurationManager.AppSettings["eventHubNamespaceFQDN"]; - string eventHubName = ConfigurationManager.AppSettings["eventHubName"]; - string clientSecret = ConfigurationManager.AppSettings["clientSecret"]; - - TokenProvider tp = TokenProvider.CreateAzureActiveDirectoryTokenProvider( - async (audience, authority, state) => - { - IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(clientId) - .WithTenantId(tenantId) - .WithClientSecret(ConfigurationManager.AppSettings["clientSecret"]) - .Build(); - - var authResult = await app.AcquireTokenForClient(new string[] { $"{audience}/.default" }).ExecuteAsync(); - return authResult.AccessToken; - }); - - var ehClient = EventHubClient.CreateWithTokenProvider(new Uri($"sb://{eventHubsNamespace}/"), eventHubName, tp); - await SendMessagesToEventHub(ehClient); - - Console.WriteLine("Press any key to exit."); - Console.ReadLine(); - } - - - // Creates an Event Hub client and sends 1000 messages to the event hub. - private static async Task SendMessagesToEventHub (EventHubClient ehClient) - { - var numMessagesToSend = 1000; - var rnd = new Random(); - - for (var i = 0; i < numMessagesToSend; i++) - { - try - { - var message = $"Message {i}"; - - // Set random partition key? - if (SetRandomPartitionKey) - { - var pKey = Guid.NewGuid().ToString(); - await ehClient.SendAsync(new EventData(Encoding.UTF8.GetBytes(message)), pKey); - Console.WriteLine($"Sent message: '{message}' Partition Key: '{pKey}'"); - } - else - { - await ehClient.SendAsync(new EventData(Encoding.UTF8.GetBytes(message))); - Console.WriteLine($"Sent message: '{message}'"); - } - } - catch (Exception exception) - { - Console.WriteLine($"{DateTime.Now} > Exception: {exception.Message}"); - } - - await Task.Delay(10); - } - - await ehClient.CloseAsync(); - - Console.WriteLine($"{numMessagesToSend} messages sent."); - } - - - } -} diff --git a/samples/DotNet/Rbac/SampleSender/Properties/AssemblyInfo.cs b/samples/DotNet/Rbac/SampleSender/Properties/AssemblyInfo.cs deleted file mode 100644 index 2aebac99b..000000000 --- a/samples/DotNet/Rbac/SampleSender/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SampleSender")] -[assembly: AssemblyTrademark("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("940bca4a-b154-4667-8a03-57e6b689866d")] diff --git a/samples/DotNet/Rbac/SampleSender/SampleSender.csproj b/samples/DotNet/Rbac/SampleSender/SampleSender.csproj deleted file mode 100644 index a5fd65e6d..000000000 --- a/samples/DotNet/Rbac/SampleSender/SampleSender.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - netcoreapp2.1 - SampleSender - Exe - SampleSender - 2.1.0 - false - false - false - - - - - - - - - - - - diff --git a/samples/DotNet/Rbac/SampleSender/SampleSender.sln b/samples/DotNet/Rbac/SampleSender/SampleSender.sln deleted file mode 100644 index 605104401..000000000 --- a/samples/DotNet/Rbac/SampleSender/SampleSender.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26730.10 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleSender", "SampleSender.csproj", "{940BCA4A-B154-4667-8A03-57E6B689866D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {940BCA4A-B154-4667-8A03-57E6B689866D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {940BCA4A-B154-4667-8A03-57E6B689866D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {940BCA4A-B154-4667-8A03-57E6B689866D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {940BCA4A-B154-4667-8A03-57E6B689866D}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {85AFEF9E-A513-4DB5-8336-ED9024AC5407} - EndGlobalSection -EndGlobal diff --git a/samples/DotNet/Rbac/SampleSender/readme.md b/samples/DotNet/Rbac/SampleSender/readme.md deleted file mode 100644 index 0054911dc..000000000 --- a/samples/DotNet/Rbac/SampleSender/readme.md +++ /dev/null @@ -1,29 +0,0 @@ -# Send events to Azure Event Hubs in .NET Standard - -This sample shows how to write a .NET Core console application that sends a set of events to an event hub. You can run the solution as-is, replacing the `EhConnectionString` and `EhEntityPath` strings with your event hub values. The sample is also [available as a tutorial](https://docs.microsoft.com/azure/event-hubs/event-hubs-dotnet-standard-getstarted-send). - -## Prerequisites - -* [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). -* [.NET Core Visual Studio 2015 or 2017 tools](http://www.microsoft.com/net/core). -* An Azure subscription. -* [An event hub namespace and an event hub](event-hubs-quickstart-namespace-portal.md). - -## Run the sample - -To run the sample, follow these steps: - -1. Clone or download this GitHub repo. -2. [Create an Event Hubs namespace and an event hub](https://docs.microsoft.com/azure/event-hubs/event-hubs-create). -3. In Visual Studio, select **File**, then **Open Project/Soultion**. Navigate to the \azure-event-hubs\samples\DotNet\Microsoft.Azure.EventHubs\SampleSender folder. -4. Load the SampleSender.sln solution file into Visual Studio. -5. Add the [Microsoft.Azure.EventHubs](https://www.nuget.org/packages/Microsoft.Azure.EventHubs/) NuGet package to the project. -6. In Program.cs, replace the placeholders in brackets with the proper values that were obtained when creating the event hub. Make sure that the `Event Hubs connection string` is the namespace-level connection string, and not the event hub string: - ```csharp - private const string EhConnectionString = "Event Hubs connection string"; - private const string EhEntityPath = "Event Hub name"; - ``` -7. Run the program, and ensure that there are no errors. - -Congratulations! You have now sent events to an event hub. To receive these events, see the [SampleEphReceiver](https://github.com/Azure/azure-event-hubs/tree/master/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver) sample. - From 12583b9f8f2e4123626ddf84cf27845241a9ef3e Mon Sep 17 00:00:00 2001 From: Shubha Vijayasarathy Date: Sun, 21 Jul 2019 21:16:08 -0700 Subject: [PATCH 16/66] Revert "Updates for Java client 3.0.0 RBAC release" (#448) --- .../Java/Basic/AdvancedSendOptions/pom.xml | 2 +- .../AdvancedSendOptions.java | 2 +- .../Basic/EventProcessorSample/.classpath | 28 ++++ .../Java/Basic/EventProcessorSample/.project | 23 +++ .../Java/Basic/EventProcessorSample/pom.xml | 4 +- .../EventProcessorSample.java | 14 +- samples/Java/Basic/ReceiveByDateTime/pom.xml | 2 +- .../receivebydatetime/ReceiveByDateTime.java | 2 +- .../Basic/ReceiveUsingSequenceNumber/pom.xml | 2 +- .../ReceiveUsingSequenceNumber.java | 2 +- samples/Java/Basic/SendBatch/pom.xml | 2 +- .../samples/sendbatch/SendBatch.java | 2 +- samples/Java/Basic/SimpleProxy/pom.xml | 2 +- .../SimpleProxy.java | 137 ++++++++++++++++++ samples/Java/Basic/SimpleSend/pom.xml | 2 +- .../samples/SimpleSend/SimpleSend.java | 2 +- .../Benchmarks/AutoScaleOnIngress/pom.xml | 2 +- .../EventHubClientPool.java | 2 +- .../Java/Benchmarks/IngressBenchmark/pom.xml | 2 +- .../ingressbenchmark/EventHubClientPool.java | 2 +- 20 files changed, 213 insertions(+), 23 deletions(-) create mode 100644 samples/Java/Basic/EventProcessorSample/.classpath create mode 100644 samples/Java/Basic/EventProcessorSample/.project create mode 100644 samples/Java/Basic/SimpleProxy/src/main/java/com.microsoft.azure.eventhubs.samples.SimpleProxy/SimpleProxy.java diff --git a/samples/Java/Basic/AdvancedSendOptions/pom.xml b/samples/Java/Basic/AdvancedSendOptions/pom.xml index 6b9c1d9c1..b0bde814f 100644 --- a/samples/Java/Basic/AdvancedSendOptions/pom.xml +++ b/samples/Java/Basic/AdvancedSendOptions/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 2.3.0 com.google.code.gson diff --git a/samples/Java/Basic/AdvancedSendOptions/src/main/java/com/microsoft/azure/eventhubs/samples/AdvancedSendOptions/AdvancedSendOptions.java b/samples/Java/Basic/AdvancedSendOptions/src/main/java/com/microsoft/azure/eventhubs/samples/AdvancedSendOptions/AdvancedSendOptions.java index b7e6a77a7..4d5fedc7b 100644 --- a/samples/Java/Basic/AdvancedSendOptions/src/main/java/com/microsoft/azure/eventhubs/samples/AdvancedSendOptions/AdvancedSendOptions.java +++ b/samples/Java/Basic/AdvancedSendOptions/src/main/java/com/microsoft/azure/eventhubs/samples/AdvancedSendOptions/AdvancedSendOptions.java @@ -46,7 +46,7 @@ public static void main(String[] args) // Each EventHubClient instance spins up a new TCP/SSL connection, which is expensive. // It is always a best practice to reuse these instances. The following sample shows the same. - final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); PartitionSender sender = null; try { diff --git a/samples/Java/Basic/EventProcessorSample/.classpath b/samples/Java/Basic/EventProcessorSample/.classpath new file mode 100644 index 000000000..db2a016f9 --- /dev/null +++ b/samples/Java/Basic/EventProcessorSample/.classpath @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/Java/Basic/EventProcessorSample/.project b/samples/Java/Basic/EventProcessorSample/.project new file mode 100644 index 000000000..03043695d --- /dev/null +++ b/samples/Java/Basic/EventProcessorSample/.project @@ -0,0 +1,23 @@ + + + EventProcessorSample + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/samples/Java/Basic/EventProcessorSample/pom.xml b/samples/Java/Basic/EventProcessorSample/pom.xml index e34f13b7d..7f8149c0d 100644 --- a/samples/Java/Basic/EventProcessorSample/pom.xml +++ b/samples/Java/Basic/EventProcessorSample/pom.xml @@ -47,12 +47,12 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 2.3.0 com.microsoft.azure azure-eventhubs-eph - 3.0.0 + 2.5.0 log4j diff --git a/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java b/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java index 18f57aced..d46b88eb8 100644 --- a/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java +++ b/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java @@ -12,7 +12,6 @@ import com.microsoft.azure.eventprocessorhost.ExceptionReceivedEventArgs; import com.microsoft.azure.eventprocessorhost.IEventProcessor; import com.microsoft.azure.eventprocessorhost.PartitionContext; -import com.microsoft.azure.eventprocessorhost.EventProcessorHost.EventProcessorHostBuilder; import java.util.concurrent.ExecutionException; import java.util.function.Consumer; @@ -44,13 +43,16 @@ public static void main(String args[]) throws InterruptedException, ExecutionExc .setSasKeyName(sasKeyName) .setSasKey(sasKey); - // Create the instance of EventProcessorHost using the builder. This sample uses Azure Storage for + // Create the instance of EventProcessorHost using the most basic constructor. This constructor uses Azure Storage for // persisting partition leases and checkpoints. The host name, which identifies the instance of EventProcessorHost, must be unique. // You can use a plain UUID, or use the createHostName utility method which appends a UUID to a supplied string. - EventProcessorHost host = EventProcessorHostBuilder.newBuilder(EventProcessorHost.createHostName(hostNamePrefix), consumerGroupName) - .useAzureStorageCheckpointLeaseManager(storageConnectionString, storageContainerName, "") - .useEventHubConnectionString(eventHubConnectionString.toString(), eventHubName) - .build(); + EventProcessorHost host = new EventProcessorHost( + EventProcessorHost.createHostName(hostNamePrefix), + eventHubName, + consumerGroupName, + eventHubConnectionString.toString(), + storageConnectionString, + storageContainerName); // Registering an event processor class with an instance of EventProcessorHost starts event processing. The host instance // obtains leases on some partitions of the Event Hub, possibly stealing some from other host instances, in a way that diff --git a/samples/Java/Basic/ReceiveByDateTime/pom.xml b/samples/Java/Basic/ReceiveByDateTime/pom.xml index f81e8db50..3108cd866 100644 --- a/samples/Java/Basic/ReceiveByDateTime/pom.xml +++ b/samples/Java/Basic/ReceiveByDateTime/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 2.3.0 diff --git a/samples/Java/Basic/ReceiveByDateTime/src/main/java/com/microsoft/azure/eventhubs/samples/receivebydatetime/ReceiveByDateTime.java b/samples/Java/Basic/ReceiveByDateTime/src/main/java/com/microsoft/azure/eventhubs/samples/receivebydatetime/ReceiveByDateTime.java index 57f72ce6b..bb73e1af2 100644 --- a/samples/Java/Basic/ReceiveByDateTime/src/main/java/com/microsoft/azure/eventhubs/samples/receivebydatetime/ReceiveByDateTime.java +++ b/samples/Java/Basic/ReceiveByDateTime/src/main/java/com/microsoft/azure/eventhubs/samples/receivebydatetime/ReceiveByDateTime.java @@ -31,7 +31,7 @@ public static void main(String[] args) .setSasKey("---SharedAccessSignatureKey----"); final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); - final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); final EventHubRuntimeInformation eventHubInfo = ehClient.getRuntimeInformation().get(); final String partitionId = eventHubInfo.getPartitionIds()[0]; // get first partition's id diff --git a/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml b/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml index 812191033..82e583349 100644 --- a/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml +++ b/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 2.3.0 diff --git a/samples/Java/Basic/ReceiveUsingSequenceNumber/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingsequencenumber/ReceiveUsingSequenceNumber.java b/samples/Java/Basic/ReceiveUsingSequenceNumber/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingsequencenumber/ReceiveUsingSequenceNumber.java index 77de83a5c..8027db35a 100644 --- a/samples/Java/Basic/ReceiveUsingSequenceNumber/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingsequencenumber/ReceiveUsingSequenceNumber.java +++ b/samples/Java/Basic/ReceiveUsingSequenceNumber/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingsequencenumber/ReceiveUsingSequenceNumber.java @@ -30,7 +30,7 @@ public static void main(String[] args) .setSasKey("---SharedAccessSignatureKey----"); final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); - final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); final EventHubRuntimeInformation eventHubInfo = ehClient.getRuntimeInformation().get(); final String partitionId = eventHubInfo.getPartitionIds()[0]; // get first partition's id diff --git a/samples/Java/Basic/SendBatch/pom.xml b/samples/Java/Basic/SendBatch/pom.xml index 03d8e3a6b..e4df26e64 100644 --- a/samples/Java/Basic/SendBatch/pom.xml +++ b/samples/Java/Basic/SendBatch/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 2.3.0 com.google.code.gson diff --git a/samples/Java/Basic/SendBatch/src/main/java/com/microsoft/azure/eventhubs/samples/sendbatch/SendBatch.java b/samples/Java/Basic/SendBatch/src/main/java/com/microsoft/azure/eventhubs/samples/sendbatch/SendBatch.java index 899034ca5..686eb4a21 100644 --- a/samples/Java/Basic/SendBatch/src/main/java/com/microsoft/azure/eventhubs/samples/sendbatch/SendBatch.java +++ b/samples/Java/Basic/SendBatch/src/main/java/com/microsoft/azure/eventhubs/samples/sendbatch/SendBatch.java @@ -31,7 +31,7 @@ public static void main(String[] args) final Gson gson = new GsonBuilder().create(); final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); - final EventHubClient sender = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); + final EventHubClient sender = EventHubClient.createSync(connStr.toString(), executorService); try { for (int batchNumber = 0; batchNumber < 10; batchNumber++) { diff --git a/samples/Java/Basic/SimpleProxy/pom.xml b/samples/Java/Basic/SimpleProxy/pom.xml index f6b021389..baf58c6e6 100644 --- a/samples/Java/Basic/SimpleProxy/pom.xml +++ b/samples/Java/Basic/SimpleProxy/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 2.3.0 com.google.code.gson diff --git a/samples/Java/Basic/SimpleProxy/src/main/java/com.microsoft.azure.eventhubs.samples.SimpleProxy/SimpleProxy.java b/samples/Java/Basic/SimpleProxy/src/main/java/com.microsoft.azure.eventhubs.samples.SimpleProxy/SimpleProxy.java new file mode 100644 index 000000000..83b9bf864 --- /dev/null +++ b/samples/Java/Basic/SimpleProxy/src/main/java/com.microsoft.azure.eventhubs.samples.SimpleProxy/SimpleProxy.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) Microsoft. All rights reserved. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +package com.microsoft.azure.eventhubs.samples.SimpleProxy; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.microsoft.azure.eventhubs.*; + +import java.io.IOException; +import java.net.*; +import java.nio.charset.Charset; +import java.time.Instant; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + + +public class SimpleProxy { + + public static void main(String[] args) + throws EventHubException, ExecutionException, InterruptedException, IOException { + + String proxyIpAddressStr = "---proxyhostname---"; + int proxyPort = 3128; + + //set the ProxySelector API; which offers the flexibility to select Proxy Server based on the Target URI. + ProxySelector systemDefaultSelector = ProxySelector.getDefault(); + ProxySelector.setDefault(new ProxySelector() { + @Override + public List select(URI uri) { + if (uri != null + && uri.getHost() != null + && uri.getHost().equalsIgnoreCase("youreventbushost.servicebus.windows.net")) { + LinkedList proxies = new LinkedList<>(); + proxies.add(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIpAddressStr, proxyPort))); + return proxies; + } + + // preserve system default selector for the rest + return systemDefaultSelector.select(uri); + } + @Override + public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { + // trace and follow up on why proxy server is down + if (uri == null || sa == null || ioe == null) { + throw new IllegalArgumentException("Arguments can't be null."); + } + + systemDefaultSelector.connectFailed(uri, sa, ioe); + + } + }); + + // if the proxy being used, doesn't need any Authentication - "setting Authenticator" step may be omitted + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + if (this.getRequestorType() == RequestorType.PROXY + && this.getRequestingScheme().equalsIgnoreCase("basic") + && this.getRequestingHost().equals(proxyIpAddressStr) + && this.getRequestingPort() == proxyPort) { + return new PasswordAuthentication("userName", "password".toCharArray()); + } + + return super.getPasswordAuthentication(); + } + }); + + final ConnectionStringBuilder connStr = new ConnectionStringBuilder() + .setNamespaceName("----NamespaceName-----") // to target National clouds - use .setEndpoint(URI) + .setEventHubName("----EventHubName-----") + .setSasKeyName("-----SharedAccessSignatureKeyName-----") + .setSasKey("---SharedAccessSignatureKey---"); + + connStr.setTransportType(TransportType.AMQP_WEB_SOCKETS); + + final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); + final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); + final Gson gson = new GsonBuilder().create(); + PartitionSender sender = null; + + //sending events + try { + + String payload = "Message " + Integer.toString(1); + byte[] payloadBytes = gson.toJson(payload).getBytes(Charset.defaultCharset()); + EventData sendEvent = EventData.create(payloadBytes); + + sender = ehClient.createPartitionSenderSync("1"); + sender.sendSync(sendEvent); + + System.out.println(Instant.now() + ": Send Complete..."); + + } + finally { + + } + + final EventHubRuntimeInformation eventHubInfo = ehClient.getRuntimeInformation().get(); + final String partitionId = eventHubInfo.getPartitionIds()[1]; // get first partition's id + + final PartitionReceiver receiver = ehClient.createEpochReceiverSync( + EventHubClient.DEFAULT_CONSUMER_GROUP_NAME, + partitionId, + EventPosition.fromEnqueuedTime(Instant.EPOCH), + 2345); + + try { + Iterable receivedEvents = receiver.receiveSync(10); + + if (receivedEvents != null) { + for (final EventData receivedEvent : receivedEvents) { + if (receivedEvent.getBytes() != null) + System.out.println(String.format("Message Payload: %s", new String(receivedEvent.getBytes(), Charset.defaultCharset()))); + } + } + + } finally { + // cleaning up receivers is paramount; + // Quota limitation on maximum number of concurrent receivers per consumergroup per partition is 5 + receiver.close() + .thenComposeAsync(aVoid -> ehClient.close(), executorService) + .whenCompleteAsync((t, u) -> { + if (u != null) { + // wire-up this error to diagnostics infrastructure + System.out.println(String.format("closing failed with error: %s", u.toString())); + } + }, executorService).get(); + + executorService.shutdown(); + } + } +} diff --git a/samples/Java/Basic/SimpleSend/pom.xml b/samples/Java/Basic/SimpleSend/pom.xml index 6045b76f8..3bdffea7a 100644 --- a/samples/Java/Basic/SimpleSend/pom.xml +++ b/samples/Java/Basic/SimpleSend/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 2.3.0 com.google.code.gson diff --git a/samples/Java/Basic/SimpleSend/src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java b/samples/Java/Basic/SimpleSend/src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java index 57908cd94..c4cccbb78 100644 --- a/samples/Java/Basic/SimpleSend/src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java +++ b/samples/Java/Basic/SimpleSend/src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java @@ -40,7 +40,7 @@ public static void main(String[] args) // Each EventHubClient instance spins up a new TCP/SSL connection, which is expensive. // It is always a best practice to reuse these instances. The following sample shows this. - final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); try { for (int i = 0; i < 100; i++) { diff --git a/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml b/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml index cf856c454..7c70ccad6 100644 --- a/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml +++ b/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 2.3.0 diff --git a/samples/Java/Benchmarks/AutoScaleOnIngress/src/main/java/com/microsoft/azure/eventhubs/samples/autoscaleoningress/EventHubClientPool.java b/samples/Java/Benchmarks/AutoScaleOnIngress/src/main/java/com/microsoft/azure/eventhubs/samples/autoscaleoningress/EventHubClientPool.java index 702123e13..e78718105 100644 --- a/samples/Java/Benchmarks/AutoScaleOnIngress/src/main/java/com/microsoft/azure/eventhubs/samples/autoscaleoningress/EventHubClientPool.java +++ b/samples/Java/Benchmarks/AutoScaleOnIngress/src/main/java/com/microsoft/azure/eventhubs/samples/autoscaleoningress/EventHubClientPool.java @@ -34,7 +34,7 @@ public CompletableFuture initialize() throws IOException, EventHubExceptio final CompletableFuture[] createSenders = new CompletableFuture[this.poolSize]; for (int count = 0; count < poolSize; count++) { final int clientsIndex = count; - createSenders[count] = EventHubClient.createFromConnectionString(this.connectionString, executorService).thenAccept(new Consumer() { + createSenders[count] = EventHubClient.create(this.connectionString, executorService).thenAccept(new Consumer() { @Override public void accept(EventHubClient eventHubClient) { clients[clientsIndex] = eventHubClient; diff --git a/samples/Java/Benchmarks/IngressBenchmark/pom.xml b/samples/Java/Benchmarks/IngressBenchmark/pom.xml index 07456532b..3d4d04917 100644 --- a/samples/Java/Benchmarks/IngressBenchmark/pom.xml +++ b/samples/Java/Benchmarks/IngressBenchmark/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 2.3.0 diff --git a/samples/Java/Benchmarks/IngressBenchmark/src/main/java/com/microsoft/azure/eventhubs/samples/ingressbenchmark/EventHubClientPool.java b/samples/Java/Benchmarks/IngressBenchmark/src/main/java/com/microsoft/azure/eventhubs/samples/ingressbenchmark/EventHubClientPool.java index 8ec98807a..b8a2dc128 100644 --- a/samples/Java/Benchmarks/IngressBenchmark/src/main/java/com/microsoft/azure/eventhubs/samples/ingressbenchmark/EventHubClientPool.java +++ b/samples/Java/Benchmarks/IngressBenchmark/src/main/java/com/microsoft/azure/eventhubs/samples/ingressbenchmark/EventHubClientPool.java @@ -34,7 +34,7 @@ public CompletableFuture initialize() throws IOException, EventHubExceptio final CompletableFuture[] createSenders = new CompletableFuture[this.poolSize]; for (int count = 0; count < poolSize; count++) { final int clientsIndex = count; - createSenders[count] = EventHubClient.createFromConnectionString(this.connectionString, executorService).thenAccept(new Consumer() { + createSenders[count] = EventHubClient.create(this.connectionString, executorService).thenAccept(new Consumer() { @Override public void accept(EventHubClient eventHubClient) { clients[clientsIndex] = eventHubClient; From ff85c7c3877d9565d6ce7051bae5fb7a75b43098 Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Mon, 22 Jul 2019 13:24:10 -0700 Subject: [PATCH 17/66] Move EH SDK to 4.0.0 --- .../DotNet/Rbac/AzureEventHubsSDK/Program.cs | 11 +++---- .../RbacWithAzureEventHubsSdk.csproj | 33 ++++++++++--------- .../Rbac/AzureEventHubsSDK/packages.config | 2 +- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/samples/DotNet/Rbac/AzureEventHubsSDK/Program.cs b/samples/DotNet/Rbac/AzureEventHubsSDK/Program.cs index 25f46903c..308113412 100644 --- a/samples/DotNet/Rbac/AzureEventHubsSDK/Program.cs +++ b/samples/DotNet/Rbac/AzureEventHubsSDK/Program.cs @@ -93,7 +93,8 @@ static async Task ClientAssertionCertScenarioAsync() var authResult = await app.AcquireTokenForClient(new string[] { $"{audience}/.default" }).ExecuteAsync(); return authResult.AccessToken; - }); + }, + $"https://login.microsoftonline.com/{TenantId}"); var ehClient = EventHubClient.CreateWithTokenProvider(new Uri($"sb://{EventHubNamespace}/"), EventHubName, tp); await SendReceiveAsync(ehClient); @@ -111,17 +112,13 @@ static async Task ClientCredentialsScenarioAsync() var authResult = await app.AcquireTokenForClient(new string[] { $"{audience}/.default" }).ExecuteAsync(); return authResult.AccessToken; - }); + }, + $"https://login.microsoftonline.com/{TenantId}"); var ehClient = EventHubClient.CreateWithTokenProvider(new Uri($"sb://{EventHubNamespace}/"), EventHubName, tp); await SendReceiveAsync(ehClient); } - static Task ControlPlaneAndDataPlaneMixedScenarioAsync() - { - return Task.FromResult(0); - } - static X509Certificate2 GetCertificate() { List locations = new List diff --git a/samples/DotNet/Rbac/AzureEventHubsSDK/RbacWithAzureEventHubsSdk.csproj b/samples/DotNet/Rbac/AzureEventHubsSDK/RbacWithAzureEventHubsSdk.csproj index e3e283cd6..847992f99 100644 --- a/samples/DotNet/Rbac/AzureEventHubsSDK/RbacWithAzureEventHubsSdk.csproj +++ b/samples/DotNet/Rbac/AzureEventHubsSDK/RbacWithAzureEventHubsSdk.csproj @@ -40,34 +40,34 @@ packages\Microsoft.Azure.Amqp.2.4.2\lib\net45\Microsoft.Azure.Amqp.dll - - packages\Microsoft.Azure.EventHubs.3.0.0-dev.20190618.1\lib\net461\Microsoft.Azure.EventHubs.dll + + packages\Microsoft.Azure.EventHubs.4.0.0\lib\net461\Microsoft.Azure.EventHubs.dll - ..\..\..\..\..\..\CxCache\Microsoft.Azure.Services.AppAuthentication.1.2.0\lib\net461\Microsoft.Azure.Services.AppAuthentication.dll + packages\Microsoft.Azure.Services.AppAuthentication.1.2.0\lib\net461\Microsoft.Azure.Services.AppAuthentication.dll True packages\Microsoft.Identity.Client.4.0.0\lib\net45\Microsoft.Identity.Client.dll - ..\..\..\..\..\..\CxCache\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll + packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll True - ..\..\..\..\..\..\CxCache\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll + packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll True - ..\..\..\..\..\..\CxCache\Microsoft.IdentityModel.JsonWebTokens.5.5.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll + packages\Microsoft.IdentityModel.JsonWebTokens.5.5.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll True - ..\..\..\..\..\..\CxCache\Microsoft.IdentityModel.Logging.5.5.0\lib\net461\Microsoft.IdentityModel.Logging.dll + packages\Microsoft.IdentityModel.Logging.5.5.0\lib\net461\Microsoft.IdentityModel.Logging.dll True - ..\..\..\..\..\..\CxCache\Microsoft.IdentityModel.Tokens.5.5.0\lib\net461\Microsoft.IdentityModel.Tokens.dll + packages\Microsoft.IdentityModel.Tokens.5.5.0\lib\net461\Microsoft.IdentityModel.Tokens.dll True @@ -85,18 +85,18 @@ - ..\..\..\..\..\..\CxCache\System.IdentityModel.Tokens.Jwt.5.5.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll + packages\System.IdentityModel.Tokens.Jwt.5.5.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll True packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll - ..\..\..\..\..\..\CxCache\System.Net.WebSockets.4.3.0\lib\net46\System.Net.WebSockets.dll + packages\System.Net.WebSockets.4.3.0\lib\net46\System.Net.WebSockets.dll True - ..\..\..\..\..\..\CxCache\System.Net.WebSockets.Client.4.3.2\lib\net46\System.Net.WebSockets.Client.dll + packages\System.Net.WebSockets.Client.4.3.2\lib\net46\System.Net.WebSockets.Client.dll True @@ -104,11 +104,11 @@ - ..\..\..\..\..\..\CxCache\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll + packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True - ..\..\..\..\..\..\CxCache\System.Security.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll + packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll True @@ -118,7 +118,7 @@ packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll - ..\..\..\..\..\..\CxCache\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll + packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll True @@ -136,14 +136,15 @@ Designer - + + Designer + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - - - - - - - - - - - - - From 5cb25d3891126a449982753a7a2ddcb22dd0b5b4 Mon Sep 17 00:00:00 2001 From: Serkant Karaca Date: Thu, 25 Jul 2019 13:55:07 -0700 Subject: [PATCH 23/66] Moving SFProcessor sample into SDK folder --- .../ServiceFabricProcessor/ProgrammersGuide.md | 0 .../ServiceFabricProcessor/Readme.md | 0 .../ServiceFabricProcessor/SFProcessorSample.sln | 0 .../ApplicationPackageRoot/ApplicationManifest.xml | 0 .../SFProcessorSample/ApplicationParameters/Cloud.xml | 0 .../SFProcessorSample/ApplicationParameters/Local.1Node.xml | 0 .../SFProcessorSample/ApplicationParameters/Local.5Node.xml | 0 .../SFProcessorSample/PublishProfiles/Cloud.xml | 0 .../SFProcessorSample/PublishProfiles/Local.1Node.xml | 0 .../SFProcessorSample/PublishProfiles/Local.5Node.xml | 0 .../SFProcessorSample/SFProcessorSample.sfproj | 0 .../SFProcessorSample/Scripts/Deploy-FabricApplication.ps1 | 0 .../ServiceFabricProcessor/SFProcessorSample/packages.config | 0 .../Stateful1/PackageRoot/Config/Settings.xml | 0 .../Stateful1/PackageRoot/ServiceManifest.xml | 0 .../ServiceFabricProcessor/Stateful1/Program.cs | 0 .../ServiceFabricProcessor/Stateful1/SampleEventProcessor.cs | 0 .../ServiceFabricProcessor/Stateful1/ServiceEventSource.cs | 0 .../ServiceFabricProcessor/Stateful1/Stateful1.cs | 0 .../ServiceFabricProcessor/Stateful1/Stateful1.csproj | 0 .../{ => RBAC}/EventHubsSenderReceiverRbac/App.config | 0 .../EventHubsSenderReceiverRbac.csproj | 0 .../EventHubsSenderReceiverRbac/EventHubsSenderReceiverRbac.sln | 0 .../{ => RBAC}/EventHubsSenderReceiverRbac/Program.cs | 0 .../EventHubsSenderReceiverRbac/Properties/AssemblyInfo.cs | 0 .../{ => RBAC}/EventHubsSenderReceiverRbac/README.md | 0 .../{ => RBAC}/EventHubsSenderReceiverRbac/packages.config | 0 27 files changed, 0 insertions(+), 0 deletions(-) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/ProgrammersGuide.md (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/Readme.md (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/SFProcessorSample.sln (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/SFProcessorSample/ApplicationPackageRoot/ApplicationManifest.xml (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Cloud.xml (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Local.1Node.xml (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Local.5Node.xml (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Cloud.xml (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Local.1Node.xml (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Local.5Node.xml (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/SFProcessorSample/SFProcessorSample.sfproj (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/SFProcessorSample/Scripts/Deploy-FabricApplication.ps1 (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/SFProcessorSample/packages.config (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/Stateful1/PackageRoot/Config/Settings.xml (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/Stateful1/PackageRoot/ServiceManifest.xml (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/Stateful1/Program.cs (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/Stateful1/SampleEventProcessor.cs (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/Stateful1/ServiceEventSource.cs (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/Stateful1/Stateful1.cs (100%) rename samples/DotNet/{ => Microsoft.Azure.EventHubs}/ServiceFabricProcessor/Stateful1/Stateful1.csproj (100%) rename samples/DotNet/Microsoft.ServiceBus/{ => RBAC}/EventHubsSenderReceiverRbac/App.config (100%) rename samples/DotNet/Microsoft.ServiceBus/{ => RBAC}/EventHubsSenderReceiverRbac/EventHubsSenderReceiverRbac.csproj (100%) rename samples/DotNet/Microsoft.ServiceBus/{ => RBAC}/EventHubsSenderReceiverRbac/EventHubsSenderReceiverRbac.sln (100%) rename samples/DotNet/Microsoft.ServiceBus/{ => RBAC}/EventHubsSenderReceiverRbac/Program.cs (100%) rename samples/DotNet/Microsoft.ServiceBus/{ => RBAC}/EventHubsSenderReceiverRbac/Properties/AssemblyInfo.cs (100%) rename samples/DotNet/Microsoft.ServiceBus/{ => RBAC}/EventHubsSenderReceiverRbac/README.md (100%) rename samples/DotNet/Microsoft.ServiceBus/{ => RBAC}/EventHubsSenderReceiverRbac/packages.config (100%) diff --git a/samples/DotNet/ServiceFabricProcessor/ProgrammersGuide.md b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/ProgrammersGuide.md similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/ProgrammersGuide.md rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/ProgrammersGuide.md diff --git a/samples/DotNet/ServiceFabricProcessor/Readme.md b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Readme.md similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/Readme.md rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Readme.md diff --git a/samples/DotNet/ServiceFabricProcessor/SFProcessorSample.sln b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample.sln similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/SFProcessorSample.sln rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample.sln diff --git a/samples/DotNet/ServiceFabricProcessor/SFProcessorSample/ApplicationPackageRoot/ApplicationManifest.xml b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/ApplicationPackageRoot/ApplicationManifest.xml similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/SFProcessorSample/ApplicationPackageRoot/ApplicationManifest.xml rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/ApplicationPackageRoot/ApplicationManifest.xml diff --git a/samples/DotNet/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Cloud.xml b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Cloud.xml similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Cloud.xml rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Cloud.xml diff --git a/samples/DotNet/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Local.1Node.xml b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Local.1Node.xml similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Local.1Node.xml rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Local.1Node.xml diff --git a/samples/DotNet/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Local.5Node.xml b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Local.5Node.xml similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Local.5Node.xml rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/ApplicationParameters/Local.5Node.xml diff --git a/samples/DotNet/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Cloud.xml b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Cloud.xml similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Cloud.xml rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Cloud.xml diff --git a/samples/DotNet/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Local.1Node.xml b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Local.1Node.xml similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Local.1Node.xml rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Local.1Node.xml diff --git a/samples/DotNet/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Local.5Node.xml b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Local.5Node.xml similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Local.5Node.xml rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/PublishProfiles/Local.5Node.xml diff --git a/samples/DotNet/ServiceFabricProcessor/SFProcessorSample/SFProcessorSample.sfproj b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/SFProcessorSample.sfproj similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/SFProcessorSample/SFProcessorSample.sfproj rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/SFProcessorSample.sfproj diff --git a/samples/DotNet/ServiceFabricProcessor/SFProcessorSample/Scripts/Deploy-FabricApplication.ps1 b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/Scripts/Deploy-FabricApplication.ps1 similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/SFProcessorSample/Scripts/Deploy-FabricApplication.ps1 rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/Scripts/Deploy-FabricApplication.ps1 diff --git a/samples/DotNet/ServiceFabricProcessor/SFProcessorSample/packages.config b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/packages.config similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/SFProcessorSample/packages.config rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/SFProcessorSample/packages.config diff --git a/samples/DotNet/ServiceFabricProcessor/Stateful1/PackageRoot/Config/Settings.xml b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/PackageRoot/Config/Settings.xml similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/Stateful1/PackageRoot/Config/Settings.xml rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/PackageRoot/Config/Settings.xml diff --git a/samples/DotNet/ServiceFabricProcessor/Stateful1/PackageRoot/ServiceManifest.xml b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/PackageRoot/ServiceManifest.xml similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/Stateful1/PackageRoot/ServiceManifest.xml rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/PackageRoot/ServiceManifest.xml diff --git a/samples/DotNet/ServiceFabricProcessor/Stateful1/Program.cs b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/Program.cs similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/Stateful1/Program.cs rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/Program.cs diff --git a/samples/DotNet/ServiceFabricProcessor/Stateful1/SampleEventProcessor.cs b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/SampleEventProcessor.cs similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/Stateful1/SampleEventProcessor.cs rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/SampleEventProcessor.cs diff --git a/samples/DotNet/ServiceFabricProcessor/Stateful1/ServiceEventSource.cs b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/ServiceEventSource.cs similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/Stateful1/ServiceEventSource.cs rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/ServiceEventSource.cs diff --git a/samples/DotNet/ServiceFabricProcessor/Stateful1/Stateful1.cs b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/Stateful1.cs similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/Stateful1/Stateful1.cs rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/Stateful1.cs diff --git a/samples/DotNet/ServiceFabricProcessor/Stateful1/Stateful1.csproj b/samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/Stateful1.csproj similarity index 100% rename from samples/DotNet/ServiceFabricProcessor/Stateful1/Stateful1.csproj rename to samples/DotNet/Microsoft.Azure.EventHubs/ServiceFabricProcessor/Stateful1/Stateful1.csproj diff --git a/samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/App.config b/samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/App.config similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/App.config rename to samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/App.config diff --git a/samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/EventHubsSenderReceiverRbac.csproj b/samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/EventHubsSenderReceiverRbac.csproj similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/EventHubsSenderReceiverRbac.csproj rename to samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/EventHubsSenderReceiverRbac.csproj diff --git a/samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/EventHubsSenderReceiverRbac.sln b/samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/EventHubsSenderReceiverRbac.sln similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/EventHubsSenderReceiverRbac.sln rename to samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/EventHubsSenderReceiverRbac.sln diff --git a/samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/Program.cs b/samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/Program.cs similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/Program.cs rename to samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/Program.cs diff --git a/samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/Properties/AssemblyInfo.cs b/samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/Properties/AssemblyInfo.cs similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/Properties/AssemblyInfo.cs rename to samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/Properties/AssemblyInfo.cs diff --git a/samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/README.md b/samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/README.md similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/README.md rename to samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/README.md diff --git a/samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/packages.config b/samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/packages.config similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/EventHubsSenderReceiverRbac/packages.config rename to samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/packages.config From d096ca248b52fe719ed4d2bb006fba78fb52840a Mon Sep 17 00:00:00 2001 From: JamesBirdsall Date: Wed, 28 Aug 2019 17:05:03 -0700 Subject: [PATCH 24/66] Update Java samples for 3.0.0 client (#455) * Update client version in poms to 3.0.0 * Remove unwanted files * Update API names --- .../Java/Basic/AdvancedSendOptions/pom.xml | 14 ++++---- .../AdvancedSendOptions.java | 2 +- .../Basic/EventProcessorSample/.classpath | 28 ---------------- .../Java/Basic/EventProcessorSample/.project | 23 ------------- .../Java/Basic/EventProcessorSample/pom.xml | 32 +++++++++---------- .../EventProcessorSample.java | 12 +++---- samples/Java/Basic/ReceiveByDateTime/pom.xml | 12 +++---- .../receivebydatetime/ReceiveByDateTime.java | 2 +- samples/Java/Basic/ReceiveUsingOffset/pom.xml | 12 +++---- .../ReceiveUsingOffset.java | 2 +- .../Basic/ReceiveUsingSequenceNumber/pom.xml | 12 +++---- .../ReceiveUsingSequenceNumber.java | 2 +- samples/Java/Basic/SendBatch/pom.xml | 14 ++++---- .../samples/sendbatch/SendBatch.java | 2 +- samples/Java/Basic/SimpleProxy/pom.xml | 10 +++--- .../SimpleProxy.java | 2 +- samples/Java/Basic/SimpleSend/pom.xml | 14 ++++---- .../samples/SimpleSend/SimpleSend.java | 2 +- .../Benchmarks/AutoScaleOnIngress/pom.xml | 12 +++---- .../EventHubClientPool.java | 2 +- .../Java/Benchmarks/IngressBenchmark/pom.xml | 12 +++---- .../ingressbenchmark/EventHubClientPool.java | 2 +- 22 files changed, 86 insertions(+), 139 deletions(-) delete mode 100644 samples/Java/Basic/EventProcessorSample/.classpath delete mode 100644 samples/Java/Basic/EventProcessorSample/.project diff --git a/samples/Java/Basic/AdvancedSendOptions/pom.xml b/samples/Java/Basic/AdvancedSendOptions/pom.xml index b0bde814f..24259349a 100644 --- a/samples/Java/Basic/AdvancedSendOptions/pom.xml +++ b/samples/Java/Basic/AdvancedSendOptions/pom.xml @@ -43,16 +43,16 @@ - + - com.microsoft.azure - azure-eventhubs - 2.3.0 - - + com.microsoft.azure + azure-eventhubs + 3.0.0 + + com.google.code.gson gson 2.8.2 - + diff --git a/samples/Java/Basic/AdvancedSendOptions/src/main/java/com/microsoft/azure/eventhubs/samples/AdvancedSendOptions/AdvancedSendOptions.java b/samples/Java/Basic/AdvancedSendOptions/src/main/java/com/microsoft/azure/eventhubs/samples/AdvancedSendOptions/AdvancedSendOptions.java index 4d5fedc7b..b7e6a77a7 100644 --- a/samples/Java/Basic/AdvancedSendOptions/src/main/java/com/microsoft/azure/eventhubs/samples/AdvancedSendOptions/AdvancedSendOptions.java +++ b/samples/Java/Basic/AdvancedSendOptions/src/main/java/com/microsoft/azure/eventhubs/samples/AdvancedSendOptions/AdvancedSendOptions.java @@ -46,7 +46,7 @@ public static void main(String[] args) // Each EventHubClient instance spins up a new TCP/SSL connection, which is expensive. // It is always a best practice to reuse these instances. The following sample shows the same. - final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); PartitionSender sender = null; try { diff --git a/samples/Java/Basic/EventProcessorSample/.classpath b/samples/Java/Basic/EventProcessorSample/.classpath deleted file mode 100644 index db2a016f9..000000000 --- a/samples/Java/Basic/EventProcessorSample/.classpath +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/Java/Basic/EventProcessorSample/.project b/samples/Java/Basic/EventProcessorSample/.project deleted file mode 100644 index 03043695d..000000000 --- a/samples/Java/Basic/EventProcessorSample/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - EventProcessorSample - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/samples/Java/Basic/EventProcessorSample/pom.xml b/samples/Java/Basic/EventProcessorSample/pom.xml index 7f8149c0d..509907670 100644 --- a/samples/Java/Basic/EventProcessorSample/pom.xml +++ b/samples/Java/Basic/EventProcessorSample/pom.xml @@ -43,26 +43,26 @@ - + - com.microsoft.azure - azure-eventhubs - 2.3.0 - - - com.microsoft.azure - azure-eventhubs-eph - 2.5.0 - - - log4j - log4j - 1.2.17 - + com.microsoft.azure + azure-eventhubs + 3.0.0 + + + com.microsoft.azure + azure-eventhubs-eph + 3.0.0 + + + log4j + log4j + 1.2.17 + org.slf4j slf4j-log4j12 1.7.25 - + diff --git a/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java b/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java index d46b88eb8..870feb2d0 100644 --- a/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java +++ b/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java @@ -46,13 +46,11 @@ public static void main(String args[]) throws InterruptedException, ExecutionExc // Create the instance of EventProcessorHost using the most basic constructor. This constructor uses Azure Storage for // persisting partition leases and checkpoints. The host name, which identifies the instance of EventProcessorHost, must be unique. // You can use a plain UUID, or use the createHostName utility method which appends a UUID to a supplied string. - EventProcessorHost host = new EventProcessorHost( - EventProcessorHost.createHostName(hostNamePrefix), - eventHubName, - consumerGroupName, - eventHubConnectionString.toString(), - storageConnectionString, - storageContainerName); + EventProcessorHost host = EventProcessorHost.EventProcessorHostBuilder + .newBuilder(EventProcessorHost.createHostName(hostNamePrefix), consumerGroupName) + .useAzureStorageCheckpointLeaseManager(storageConnectionString, storageContainerName, null) + .useEventHubConnectionString(eventHubConnectionString.toString(), eventHubName) + .build(); // Registering an event processor class with an instance of EventProcessorHost starts event processing. The host instance // obtains leases on some partitions of the Event Hub, possibly stealing some from other host instances, in a way that diff --git a/samples/Java/Basic/ReceiveByDateTime/pom.xml b/samples/Java/Basic/ReceiveByDateTime/pom.xml index 3108cd866..f01af98df 100644 --- a/samples/Java/Basic/ReceiveByDateTime/pom.xml +++ b/samples/Java/Basic/ReceiveByDateTime/pom.xml @@ -43,11 +43,11 @@ - + - com.microsoft.azure - azure-eventhubs - 2.3.0 - - + com.microsoft.azure + azure-eventhubs + 3.0.0 + + diff --git a/samples/Java/Basic/ReceiveByDateTime/src/main/java/com/microsoft/azure/eventhubs/samples/receivebydatetime/ReceiveByDateTime.java b/samples/Java/Basic/ReceiveByDateTime/src/main/java/com/microsoft/azure/eventhubs/samples/receivebydatetime/ReceiveByDateTime.java index bb73e1af2..57f72ce6b 100644 --- a/samples/Java/Basic/ReceiveByDateTime/src/main/java/com/microsoft/azure/eventhubs/samples/receivebydatetime/ReceiveByDateTime.java +++ b/samples/Java/Basic/ReceiveByDateTime/src/main/java/com/microsoft/azure/eventhubs/samples/receivebydatetime/ReceiveByDateTime.java @@ -31,7 +31,7 @@ public static void main(String[] args) .setSasKey("---SharedAccessSignatureKey----"); final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); - final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); final EventHubRuntimeInformation eventHubInfo = ehClient.getRuntimeInformation().get(); final String partitionId = eventHubInfo.getPartitionIds()[0]; // get first partition's id diff --git a/samples/Java/Basic/ReceiveUsingOffset/pom.xml b/samples/Java/Basic/ReceiveUsingOffset/pom.xml index 806d116b4..727de2acd 100644 --- a/samples/Java/Basic/ReceiveUsingOffset/pom.xml +++ b/samples/Java/Basic/ReceiveUsingOffset/pom.xml @@ -43,11 +43,11 @@ - + - com.microsoft.azure - azure-eventhubs - 2.3.0 - - + com.microsoft.azure + azure-eventhubs + 3.0.0 + + diff --git a/samples/Java/Basic/ReceiveUsingOffset/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingoffset/ReceiveUsingOffset.java b/samples/Java/Basic/ReceiveUsingOffset/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingoffset/ReceiveUsingOffset.java index 9890dc64f..83335768d 100644 --- a/samples/Java/Basic/ReceiveUsingOffset/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingoffset/ReceiveUsingOffset.java +++ b/samples/Java/Basic/ReceiveUsingOffset/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingoffset/ReceiveUsingOffset.java @@ -29,7 +29,7 @@ public static void main(String[] args) .setSasKey("---SharedAccessSignatureKey----"); final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); - final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); final EventHubRuntimeInformation eventHubInfo = ehClient.getRuntimeInformation().get(); final String partitionId = eventHubInfo.getPartitionIds()[0]; // get first partition's id diff --git a/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml b/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml index 82e583349..c0fc9b4b7 100644 --- a/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml +++ b/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml @@ -43,11 +43,11 @@ - + - com.microsoft.azure - azure-eventhubs - 2.3.0 - - + com.microsoft.azure + azure-eventhubs + 3.0.0 + + diff --git a/samples/Java/Basic/ReceiveUsingSequenceNumber/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingsequencenumber/ReceiveUsingSequenceNumber.java b/samples/Java/Basic/ReceiveUsingSequenceNumber/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingsequencenumber/ReceiveUsingSequenceNumber.java index 8027db35a..77de83a5c 100644 --- a/samples/Java/Basic/ReceiveUsingSequenceNumber/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingsequencenumber/ReceiveUsingSequenceNumber.java +++ b/samples/Java/Basic/ReceiveUsingSequenceNumber/src/main/java/com/microsoft/azure/eventhubs/samples/receiveusingsequencenumber/ReceiveUsingSequenceNumber.java @@ -30,7 +30,7 @@ public static void main(String[] args) .setSasKey("---SharedAccessSignatureKey----"); final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); - final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); final EventHubRuntimeInformation eventHubInfo = ehClient.getRuntimeInformation().get(); final String partitionId = eventHubInfo.getPartitionIds()[0]; // get first partition's id diff --git a/samples/Java/Basic/SendBatch/pom.xml b/samples/Java/Basic/SendBatch/pom.xml index e4df26e64..73138cadd 100644 --- a/samples/Java/Basic/SendBatch/pom.xml +++ b/samples/Java/Basic/SendBatch/pom.xml @@ -43,16 +43,16 @@ - - - com.microsoft.azure - azure-eventhubs - 2.3.0 - + + + com.microsoft.azure + azure-eventhubs + 3.0.0 + com.google.code.gson gson [2.8.2,] - + diff --git a/samples/Java/Basic/SendBatch/src/main/java/com/microsoft/azure/eventhubs/samples/sendbatch/SendBatch.java b/samples/Java/Basic/SendBatch/src/main/java/com/microsoft/azure/eventhubs/samples/sendbatch/SendBatch.java index 686eb4a21..899034ca5 100644 --- a/samples/Java/Basic/SendBatch/src/main/java/com/microsoft/azure/eventhubs/samples/sendbatch/SendBatch.java +++ b/samples/Java/Basic/SendBatch/src/main/java/com/microsoft/azure/eventhubs/samples/sendbatch/SendBatch.java @@ -31,7 +31,7 @@ public static void main(String[] args) final Gson gson = new GsonBuilder().create(); final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); - final EventHubClient sender = EventHubClient.createSync(connStr.toString(), executorService); + final EventHubClient sender = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); try { for (int batchNumber = 0; batchNumber < 10; batchNumber++) { diff --git a/samples/Java/Basic/SimpleProxy/pom.xml b/samples/Java/Basic/SimpleProxy/pom.xml index baf58c6e6..e7fd40b0f 100644 --- a/samples/Java/Basic/SimpleProxy/pom.xml +++ b/samples/Java/Basic/SimpleProxy/pom.xml @@ -44,11 +44,11 @@ - - com.microsoft.azure - azure-eventhubs - 2.3.0 - + + com.microsoft.azure + azure-eventhubs + 3.0.0 + com.google.code.gson gson diff --git a/samples/Java/Basic/SimpleProxy/src/main/java/com.microsoft.azure.eventhubs.samples.SimpleProxy/SimpleProxy.java b/samples/Java/Basic/SimpleProxy/src/main/java/com.microsoft.azure.eventhubs.samples.SimpleProxy/SimpleProxy.java index 83b9bf864..7326604dd 100644 --- a/samples/Java/Basic/SimpleProxy/src/main/java/com.microsoft.azure.eventhubs.samples.SimpleProxy/SimpleProxy.java +++ b/samples/Java/Basic/SimpleProxy/src/main/java/com.microsoft.azure.eventhubs.samples.SimpleProxy/SimpleProxy.java @@ -79,7 +79,7 @@ protected PasswordAuthentication getPasswordAuthentication() { connStr.setTransportType(TransportType.AMQP_WEB_SOCKETS); final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); - final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); final Gson gson = new GsonBuilder().create(); PartitionSender sender = null; diff --git a/samples/Java/Basic/SimpleSend/pom.xml b/samples/Java/Basic/SimpleSend/pom.xml index 3bdffea7a..a826774a3 100644 --- a/samples/Java/Basic/SimpleSend/pom.xml +++ b/samples/Java/Basic/SimpleSend/pom.xml @@ -43,16 +43,16 @@ - + - com.microsoft.azure - azure-eventhubs - 2.3.0 - - + com.microsoft.azure + azure-eventhubs + 3.0.0 + + com.google.code.gson gson 2.8.5 - + diff --git a/samples/Java/Basic/SimpleSend/src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java b/samples/Java/Basic/SimpleSend/src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java index c4cccbb78..57908cd94 100644 --- a/samples/Java/Basic/SimpleSend/src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java +++ b/samples/Java/Basic/SimpleSend/src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java @@ -40,7 +40,7 @@ public static void main(String[] args) // Each EventHubClient instance spins up a new TCP/SSL connection, which is expensive. // It is always a best practice to reuse these instances. The following sample shows this. - final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService); + final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); try { for (int i = 0; i < 100; i++) { diff --git a/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml b/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml index 7c70ccad6..9eaa993f8 100644 --- a/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml +++ b/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml @@ -43,11 +43,11 @@ - + - com.microsoft.azure - azure-eventhubs - 2.3.0 - - + com.microsoft.azure + azure-eventhubs + 3.0.0 + + diff --git a/samples/Java/Benchmarks/AutoScaleOnIngress/src/main/java/com/microsoft/azure/eventhubs/samples/autoscaleoningress/EventHubClientPool.java b/samples/Java/Benchmarks/AutoScaleOnIngress/src/main/java/com/microsoft/azure/eventhubs/samples/autoscaleoningress/EventHubClientPool.java index e78718105..702123e13 100644 --- a/samples/Java/Benchmarks/AutoScaleOnIngress/src/main/java/com/microsoft/azure/eventhubs/samples/autoscaleoningress/EventHubClientPool.java +++ b/samples/Java/Benchmarks/AutoScaleOnIngress/src/main/java/com/microsoft/azure/eventhubs/samples/autoscaleoningress/EventHubClientPool.java @@ -34,7 +34,7 @@ public CompletableFuture initialize() throws IOException, EventHubExceptio final CompletableFuture[] createSenders = new CompletableFuture[this.poolSize]; for (int count = 0; count < poolSize; count++) { final int clientsIndex = count; - createSenders[count] = EventHubClient.create(this.connectionString, executorService).thenAccept(new Consumer() { + createSenders[count] = EventHubClient.createFromConnectionString(this.connectionString, executorService).thenAccept(new Consumer() { @Override public void accept(EventHubClient eventHubClient) { clients[clientsIndex] = eventHubClient; diff --git a/samples/Java/Benchmarks/IngressBenchmark/pom.xml b/samples/Java/Benchmarks/IngressBenchmark/pom.xml index 3d4d04917..9c0462d2a 100644 --- a/samples/Java/Benchmarks/IngressBenchmark/pom.xml +++ b/samples/Java/Benchmarks/IngressBenchmark/pom.xml @@ -43,11 +43,11 @@ - + - com.microsoft.azure - azure-eventhubs - 2.3.0 - - + com.microsoft.azure + azure-eventhubs + 3.0.0 + + diff --git a/samples/Java/Benchmarks/IngressBenchmark/src/main/java/com/microsoft/azure/eventhubs/samples/ingressbenchmark/EventHubClientPool.java b/samples/Java/Benchmarks/IngressBenchmark/src/main/java/com/microsoft/azure/eventhubs/samples/ingressbenchmark/EventHubClientPool.java index b8a2dc128..8ec98807a 100644 --- a/samples/Java/Benchmarks/IngressBenchmark/src/main/java/com/microsoft/azure/eventhubs/samples/ingressbenchmark/EventHubClientPool.java +++ b/samples/Java/Benchmarks/IngressBenchmark/src/main/java/com/microsoft/azure/eventhubs/samples/ingressbenchmark/EventHubClientPool.java @@ -34,7 +34,7 @@ public CompletableFuture initialize() throws IOException, EventHubExceptio final CompletableFuture[] createSenders = new CompletableFuture[this.poolSize]; for (int count = 0; count < poolSize; count++) { final int clientsIndex = count; - createSenders[count] = EventHubClient.create(this.connectionString, executorService).thenAccept(new Consumer() { + createSenders[count] = EventHubClient.createFromConnectionString(this.connectionString, executorService).thenAccept(new Consumer() { @Override public void accept(EventHubClient eventHubClient) { clients[clientsIndex] = eventHubClient; From 12b87e6038bd18667b9a064e259c7e0b2f7c5839 Mon Sep 17 00:00:00 2001 From: JamesBirdsall Date: Thu, 29 Aug 2019 16:15:54 -0700 Subject: [PATCH 25/66] Consolidate all Java RBAC sample work (#456) * Adding Java RBAC sample * Remove unwanted classpath and project files * README with RBAC and MI instructions --- samples/Java/Rbac/README.md | 42 ++++ samples/Java/Rbac/pom.xml | 63 ++++++ .../eventhubs/samples/rbac/AuthCallback.java | 39 ++++ .../samples/rbac/CustomTokenProvider.java | 53 +++++ .../eventhubs/samples/rbac/SendReceive.java | 189 ++++++++++++++++++ 5 files changed, 386 insertions(+) create mode 100644 samples/Java/Rbac/README.md create mode 100644 samples/Java/Rbac/pom.xml create mode 100644 samples/Java/Rbac/src/main/java/com/microsoft/azure/eventhubs/samples/rbac/AuthCallback.java create mode 100644 samples/Java/Rbac/src/main/java/com/microsoft/azure/eventhubs/samples/rbac/CustomTokenProvider.java create mode 100644 samples/Java/Rbac/src/main/java/com/microsoft/azure/eventhubs/samples/rbac/SendReceive.java diff --git a/samples/Java/Rbac/README.md b/samples/Java/Rbac/README.md new file mode 100644 index 000000000..7aa4c31df --- /dev/null +++ b/samples/Java/Rbac/README.md @@ -0,0 +1,42 @@ +# Role based access sample with Azure Event Hubs Java SDK + +For general information on using Role based access (RBAC) with Azure Event Hubs, see the [documentation](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-role-based-access-control). + +This sample uses the [Microsoft Authentication Library (MSAL) for Java](https://github.com/AzureAD/microsoft-authentication-library-for-java) to obtain tokens from Azure Active Directory (AAD). + +## Prerequisites + +Please refer to the Java sample overview README for setting up the sample environment, including creating an Event Hubs cloud namespace and an event hub. + +The specific AAD pattern used in this sample is ["Authenticate an appliction"](https://docs.microsoft.com/en-us/azure/event-hubs/authenticate-application). Please follow the steps described to +create an application (client) id and application (client) secret, obtain your directory (tenant) id, and assign the application the Data Owner role on your event hub. + +Once you have performed the previous steps, edit SendReceive.java to provide the necessary information. + +```java + final java.net.URI namespace = new java.net.URI("----EventHubsNamespace---.servicebus.windows.net"); // to target National clouds, change domain name too + final String eventhub = "----EventHubName----"; + final String authority = "https://login.windows.net/----replaceWithTenantIdGuid----"; + final String clientId = "----replaceWithClientIdGuid----"; // not needed to run with Managed Identity + final String clientSecret = "----replaceWithClientSecret----"; // not needed to run with Managed Identity +``` + +The Azure Event Hubs Java SDK also has limited built-in support for Managed Identity: specifically, when running in a virtual machine with a system-assigned managed identity, the SDK can +obtain and use that identity to perform role based access. This sample can demonstrate that ability when run in an +[appropriately-configured virtual machine](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/qs-configure-portal-windows-vm) and the managed identity +[has been assigned the Data Owner role on your event hub.](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-managed-service-identity) + + +## Build and run + +The sample can be built independently with + +```bash +mvn clean package +``` + +and then run with (or just from VS Code or another Java IDE) + +```bash +java -jar ./target/send-1.0.0-jar-with-dependencies.jar +``` \ No newline at end of file diff --git a/samples/Java/Rbac/pom.xml b/samples/Java/Rbac/pom.xml new file mode 100644 index 000000000..ad0b69401 --- /dev/null +++ b/samples/Java/Rbac/pom.xml @@ -0,0 +1,63 @@ + + 4.0.0 + rbac + 1.0.0 + rbac + jar + + UTF-8 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + true + lines,vars,source + + + + maven-assembly-plugin + + + package + + single + + + + + + jar-with-dependencies + + + + com.microsoft.azure.eventhubs.samples.rbac.SendReceive + + + + + + + + + com.microsoft.azure + azure-eventhubs + 3.0.0 + + + com.google.code.gson + gson + 2.8.5 + + + com.microsoft.azure + msal4j + 0.5.0-preview + + + diff --git a/samples/Java/Rbac/src/main/java/com/microsoft/azure/eventhubs/samples/rbac/AuthCallback.java b/samples/Java/Rbac/src/main/java/com/microsoft/azure/eventhubs/samples/rbac/AuthCallback.java new file mode 100644 index 000000000..943eb6421 --- /dev/null +++ b/samples/Java/Rbac/src/main/java/com/microsoft/azure/eventhubs/samples/rbac/AuthCallback.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) Microsoft. All rights reserved. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +package com.microsoft.azure.eventhubs.samples.rbac; + +import java.util.Collections; +import java.util.concurrent.CompletableFuture; + +import com.microsoft.aad.msal4j.*; +import com.microsoft.azure.eventhubs.AzureActiveDirectoryTokenProvider; + +class AuthCallback implements AzureActiveDirectoryTokenProvider.AuthenticationCallback { + final private String clientId; + final private String clientSecret; + + public AuthCallback(final String clientId, final String clientSecret) { + this.clientId = clientId; + this.clientSecret = clientSecret; + } + + @Override + public CompletableFuture acquireToken(String audience, String authority, Object state) { + try { + ConfidentialClientApplication app = ConfidentialClientApplication.builder(this.clientId, new ClientSecret(this.clientSecret)) + .authority(authority) + .build(); + ClientCredentialParameters parameters = ClientCredentialParameters.builder(Collections.singleton(audience + ".default")).build(); + return app.acquireToken(parameters).thenApply((authResult) -> { + return authResult.accessToken(); + }); + } catch (Exception e) { + CompletableFuture failed = new CompletableFuture(); + failed.completeExceptionally(e); + return failed; + } + } +} diff --git a/samples/Java/Rbac/src/main/java/com/microsoft/azure/eventhubs/samples/rbac/CustomTokenProvider.java b/samples/Java/Rbac/src/main/java/com/microsoft/azure/eventhubs/samples/rbac/CustomTokenProvider.java new file mode 100644 index 000000000..2ae948abc --- /dev/null +++ b/samples/Java/Rbac/src/main/java/com/microsoft/azure/eventhubs/samples/rbac/CustomTokenProvider.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) Microsoft. All rights reserved. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +package com.microsoft.azure.eventhubs.samples.rbac; + +import java.text.ParseException; +import java.time.Duration; +import java.util.Collections; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import com.microsoft.aad.msal4j.*; +import com.microsoft.azure.eventhubs.*; +import com.microsoft.azure.eventhubs.impl.ClientConstants; + +class CustomTokenProvider implements ITokenProvider { + final private String authority; + final private String audience = ClientConstants.EVENTHUBS_AUDIENCE; + final private String clientId; + final private String clientSecret; + + public CustomTokenProvider(final String authority, final String clientId, final String clientSecret) { + this.authority = authority; + this.clientId = clientId; + this.clientSecret = clientSecret; + } + + @Override + public CompletableFuture getToken(String resource, Duration timeout) { + try { + ConfidentialClientApplication app = ConfidentialClientApplication.builder(this.clientId, new ClientSecret(this.clientSecret)) + .authority(authority) + .build(); + ClientCredentialParameters parameters = ClientCredentialParameters.builder(Collections.singleton(audience + ".default")).build(); + return app.acquireToken(parameters) + .thenApply((authResult) -> { + try { + return new JsonSecurityToken(authResult.accessToken(), resource); + } catch (ParseException e) { + throw new CompletionException(e); + } + }); + } + catch (Exception e) { + CompletableFuture failed = new CompletableFuture(); + failed.completeExceptionally(e); + return failed; + } + } +} + diff --git a/samples/Java/Rbac/src/main/java/com/microsoft/azure/eventhubs/samples/rbac/SendReceive.java b/samples/Java/Rbac/src/main/java/com/microsoft/azure/eventhubs/samples/rbac/SendReceive.java new file mode 100644 index 000000000..1dfbc777d --- /dev/null +++ b/samples/Java/Rbac/src/main/java/com/microsoft/azure/eventhubs/samples/rbac/SendReceive.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) Microsoft. All rights reserved. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +package com.microsoft.azure.eventhubs.samples.rbac; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.microsoft.azure.eventhubs.AzureActiveDirectoryTokenProvider; +import com.microsoft.azure.eventhubs.ConnectionStringBuilder; +import com.microsoft.azure.eventhubs.EventData; +import com.microsoft.azure.eventhubs.EventHubClient; +import com.microsoft.azure.eventhubs.EventHubException; +import com.microsoft.azure.eventhubs.EventPosition; +import com.microsoft.azure.eventhubs.PartitionReceiver; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.time.Instant; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + +public class SendReceive { + + final java.net.URI namespace = new java.net.URI("----EventHubsNamespace---.servicebus.windows.net"); // to target National clouds, change domain name too + final String eventhub = "----EventHubName----"; + final String authority = "https://login.windows.net/----replaceWithTenantIdGuid----"; + final String clientId = "----replaceWithClientIdGuid----"; // not needed to run with Managed Identity + final String clientSecret = "----replaceWithClientSecret----"; // not needed to run with Managed Identity + + public SendReceive() throws URISyntaxException { + } + + public static int main(String[] args) + throws EventHubException, ExecutionException, InterruptedException, IOException, URISyntaxException { + + SendReceive ss = new SendReceive(); + return ss.run(args); + } + + private int run(String[] args) throws IOException { + + System.out.println("Choose an action:"); + System.out.println("[A] Authenticate via Managed Identity"); + System.out.println("[B] Get AAD token using AuthCallback"); + System.out.println("[C] Get AAD token using AzureActiveDirectoryTokenProvider to wrap AuthCallback"); + System.out.println("[D] Get AAD token using ITokenProvider implementation"); + + char key = (char)System.in.read(); + char keyPressed = Character.toUpperCase(key); + + try { + switch (keyPressed) { + case 'A': + managedIdentityScenario(); + break; + case 'B': + useAuthCallback(); + break; + case 'C': + useAADTokenProvider(); + break; + case 'D': + useCustomTokenProvider(); + break; + default: + System.out.println("Unknown command, press enter to exit"); + System.in.read(); + return -1; + } + } + catch (Exception ex) { + System.out.println("Error during execution. Exception: " + ex.toString()); + return -1; + } + + return 0; + } + + private ScheduledExecutorService getScheduledExecutorService() { + // The Executor handles all asynchronous tasks and this is passed to the EventHubClient instance. + // This enables the user to segregate their thread pool based on the work load. + // This pool can then be shared across multiple EventHubClient instances. + // The following sample uses a single thread executor, as there is only one EventHubClient instance, + // handling different flavors of ingestion to Event Hubs here. + final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); + return executorService; + } + + private void managedIdentityScenario() throws IOException, EventHubException { + + final ConnectionStringBuilder connStr = new ConnectionStringBuilder() + .setEndpoint(this.namespace) + .setEventHubName(this.eventhub) + .setAuthentication(ConnectionStringBuilder.MANAGED_IDENTITY_AUTHENTICATION); + ScheduledExecutorService executorService = getScheduledExecutorService(); + + final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); + + sendReceive(ehClient, executorService); + } + + private void useAuthCallback() throws IOException, InterruptedException, ExecutionException, EventHubException { + + final AuthCallback callback = new AuthCallback(clientId, clientSecret); + ScheduledExecutorService executorService = getScheduledExecutorService(); + + final EventHubClient ehClient = EventHubClient.createWithAzureActiveDirectory(namespace, eventhub, callback, authority, executorService, null).get(); + + sendReceive(ehClient, executorService); + } + + private void useAADTokenProvider() throws IOException, InterruptedException, ExecutionException, EventHubException { + + final AuthCallback callback = new AuthCallback(clientId, clientSecret); + ScheduledExecutorService executorService = getScheduledExecutorService(); + + final AzureActiveDirectoryTokenProvider aadTokenProvider = new AzureActiveDirectoryTokenProvider(callback, authority, null); + + final EventHubClient ehClient = EventHubClient.createWithTokenProvider(namespace, eventhub, aadTokenProvider, executorService, null).get(); + + sendReceive(ehClient, executorService); + } + + private void useCustomTokenProvider() throws IOException, InterruptedException, ExecutionException, EventHubException { + + final CustomTokenProvider tokenProvider = new CustomTokenProvider(authority, clientId, clientSecret); + ScheduledExecutorService executorService = getScheduledExecutorService(); + + final EventHubClient ehClient = EventHubClient.createWithTokenProvider(namespace, eventhub, tokenProvider, executorService, null).get(); + + sendReceive(ehClient, executorService); + } + + private void sendReceive(EventHubClient ehClient, ScheduledExecutorService executorService) throws IOException, EventHubException { + try { + final Gson gson = new GsonBuilder().create(); + + for (int i = 0; i < 100; i++) { + + String payload = "Message " + Integer.toString(i); + byte[] payloadBytes = gson.toJson(payload).getBytes(Charset.defaultCharset()); + EventData sendEvent = EventData.create(payloadBytes); + ehClient.sendSync(sendEvent); + } + + System.out.println(Instant.now() + ": Send Complete..."); + + final PartitionReceiver receiver = ehClient.createReceiverSync( + EventHubClient.DEFAULT_CONSUMER_GROUP_NAME, + "0", + EventPosition.fromStartOfStream()); + + Iterable receivedEvents = receiver.receiveSync(100); + while (true) { + int batchSize = 0; + if (receivedEvents != null) { + for (final EventData receivedEvent : receivedEvents) { + if (receivedEvent.getBytes() != null) + System.out.println(String.format("Message Payload: %s", new String(receivedEvent.getBytes(), Charset.defaultCharset()))); + + System.out.println(String.format("Offset: %s, SeqNo: %s, EnqueueTime: %s", + receivedEvent.getSystemProperties().getOffset(), + receivedEvent.getSystemProperties().getSequenceNumber(), + receivedEvent.getSystemProperties().getEnqueuedTime())); + batchSize++; + } + } + else { + break; + } + + System.out.println(String.format("ReceivedBatch Size: %s", batchSize)); + receivedEvents = receiver.receiveSync(100); + } + + System.out.println(Instant.now() + ": Receive Complete..."); + + System.out.println("Press Enter to stop."); + System.in.read(); + } finally { + ehClient.closeSync(); + executorService.shutdown(); + } + } +} From cbc412e5761d6c5ae1fe29c163a66fee80f9f2ce Mon Sep 17 00:00:00 2001 From: Sreedhar Pelluru Date: Tue, 22 Oct 2019 22:24:37 -0400 Subject: [PATCH 26/66] updated to use the 5.0.0 SDK (#459) * updated to use the 5.0.0 SDK * updated to use the 5.0.0 azure.messaging.eventhubs --- .../AnomalyDetector/Producer/Producer.csproj | 2 +- .../AnomalyDetector/Producer/Program.cs | 25 +++---- .../WindTurbineDataGenerator/App.config | 22 +++++- .../WindTurbineDataGenerator/Program.cs | 15 ++-- .../WindTurbineDataGenerator.csproj | 74 ++++++++++++++++++- .../WindTurbineDataGenerator/packages.config | 20 ++++- 6 files changed, 133 insertions(+), 25 deletions(-) diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/AnomalyDetector/Producer/Producer.csproj b/samples/DotNet/Microsoft.Azure.EventHubs/AnomalyDetector/Producer/Producer.csproj index cf1926bfe..be1913da2 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/AnomalyDetector/Producer/Producer.csproj +++ b/samples/DotNet/Microsoft.Azure.EventHubs/AnomalyDetector/Producer/Producer.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/AnomalyDetector/Producer/Program.cs b/samples/DotNet/Microsoft.Azure.EventHubs/AnomalyDetector/Producer/Program.cs index ace75d409..e2b567055 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/AnomalyDetector/Producer/Program.cs +++ b/samples/DotNet/Microsoft.Azure.EventHubs/AnomalyDetector/Producer/Program.cs @@ -6,15 +6,15 @@ namespace Producer using System; using System.Text; using System.Threading.Tasks; - using Microsoft.Azure.EventHubs; + using Azure.Messaging.EventHubs; using System.Collections.Generic; using System.IO; public class Program { - private const string EventHubConnectionString = "Event Hubs connection string"; + private const string EventHubConnectionString = ""; - private const string EventHubName = "Event Hub name"; + private const string EventHubName = ""; private const string TransactionsDumpFile = "mocktransactions.csv"; @@ -27,16 +27,10 @@ public static int Main(string[] args) private static async Task MainAsync(string[] args) { - // Creates an EventHubsConnectionStringBuilder object from a the connection string, and sets the EntityPath. - // Typically the connection string should have the Entity Path in it, but for the sake of this simple scenario - // we are using the connection string from the namespace. - var connectionStringBuilder = new EventHubsConnectionStringBuilder(EventHubConnectionString) - { - EntityPath = EventHubName, - }; - - eventHubClient = EventHubClient.CreateFromConnectionString(connectionStringBuilder.ToString()); + // create an Event Hubs client using the namespace connection string and the event hub name + eventHubClient = new EventHubClient(EventHubConnectionString, EventHubName); + // send messages to the event hub await SendMessagesToEventHubAsync(1000); await eventHubClient.CloseAsync(); @@ -64,6 +58,9 @@ private static async Task SendMessagesToEventHubAsync(int numMessagesToSend) TransactionsDumpFile, $"CreditCardId,Timestamp,Location,Amount,Type{Environment.NewLine}"); + // create a producer object that you can use to produce or send messages to the event hub + EventHubProducer producer = eventHubClient.CreateProducer(); + foreach (var t in transactions) { try @@ -93,7 +90,9 @@ private static async Task SendMessagesToEventHubAsync(int numMessagesToSend) File.AppendAllText(TransactionsDumpFile, line); var ed = new EventData(Encoding.UTF8.GetBytes(message)); - await eventHubClient.SendAsync(ed); + + // send the message to the event hub using the producer object + await producer.SendAsync(ed); } catch (Exception ex) { diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config index 731f6de6c..8291b54ec 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config @@ -1,6 +1,26 @@ - + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs index e97740b68..abbcf606e 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs @@ -6,7 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; -using Microsoft.Azure.EventHubs; +using Azure.Messaging.EventHubs; namespace WindTurbineDataGenerator { @@ -39,12 +39,11 @@ private static async Task StartEventGenerationAsync(CancellationToken cancellati { var random = new Random((int)DateTimeOffset.UtcNow.Ticks); - var connectionStringBuilder = new EventHubsConnectionStringBuilder(EventHubConnectionString) - { - EntityPath = EventHubName - }; + // create an Event Hubs client using the namespace connection string and the event hub name + EventHubClient client = new EventHubClient(EventHubConnectionString, EventHubName); - EventHubClient client = EventHubClient.CreateFromConnectionString(connectionStringBuilder.ToString()); + // create a producer object to send messages to the event hub + EventHubProducer producer = client.CreateProducer(); while (!cancellationToken.IsCancellationRequested) { @@ -62,7 +61,9 @@ private static async Task StartEventGenerationAsync(CancellationToken cancellati } Console.Write("."); - await client.SendAsync(devicesData); + + // send the message to the event hub + await producer.SendAsync(devicesData); } catch (Exception ex) { diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj index 8ddc90db0..9e5da2d22 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj @@ -32,17 +32,87 @@ 4 - - ..\packages\Microsoft.Azure.Amqp.2.0.4\lib\net45\Microsoft.Azure.Amqp.dll + + ..\packages\Azure.Core.1.0.0-preview.9\lib\netstandard2.0\Azure.Core.dll + + + ..\packages\Azure.Messaging.EventHubs.5.0.0-preview.4\lib\netstandard2.0\Azure.Messaging.EventHubs.dll + + + ..\packages\Microsoft.Azure.Amqp.2.4.2\lib\net45\Microsoft.Azure.Amqp.dll ..\packages\Microsoft.Azure.EventHubs.1.0.2\lib\net451\Microsoft.Azure.EventHubs.dll + + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0-rc1.19456.4\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + ..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll + + + ..\packages\System.Diagnostics.DiagnosticSource.4.6.0-rc1.19456.4\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + + ..\packages\System.Net.WebSockets.4.0.0\lib\net46\System.Net.WebSockets.dll + True + True + + + ..\packages\System.Net.WebSockets.Client.4.0.2\lib\net46\System.Net.WebSockets.Client.dll + True + True + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Reflection.TypeExtensions.4.5.1\lib\net461\System.Reflection.TypeExtensions.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + + ..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll + True + True + + + ..\packages\System.Security.Cryptography.Algorithms.4.2.0\lib\net461\System.Security.Cryptography.Algorithms.dll + True + True + + + ..\packages\System.Security.Cryptography.Encoding.4.0.0\lib\net46\System.Security.Cryptography.Encoding.dll + True + True + + + ..\packages\System.Security.Cryptography.Primitives.4.0.0\lib\net46\System.Security.Cryptography.Primitives.dll + True + True + + + ..\packages\System.Security.Cryptography.X509Certificates.4.1.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + True + True + + + ..\packages\System.Threading.Channels.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Threading.Channels.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config index 440e8d5c6..3a3e6b5ca 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config @@ -1,6 +1,24 @@  - + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 790471f8463313a18787340f5cf3ff6c8ea8dd11 Mon Sep 17 00:00:00 2001 From: JamesBirdsall Date: Wed, 23 Oct 2019 14:20:52 -0700 Subject: [PATCH 27/66] Update samples for client 3.0.2 (#457) * Update samples for client 3.0.1 * Update samples for client 3.0.2 --- samples/Java/Basic/AdvancedSendOptions/pom.xml | 2 +- samples/Java/Basic/EventProcessorSample/pom.xml | 4 ++-- samples/Java/Basic/ReceiveByDateTime/pom.xml | 2 +- samples/Java/Basic/ReceiveUsingOffset/pom.xml | 2 +- samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml | 2 +- samples/Java/Basic/SendBatch/pom.xml | 2 +- samples/Java/Basic/SimpleProxy/pom.xml | 2 +- samples/Java/Basic/SimpleSend/pom.xml | 2 +- samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml | 2 +- samples/Java/Benchmarks/IngressBenchmark/pom.xml | 2 +- samples/Java/Rbac/pom.xml | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/samples/Java/Basic/AdvancedSendOptions/pom.xml b/samples/Java/Basic/AdvancedSendOptions/pom.xml index 24259349a..4cb5b21de 100644 --- a/samples/Java/Basic/AdvancedSendOptions/pom.xml +++ b/samples/Java/Basic/AdvancedSendOptions/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 3.0.2 com.google.code.gson diff --git a/samples/Java/Basic/EventProcessorSample/pom.xml b/samples/Java/Basic/EventProcessorSample/pom.xml index 509907670..f66303de8 100644 --- a/samples/Java/Basic/EventProcessorSample/pom.xml +++ b/samples/Java/Basic/EventProcessorSample/pom.xml @@ -47,12 +47,12 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 3.0.2 com.microsoft.azure azure-eventhubs-eph - 3.0.0 + 3.0.2 log4j diff --git a/samples/Java/Basic/ReceiveByDateTime/pom.xml b/samples/Java/Basic/ReceiveByDateTime/pom.xml index f01af98df..1124ea6be 100644 --- a/samples/Java/Basic/ReceiveByDateTime/pom.xml +++ b/samples/Java/Basic/ReceiveByDateTime/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 3.0.2 diff --git a/samples/Java/Basic/ReceiveUsingOffset/pom.xml b/samples/Java/Basic/ReceiveUsingOffset/pom.xml index 727de2acd..669acc71b 100644 --- a/samples/Java/Basic/ReceiveUsingOffset/pom.xml +++ b/samples/Java/Basic/ReceiveUsingOffset/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 3.0.2 diff --git a/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml b/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml index c0fc9b4b7..b91950b98 100644 --- a/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml +++ b/samples/Java/Basic/ReceiveUsingSequenceNumber/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 3.0.2 diff --git a/samples/Java/Basic/SendBatch/pom.xml b/samples/Java/Basic/SendBatch/pom.xml index 73138cadd..97b8a0e94 100644 --- a/samples/Java/Basic/SendBatch/pom.xml +++ b/samples/Java/Basic/SendBatch/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 3.0.2 com.google.code.gson diff --git a/samples/Java/Basic/SimpleProxy/pom.xml b/samples/Java/Basic/SimpleProxy/pom.xml index e7fd40b0f..b403f18ed 100644 --- a/samples/Java/Basic/SimpleProxy/pom.xml +++ b/samples/Java/Basic/SimpleProxy/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 3.0.2 com.google.code.gson diff --git a/samples/Java/Basic/SimpleSend/pom.xml b/samples/Java/Basic/SimpleSend/pom.xml index a826774a3..16bb783cb 100644 --- a/samples/Java/Basic/SimpleSend/pom.xml +++ b/samples/Java/Basic/SimpleSend/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 3.0.2 com.google.code.gson diff --git a/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml b/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml index 9eaa993f8..ec1a5cc43 100644 --- a/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml +++ b/samples/Java/Benchmarks/AutoScaleOnIngress/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 3.0.2 diff --git a/samples/Java/Benchmarks/IngressBenchmark/pom.xml b/samples/Java/Benchmarks/IngressBenchmark/pom.xml index 9c0462d2a..1298bec57 100644 --- a/samples/Java/Benchmarks/IngressBenchmark/pom.xml +++ b/samples/Java/Benchmarks/IngressBenchmark/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 3.0.2 diff --git a/samples/Java/Rbac/pom.xml b/samples/Java/Rbac/pom.xml index ad0b69401..e2f5e8aff 100644 --- a/samples/Java/Rbac/pom.xml +++ b/samples/Java/Rbac/pom.xml @@ -47,7 +47,7 @@ com.microsoft.azure azure-eventhubs - 3.0.0 + 3.0.2 com.google.code.gson From 8cf2471b37da3efc67cf523306fe44a0c4e87a26 Mon Sep 17 00:00:00 2001 From: spelluru Date: Tue, 29 Oct 2019 22:32:21 -0400 Subject: [PATCH 28/66] updated samples used by tutorials to use the new package --- .../AnomalyDetector/AnomalyDetector.sln | 25 ++ .../Producer/EventGenerator.cs | 127 ++++++++ .../AnomalyDetector/Producer/JsonHelper.cs | 41 +++ .../AnomalyDetector/Producer/Producer.csproj | 13 + .../AnomalyDetector/Producer/Program.cs | 109 +++++++ .../AnomalyDetector/Producer/Transaction.cs | 13 + .../Producer/TransactionData.cs | 19 ++ .../Producer/TransactionType.cs | 17 ++ .../AnomalyDetector/Readme.md | 5 + .../DWDumper/App.config | 14 + .../DWDumper/DWDumper.csproj | 82 ++++++ .../DWDumper/Program.cs | 113 +++++++ .../DWDumper/Properties/AssemblyInfo.cs | 36 +++ .../DWDumper/WindTurbineMeasure.cs | 14 + .../DWDumper/packages.config | 16 + .../EventHubsCaptureEventGridDemo.sln | 37 +++ .../FunctionEGDWDumper/EventGridEvent.cs | 29 ++ .../FunctionEGDWDumper/Function1.cs | 153 ++++++++++ .../FunctionEGDWDumper.csproj | 23 ++ .../FunctionEGDWDumper/WindTurbineMeasure.cs | 14 + .../FunctionEGDWDumper/host.json | 2 + .../FunctionEGDWDumper/local.settings.json | 7 + .../EventHubsCaptureEventGridDemo/Readme.md | 3 + .../WindTurbineDataGenerator/App.config | 26 ++ .../WindTurbineDataGenerator/Program.cs | 97 ++++++ .../Properties/AssemblyInfo.cs | 36 +++ .../WindTurbineDataGenerator.csproj | 133 +++++++++ .../WindTurbineMeasure.cs | 14 + .../WindTurbineDataGenerator/packages.config | 24 ++ .../scripts/CreateDataWarehouseTable.sql | 8 + .../ManagedIdentityWebApp/Global.asax | 1 + .../ManagedIdentityWebApp/Global.asax.cs | 16 + .../ManagedIdentityWebApp.csproj | 277 ++++++++++++++++++ .../ManagedIdentityWebApp.sln | 25 ++ .../Properties/AssemblyInfo.cs | 35 +++ .../ManagedIdentityWebApp/README.md | 4 + .../ManagedIdentityWebApp/SendReceive.aspx | 32 ++ .../ManagedIdentityWebApp/SendReceive.aspx.cs | 56 ++++ .../SendReceive.aspx.designer.cs | 89 ++++++ .../ManagedIdentityWebApp/StyleSheet.css | 13 + .../ManagedIdentityWebApp/Web.Debug.config | 30 ++ .../ManagedIdentityWebApp/Web.Release.config | 31 ++ .../ManagedIdentityWebApp/Web.config | 66 +++++ .../ManagedIdentityWebApp/packages.config | 40 +++ 44 files changed, 1965 insertions(+) create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/AnomalyDetector.sln create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/EventGenerator.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/JsonHelper.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Transaction.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/TransactionData.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/TransactionType.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Readme.md create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/App.config create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Properties/AssemblyInfo.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/packages.config create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/WindTurbineMeasure.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/local.settings.json create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/Readme.md create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Properties/AssemblyInfo.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineMeasure.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/scripts/CreateDataWarehouseTable.sql create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Global.asax create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Global.asax.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.sln create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Properties/AssemblyInfo.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/README.md create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.designer.cs create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/StyleSheet.css create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.Debug.config create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.Release.config create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.config create mode 100644 samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/AnomalyDetector.sln b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/AnomalyDetector.sln new file mode 100644 index 000000000..13711caba --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/AnomalyDetector.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27004.2005 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Producer", "Producer\Producer.csproj", "{8A768654-3ABD-4D6B-BDB3-C59CFC05C50A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8A768654-3ABD-4D6B-BDB3-C59CFC05C50A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A768654-3ABD-4D6B-BDB3-C59CFC05C50A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A768654-3ABD-4D6B-BDB3-C59CFC05C50A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A768654-3ABD-4D6B-BDB3-C59CFC05C50A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {73BDBF55-C72D-4F8D-999B-E8E068E3B5A4} + EndGlobalSection +EndGlobal diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/EventGenerator.cs b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/EventGenerator.cs new file mode 100644 index 000000000..6ec4d0c10 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/EventGenerator.cs @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Producer +{ + using System; + using System.Collections.Generic; + + internal sealed class EventGenerator + { + // i.e. 1 in every 20 transactions is an anomaly + private const int AnomalyFactor = 20; + + private const int MaxAmount = 1000; + + private const int MaxDays = 30; + + private readonly Random random = new Random((int)DateTimeOffset.UtcNow.Ticks); + + private readonly DateTimeOffset startTime = new DateTimeOffset(DateTime.Now); + + private readonly List knownCreditCards = new List + { + "FC6018B3-B934-4FFF-B6A9-904C4B3082C7", + "71B3B20F-0BD1-4C1D-BA33-3264D904581C", + "B3B19755-C6E5-4E4A-B423-1B31DCCEB137", + "1AF29CA0-FBF2-48B6-9D0B-88FF331FADC1", + "039AA17C-2C5C-4A4F-B019-D416D0E4F5E6", + }; + + private readonly List knownLocations = new List + { + "Seattle", + "San Francisco", + "New York", + "Kahului", + "Miami", + }; + + public IEnumerable GenerateEvents(int count) + { + int counter = 0; + + var timestamp = startTime; + + while (counter < count) + { + foreach (var t in NewMockPurchases(timestamp)) + { + yield return t; + counter++; + } + + timestamp += TimeSpan.FromMinutes(10); + } + } + + /// + /// Returns a new mock transaction. In some cases where there is an anomaly, then it returns + /// 2 transactions. one regular and one anomaly. They differ in amounts, locations and timestamps, but have + /// the same credit card Id. + /// At the consumer side, since the timestamps are close together but the locations are different, these + /// 2 transactions are flagged as anomalous. + /// + /// + private IEnumerable NewMockPurchases(DateTimeOffset timestamp) + { + var maxIndex = Math.Min(knownCreditCards.Count, knownLocations.Count); + + var index = random.Next(0, maxIndex); + var cc = knownCreditCards[index]; + var location = knownLocations[index]; + + bool isAnomaly = (random.Next(0, AnomalyFactor) % AnomalyFactor) == 0; + + var purchases = new List(); + + var regularTransaction = new Transaction + { + Data = new TransactionData + { + Amount = random.Next(1, MaxAmount), + Location = location, + CreditCardId = cc, + Timestamp = timestamp, + }, + Type = TransactionType.Regular, + }; + + purchases.Add(regularTransaction); + + if (isAnomaly) + { + // change the location to something else + // now the transaction on a credit card is happening from a different location which is an anomaly! + + string newLocation = null; + + do + { + var newIndex = random.Next(0, knownLocations.Count); + newLocation = knownLocations[newIndex]; + + // while loop is - if by chance the "random" new location is the same as the original location + + } while (string.Equals(newLocation, location, StringComparison.OrdinalIgnoreCase)); + + var suspectTransaction = new Transaction + { + Data = new TransactionData + { + Amount = random.Next(1, MaxAmount), + Location = newLocation, + CreditCardId = cc, + Timestamp = timestamp + TimeSpan.FromSeconds(2), // suspect transaction time range is close to a regular transaction + }, + Type = TransactionType.Suspect, + }; + + purchases.Add(suspectTransaction); + } + + return purchases; + } + } +} + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/JsonHelper.cs b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/JsonHelper.cs new file mode 100644 index 000000000..5e48472f4 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/JsonHelper.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Producer +{ + using Newtonsoft.Json; + using Newtonsoft.Json.Serialization; + public static class JsonHelper + { + private static readonly JsonSerializerSettings publicSerializationSettings = CreatePublicSerializationSettings(); + + /// + /// Converts an object to its Json representation. + /// + public static string ToJson(this T value) + { + string json = JsonConvert.SerializeObject(value, typeof(T), publicSerializationSettings); + return json; + } + + /// + /// Converts a Json string to an object. + /// + public static T FromJson(this string value) + { + T @object = JsonConvert.DeserializeObject(value, publicSerializationSettings); + + return @object; + } + + private static JsonSerializerSettings CreatePublicSerializationSettings() + { + var settings = new JsonSerializerSettings(); + + settings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter()); + + return settings; + } + } +} + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj new file mode 100644 index 000000000..be1913da2 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj @@ -0,0 +1,13 @@ + + + + Exe + netcoreapp2.0 + + + + + + + + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs new file mode 100644 index 000000000..e2b567055 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs @@ -0,0 +1,109 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Producer +{ + using System; + using System.Text; + using System.Threading.Tasks; + using Azure.Messaging.EventHubs; + using System.Collections.Generic; + using System.IO; + + public class Program + { + private const string EventHubConnectionString = ""; + + private const string EventHubName = ""; + + private const string TransactionsDumpFile = "mocktransactions.csv"; + + private static EventHubClient eventHubClient; + + public static int Main(string[] args) + { + return MainAsync(args).GetAwaiter().GetResult(); + } + + private static async Task MainAsync(string[] args) + { + // create an Event Hubs client using the namespace connection string and the event hub name + eventHubClient = new EventHubClient(EventHubConnectionString, EventHubName); + + // send messages to the event hub + await SendMessagesToEventHubAsync(1000); + + await eventHubClient.CloseAsync(); + + Console.WriteLine("Press [enter] to exit."); + Console.ReadLine(); + + return 0; + } + + // Creates an Event Hub client and sends messages to the event hub. + private static async Task SendMessagesToEventHubAsync(int numMessagesToSend) + { + var eg = new EventGenerator(); + + IEnumerable transactions = eg.GenerateEvents(numMessagesToSend); + + if (File.Exists(TransactionsDumpFile)) + { + // exceptions not handled for brevity + File.Delete(TransactionsDumpFile); + } + + File.AppendAllText( + TransactionsDumpFile, + $"CreditCardId,Timestamp,Location,Amount,Type{Environment.NewLine}"); + + // create a producer object that you can use to produce or send messages to the event hub + EventHubProducer producer = eventHubClient.CreateProducer(); + + foreach (var t in transactions) + { + try + { + // we don't send the transaction type as part of the message. + // that is up to the downstream analytics to figure out! + // we just pretty print them here so they can easily be compared with the downstream + // analytics results. + var message = t.Data.ToJson(); + + if (t.Type == TransactionType.Suspect) + { + var fc = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.Yellow; + + Console.WriteLine($"Suspect transaction: {message}"); + + Console.ForegroundColor = fc; // reset to original + } + else + { + Console.WriteLine($"Regular transaction: {message}"); + } + + var line = $"{t.Data.CreditCardId},{t.Data.Timestamp.ToString("o")},{t.Data.Location},{t.Data.Amount},{t.Type}{Environment.NewLine}"; + + File.AppendAllText(TransactionsDumpFile, line); + + var ed = new EventData(Encoding.UTF8.GetBytes(message)); + + // send the message to the event hub using the producer object + await producer.SendAsync(ed); + } + catch (Exception ex) + { + Console.WriteLine($"{t.ToJson()}{Environment.NewLine}Exception: {ex.Message}"); + } + + await Task.Delay(10); + } + + Console.WriteLine($"{numMessagesToSend} messages sent."); + } + } +} + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Transaction.cs b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Transaction.cs new file mode 100644 index 000000000..eb743f1c3 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Transaction.cs @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Producer +{ + internal sealed class Transaction + { + public TransactionData Data { get; set; } + + public TransactionType Type { get; set; } + } +} + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/TransactionData.cs b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/TransactionData.cs new file mode 100644 index 000000000..dd4af634f --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/TransactionData.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Producer +{ + using System; + + internal sealed class TransactionData + { + public string CreditCardId { get; set; } // like a credit card no. just simpler to use a Guid for our sample than a 16 digit no! + + public int Amount { get; set; } // simplified to int instead of double for now + + public string Location { get; set; } + + public DateTimeOffset Timestamp { get; set; } + } +} + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/TransactionType.cs b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/TransactionType.cs new file mode 100644 index 000000000..6bccc741c --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/TransactionType.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Producer +{ + /// + /// A mechanism to identify the mock transactions that are generated on the client side. + /// This is not used downstream. But is used more for an easy (or visual) comparison of + /// anomalous data that the downstream analytics produces. + /// + internal enum TransactionType + { + Regular, + Suspect, + } +} + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Readme.md b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Readme.md new file mode 100644 index 000000000..6c6aeb0ad --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Readme.md @@ -0,0 +1,5 @@ + +# Visualize data anomalies in real-time events sent to Azure Event Hubs +In this sample, you run an application that creates and sends credit card transactions to an event hub. Then you read the stream of data in real-time with Azure Stream Analytics, which separates the valid transactions from the invalid transactions, and then use Power BI to visually identify the transactions that are tagged as invalid. + +For detailed information and steps for using this sample, see [this article](https://docs.microsoft.com/azure/event-hubs/event-hubs-tutorial-visualize-anomalies). \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/App.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/App.config new file mode 100644 index 000000000..390b41521 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/App.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj new file mode 100644 index 000000000..b947b0d03 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj @@ -0,0 +1,82 @@ + + + + + Debug + AnyCPU + {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3} + Exe + DWDumper + DWDumper + v4.6.1 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Apache.Avro.1.7.7.2\lib\Avro.dll + + + ..\packages\log4net.1.2.10\lib\2.0\log4net.dll + + + ..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll + + + ..\packages\Microsoft.Data.Edm.5.8.2\lib\net40\Microsoft.Data.Edm.dll + + + ..\packages\Microsoft.Data.OData.5.8.2\lib\net40\Microsoft.Data.OData.dll + + + ..\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll + + + ..\packages\WindowsAzure.Storage.8.3.0\lib\net45\Microsoft.WindowsAzure.Storage.dll + + + ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll + True + + + + + ..\packages\System.Spatial.5.8.2\lib\net40\System.Spatial.dll + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs new file mode 100644 index 000000000..2b9e73718 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Avro.File; +using Avro.Generic; +using Newtonsoft.Json; +using Microsoft.WindowsAzure.Storage; + +namespace DWDumper +{ + /// + /// A simple test program to dump a single Avro blob file created by EventHubs Capture into a SQL data warehouse (DW). + /// This is useful for testing connections with your SQL DW before integrating this DW dumping code with Azure Functions + /// + class Program + { + private const string StorageConnectionString = "[provide your storage connection string]"; + private const string EventHubsCaptureAvroBlobUri = "[provide the blob path to a single blob file just to test if it can be parsed and dumped to the DW]"; + private const string SqlDwConnection = "[provide the SQL DW connection string]"; + + private static int Main(string[] args) + { + var p = new Program(); + p.Dump(); + + return 0; + } + + public void Dump() + { + // Get the blob reference + var storageAccount = CloudStorageAccount.Parse(StorageConnectionString); + var blobClient = storageAccount.CreateCloudBlobClient(); + var blob = blobClient.GetBlobReferenceFromServer(new Uri(EventHubsCaptureAvroBlobUri)); + + using (var dataTable = GetWindTurbineMetricsTable()) + { + // Parse the Avro File + using (var avroReader = DataFileReader.OpenReader(blob.OpenRead())) + { + while (avroReader.HasNext()) + { + GenericRecord r = avroReader.Next(); + + byte[] body = (byte[]) r["Body"]; + var windTurbineMeasure = DeserializeToWindTurbineMeasure(body); + + // Add the row to in memory table + AddWindTurbineMetricToTable(dataTable, windTurbineMeasure); + } + } + + if (dataTable.Rows.Count > 0) + { + BatchInsert(dataTable); + } + } + } + + private void BatchInsert(DataTable table) + { + // Write the data to SQL DW using SqlBulkCopy + using (var sqlDwConnection = new SqlConnection(SqlDwConnection)) + { + sqlDwConnection.Open(); + + using (var bulkCopy = new SqlBulkCopy(sqlDwConnection)) + { + bulkCopy.BulkCopyTimeout = 30; + bulkCopy.DestinationTableName = "dbo.Fact_WindTurbineMetrics"; + bulkCopy.WriteToServer(table); + } + } + } + + private WindTurbineMeasure DeserializeToWindTurbineMeasure(byte[] body) + { + string payload = Encoding.ASCII.GetString(body); + return JsonConvert.DeserializeObject(payload); + } + + private DataTable GetWindTurbineMetricsTable() + { + var dt = new DataTable(); + dt.Columns.AddRange + ( + new DataColumn[5] + { + new DataColumn("DeviceId", typeof(string)), + new DataColumn("MeasureTime", typeof(DateTime)), + new DataColumn("GeneratedPower", typeof(float)), + new DataColumn("WindSpeed", typeof(float)), + new DataColumn("TurbineSpeed", typeof(float)) + } + ); + + return dt; + } + + private void AddWindTurbineMetricToTable(DataTable table, WindTurbineMeasure wtm) + { + table.Rows.Add(wtm.DeviceId, wtm.MeasureTime, wtm.GeneratedPower, wtm.WindSpeed, wtm.TurbineSpeed); + Console.WriteLine( + "DeviceId: {0}, MeasureTime: {1}, GeneratedPower: {2}, WindSpeed: {3}, TurbineSpeed: {4}", + wtm.DeviceId, wtm.MeasureTime, wtm.GeneratedPower, wtm.WindSpeed, wtm.TurbineSpeed); + } + } + +} diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Properties/AssemblyInfo.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..d12e26ed9 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("DWDumper")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DWDumper")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c9e1d3c8-0c0d-45eb-a3b5-15f95efc01e3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs new file mode 100644 index 000000000..0ab7b9217 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs @@ -0,0 +1,14 @@ +using System; + +namespace DWDumper +{ + // TODO, move this class to a Contracts assembly that is shared across different projects + class WindTurbineMeasure + { + public string DeviceId { get; set; } + public DateTime MeasureTime { get; set; } + public float GeneratedPower { get; set; } + public float WindSpeed { get; set; } + public float TurbineSpeed { get; set; } + } +} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/packages.config new file mode 100644 index 000000000..935667da9 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/packages.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln new file mode 100644 index 000000000..2d7d0cecf --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindTurbineDataGenerator", "WindTurbineDataGenerator\WindTurbineDataGenerator.csproj", "{0C87A54A-AD21-46D5-8B75-4247DA32237E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DWDumper", "DWDumper\DWDumper.csproj", "{C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionEGDWDumper", "FunctionEGDWDumper\FunctionEGDWDumper.csproj", "{27D28A3D-4157-4ED2-A1C4-5525507CCA04}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Release|Any CPU.Build.0 = Release|Any CPU + {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Release|Any CPU.Build.0 = Release|Any CPU + {27D28A3D-4157-4ED2-A1C4-5525507CCA04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {27D28A3D-4157-4ED2-A1C4-5525507CCA04}.Debug|Any CPU.Build.0 = Debug|Any CPU + {27D28A3D-4157-4ED2-A1C4-5525507CCA04}.Release|Any CPU.ActiveCfg = Release|Any CPU + {27D28A3D-4157-4ED2-A1C4-5525507CCA04}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0BDB7260-AF54-438B-B99E-95E7136C1486} + EndGlobalSection +EndGlobal diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs new file mode 100644 index 000000000..8b5d40302 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs @@ -0,0 +1,29 @@ +namespace FunctionEGDWDumper +{ + /// + /// These classes were generated from the EventGrid event schema. + /// comments for understanding how the EventGrid schema was obtained. + /// + public class EventGridEHEvent + { + public string topic { get; set; } + public string subject { get; set; } + public string eventType { get; set; } + public string eventTime { get; set; } + public string id { get; set; } + public Data data { get; set; } + } + + public class Data + { + public string fileUrl { get; set; } + public string fileType { get; set; } + public string partitionId { get; set; } + public int sizeInBytes { get; set; } + public int eventCount { get; set; } + public int firstSequenceNumber { get; set; } + public int lastSequenceNumber { get; set; } + public string firstEnqueueTime { get; set; } + public string lastEnqueueTime { get; set; } + } +} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs new file mode 100644 index 000000000..41944c22f --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs @@ -0,0 +1,153 @@ +// This is the default URL for triggering event grid function in the local environment. +// http://localhost:7071/admin/extensions/EventGridExtensionConfig?functionName={functionname} + +using System; +using System.Data; +using System.Data.SqlClient; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Avro.File; +using Avro.Generic; +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Extensions.EventGrid; +using Microsoft.Azure.WebJobs.Extensions.Http; +using Microsoft.Azure.WebJobs.Host; +using Microsoft.WindowsAzure.Storage; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace FunctionEGDWDumper +{ + + public static class Function1 + { + private static readonly string StorageConnectionString = Environment.GetEnvironmentVariable("StorageConnectionString"); + private static readonly string SqlDwConnection = Environment.GetEnvironmentVariable("SqlDwConnection"); + + /// + /// Use the accompanying .sql script to create this table in the data warehouse + /// + private const string TableName = "dbo.Fact_WindTurbineMetrics"; + + [FunctionName("EventGridTriggerMigrateData")] + public static void Run([EventGridTrigger]JObject eventGridEvent, TraceWriter log) + { + log.Info("C# EventGrid trigger function processed a request."); + log.Info(eventGridEvent.ToString(Formatting.Indented)); + + try + { + // Copy to a static Album instance + EventGridEHEvent ehEvent = eventGridEvent.ToObject(); + + // Get the URL from the event that points to the Capture file + var uri = new Uri(ehEvent.data.fileUrl); + + // Get data from the file and migrate to data warehouse + Dump(uri); + } + catch (Exception e) + { + string s = string.Format(CultureInfo.InvariantCulture, + "Error processing request. Exception: {0}, Request: {1}", e, eventGridEvent.ToString()); + log.Error(s); + } + } + + /// + /// Dumps the data from the Avro blob to the data warehouse (DW). + /// Before running this, ensure that the DW has the required table created. + /// + private static void Dump(Uri fileUri) + { + // Get the blob reference + var storageAccount = CloudStorageAccount.Parse(StorageConnectionString); + var blobClient = storageAccount.CreateCloudBlobClient(); + var blob = blobClient.GetBlobReferenceFromServer(fileUri); + + using (var dataTable = GetWindTurbineMetricsTable()) + { + // Parse the Avro File + using (var avroReader = DataFileReader.OpenReader(blob.OpenRead())) + { + while (avroReader.HasNext()) + { + GenericRecord r = avroReader.Next(); + + byte[] body = (byte[])r["Body"]; + var windTurbineMeasure = DeserializeToWindTurbineMeasure(body); + + // Add the row to in memory table + AddWindTurbineMetricToTable(dataTable, windTurbineMeasure); + } + } + + if (dataTable.Rows.Count > 0) + { + BatchInsert(dataTable); + } + } + } + + /// + /// Open connection to data warehouse. Write the parsed data to the table. + /// + private static void BatchInsert(DataTable table) + { + // Write the data to SQL DW using SqlBulkCopy + using (var sqlDwConnection = new SqlConnection(SqlDwConnection)) + { + sqlDwConnection.Open(); + + using (var bulkCopy = new SqlBulkCopy(sqlDwConnection)) + { + bulkCopy.BulkCopyTimeout = 30; + bulkCopy.DestinationTableName = TableName; + bulkCopy.WriteToServer(table); + } + } + } + + /// + /// Deserialize data and return object with expected properties. + /// + private static WindTurbineMeasure DeserializeToWindTurbineMeasure(byte[] body) + { + string payload = Encoding.ASCII.GetString(body); + return JsonConvert.DeserializeObject(payload); + } + + /// + /// Define the in-memory table to store the data. The columns match the columns in the .sql script. + /// + private static DataTable GetWindTurbineMetricsTable() + { + var dt = new DataTable(); + dt.Columns.AddRange + ( + new DataColumn[5] + { + new DataColumn("DeviceId", typeof(string)), + new DataColumn("MeasureTime", typeof(DateTime)), + new DataColumn("GeneratedPower", typeof(float)), + new DataColumn("WindSpeed", typeof(float)), + new DataColumn("TurbineSpeed", typeof(float)) + } + ); + + return dt; + } + + /// + /// For each parsed record, add a row to the in-memory table. + /// + private static void AddWindTurbineMetricToTable(DataTable table, WindTurbineMeasure wtm) + { + table.Rows.Add(wtm.DeviceId, wtm.MeasureTime, wtm.GeneratedPower, wtm.WindSpeed, wtm.TurbineSpeed); + } + } +} diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj new file mode 100644 index 000000000..84dfa5bc1 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj @@ -0,0 +1,23 @@ + + + net461 + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + Never + + + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/WindTurbineMeasure.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/WindTurbineMeasure.cs new file mode 100644 index 000000000..0c35262d2 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/WindTurbineMeasure.cs @@ -0,0 +1,14 @@ +using System; + +namespace FunctionEGDWDumper +{ + // TODO, move this class to a Contracts assembly that is shared across different projects + class WindTurbineMeasure + { + public string DeviceId { get; set; } + public DateTime MeasureTime { get; set; } + public float GeneratedPower { get; set; } + public float WindSpeed { get; set; } + public float TurbineSpeed { get; set; } + } +} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json new file mode 100644 index 000000000..7a73a41bf --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/local.settings.json b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/local.settings.json new file mode 100644 index 000000000..8f901f116 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/local.settings.json @@ -0,0 +1,7 @@ +{ + "IsEncrypted": false, + "Values": { + "AzureWebJobsStorage": "", + "AzureWebJobsDashboard": "" + } +} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/Readme.md b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/Readme.md new file mode 100644 index 000000000..ed3773221 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/Readme.md @@ -0,0 +1,3 @@ +# Migrate captured Event Hubs data to a SQL Data Warehouse using Event Grid and Azure Function + +See this [tutorial article](https://docs.microsoft.com/azure/event-hubs/store-captured-data-data-warehouse) for details on using this sample. It shows you how to capture data from your event hub into a SQL data warehouse by using an Azure function triggered by an event grid. diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config new file mode 100644 index 000000000..8291b54ec --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs new file mode 100644 index 000000000..abbcf606e --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Azure.Messaging.EventHubs; + +namespace WindTurbineDataGenerator +{ + internal class Program + { + private const string EventHubConnectionString = + "[provide the EH connection string]"; + + private const string EventHubName = "[provide the EH name]"; + + private static int Main(string[] args) + { + Console.WriteLine("Starting wind turbine generator. Press to exit"); + + // Start generation of events + var cts = new CancellationTokenSource(); + + var t0 = StartEventGenerationAsync(cts.Token); + + Console.ReadLine(); + cts.Cancel(); + + var t1 = Task.Delay(TimeSpan.FromSeconds(3)); + Task.WhenAny(t0, t1).GetAwaiter().GetResult(); + + return 0; + } + + private static async Task StartEventGenerationAsync(CancellationToken cancellationToken) + { + var random = new Random((int)DateTimeOffset.UtcNow.Ticks); + + // create an Event Hubs client using the namespace connection string and the event hub name + EventHubClient client = new EventHubClient(EventHubConnectionString, EventHubName); + + // create a producer object to send messages to the event hub + EventHubProducer producer = client.CreateProducer(); + + while (!cancellationToken.IsCancellationRequested) + { + try + { + // Simulate sending data from 100 weather sensors + var devicesData = new List(); + + for (int i = 0; i < 100; i++) + { + int scaleFactor = random.Next(0, 25); + var windTurbineMeasure = GenerateTurbineMeasure("Turbine_" + i, scaleFactor); + EventData evData = SerializeWindTurbineToEventData(windTurbineMeasure); + devicesData.Add(evData); + } + + Console.Write("."); + + // send the message to the event hub + await producer.SendAsync(devicesData); + } + catch (Exception ex) + { + Debug.WriteLine("Error generating turbine data. Exception: {0}", ex); + Console.Write("E"); + } + + await Task.Delay(1000, cancellationToken); + } + } + + private static WindTurbineMeasure GenerateTurbineMeasure(string turbineId, int scaleFactor) + { + return new WindTurbineMeasure + { + DeviceId = turbineId, + MeasureTime = DateTime.UtcNow, + GeneratedPower = 2.5F * scaleFactor, // in MegaWatts/hour + WindSpeed = 15 * scaleFactor, // miles per hour + TurbineSpeed = 0.3F * scaleFactor // RPMs + }; + } + + private static EventData SerializeWindTurbineToEventData(WindTurbineMeasure wtm) + { + var messageString = JsonConvert.SerializeObject(wtm); + var bytes = Encoding.ASCII.GetBytes(messageString); + return new EventData(bytes); + } + } +} diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Properties/AssemblyInfo.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..3287a2bd9 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("WindTurbineDataGenerator")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("WindTurbineDataGenerator")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("0c87a54a-ad21-46d5-8b75-4247da32237e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj new file mode 100644 index 000000000..9e5da2d22 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj @@ -0,0 +1,133 @@ + + + + + Debug + AnyCPU + {0C87A54A-AD21-46D5-8B75-4247DA32237E} + Exe + WindTurbineDataGenerator + WindTurbineDataGenerator + v4.6.1 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Azure.Core.1.0.0-preview.9\lib\netstandard2.0\Azure.Core.dll + + + ..\packages\Azure.Messaging.EventHubs.5.0.0-preview.4\lib\netstandard2.0\Azure.Messaging.EventHubs.dll + + + ..\packages\Microsoft.Azure.Amqp.2.4.2\lib\net45\Microsoft.Azure.Amqp.dll + + + ..\packages\Microsoft.Azure.EventHubs.1.0.2\lib\net451\Microsoft.Azure.EventHubs.dll + + + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0-rc1.19456.4\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + + ..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll + + + + ..\packages\System.Diagnostics.DiagnosticSource.4.6.0-rc1.19456.4\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + + ..\packages\System.Net.WebSockets.4.0.0\lib\net46\System.Net.WebSockets.dll + True + True + + + ..\packages\System.Net.WebSockets.Client.4.0.2\lib\net46\System.Net.WebSockets.Client.dll + True + True + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Reflection.TypeExtensions.4.5.1\lib\net461\System.Reflection.TypeExtensions.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + + ..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll + True + True + + + ..\packages\System.Security.Cryptography.Algorithms.4.2.0\lib\net461\System.Security.Cryptography.Algorithms.dll + True + True + + + ..\packages\System.Security.Cryptography.Encoding.4.0.0\lib\net46\System.Security.Cryptography.Encoding.dll + True + True + + + ..\packages\System.Security.Cryptography.Primitives.4.0.0\lib\net46\System.Security.Cryptography.Primitives.dll + True + True + + + ..\packages\System.Security.Cryptography.X509Certificates.4.1.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + True + True + + + ..\packages\System.Threading.Channels.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Threading.Channels.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineMeasure.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineMeasure.cs new file mode 100644 index 000000000..35ecad5b8 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineMeasure.cs @@ -0,0 +1,14 @@ +using System; + +namespace WindTurbineDataGenerator +{ + // TODO, move this class to a Contracts assembly that is shared across different projects + class WindTurbineMeasure + { + public string DeviceId { get; set; } + public DateTime MeasureTime { get; set; } + public float GeneratedPower { get; set; } + public float WindSpeed { get; set; } + public float TurbineSpeed { get; set; } + } +} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config new file mode 100644 index 000000000..3a3e6b5ca --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/scripts/CreateDataWarehouseTable.sql b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/scripts/CreateDataWarehouseTable.sql new file mode 100644 index 000000000..163f9eea3 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/scripts/CreateDataWarehouseTable.sql @@ -0,0 +1,8 @@ +CREATE TABLE [dbo].[Fact_WindTurbineMetrics] ( + [DeviceId] nvarchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, + [MeasureTime] datetime NULL, + [GeneratedPower] float NULL, + [WindSpeed] float NULL, + [TurbineSpeed] float NULL +) +WITH (CLUSTERED COLUMNSTORE INDEX, DISTRIBUTION = ROUND_ROBIN); \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Global.asax b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Global.asax new file mode 100644 index 000000000..21d85acb9 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="ManagedIdentityWebApp.Global" Language="C#" %> diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Global.asax.cs b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Global.asax.cs new file mode 100644 index 000000000..e483b9141 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Global.asax.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Security; +using System.Web.SessionState; + +namespace ManagedIdentityWebApp +{ + public class Global : System.Web.HttpApplication + { + protected void Application_Start(object sender, EventArgs e) + { + } + } +} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj new file mode 100644 index 000000000..db4d39fe9 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj @@ -0,0 +1,277 @@ + + + + + Debug + AnyCPU + + + 2.0 + {476F98B4-05BF-42B6-B0B4-E50CD5B71635} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + ManagedIdentityWebApp + ManagedIdentityWebApp + v4.7.2 + true + + + + + + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + 8.0 + + + true + pdbonly + true + bin\ + TRACE + prompt + 4 + 8.0 + + + + packages\Azure.Core.1.0.0-preview.9\lib\netstandard2.0\Azure.Core.dll + + + packages\Azure.Identity.1.0.0-preview.5\lib\netstandard2.0\Azure.Identity.dll + + + packages\Azure.Messaging.EventHubs.5.0.0-preview.4\lib\netstandard2.0\Azure.Messaging.EventHubs.dll + + + packages\Microsoft.Azure.Amqp.2.4.3\lib\net45\Microsoft.Azure.Amqp.dll + + + packages\Microsoft.Azure.Services.AppAuthentication.1.2.1\lib\net472\Microsoft.Azure.Services.AppAuthentication.dll + + + packages\Microsoft.Bcl.AsyncInterfaces.1.0.0-rc1.19456.4\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll + + + + packages\Microsoft.Identity.Client.4.1.0\lib\net45\Microsoft.Identity.Client.dll + + + packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll + + + packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll + + + packages\Microsoft.IdentityModel.JsonWebTokens.5.5.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll + + + packages\Microsoft.IdentityModel.Logging.5.5.0\lib\net461\Microsoft.IdentityModel.Logging.dll + + + packages\Microsoft.IdentityModel.Tokens.5.5.0\lib\net461\Microsoft.IdentityModel.Tokens.dll + + + packages\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll + + + packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll + + + + + packages\System.Diagnostics.DiagnosticSource.4.6.0-rc1.19456.4\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + + packages\System.IdentityModel.Tokens.Jwt.5.5.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll + + + packages\System.IO.4.3.0\lib\net462\System.IO.dll + True + True + + + packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + + packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll + True + True + + + packages\System.Net.WebSockets.4.0.0\lib\net46\System.Net.WebSockets.dll + True + True + + + packages\System.Net.WebSockets.Client.4.0.2\lib\net46\System.Net.WebSockets.Client.dll + True + True + + + + packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + packages\System.Reflection.TypeExtensions.4.5.1\lib\net461\System.Reflection.TypeExtensions.dll + + + packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll + True + True + + + packages\System.Runtime.CompilerServices.Unsafe.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + + packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll + True + True + + + + packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll + True + True + + + packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll + True + True + + + packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + True + True + + + packages\System.Security.Cryptography.ProtectedData.4.5.0\lib\net461\System.Security.Cryptography.ProtectedData.dll + + + packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + True + True + + + + packages\System.Text.Encodings.Web.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Text.Encodings.Web.dll + + + packages\System.Text.Json.4.6.0-rc1.19456.4\lib\net461\System.Text.Json.dll + + + packages\System.Threading.Channels.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Threading.Channels.dll + + + packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + + + packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll + + + + + + + + + + + + + + + + + + + + + + Web.config + + + Web.config + + + + + + + + Designer + + + + + SendReceive.aspx + ASPXCodeBehind + + + SendReceive.aspx + + + Global.asax + + + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + True + True + 56779 + / + http://localhost:56779/ + False + False + + + False + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.sln b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.sln new file mode 100644 index 000000000..99d261930 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27004.2010 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedIdentityWebApp", "ManagedIdentityWebApp.csproj", "{476F98B4-05BF-42B6-B0B4-E50CD5B71635}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {476F98B4-05BF-42B6-B0B4-E50CD5B71635}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {476F98B4-05BF-42B6-B0B4-E50CD5B71635}.Debug|Any CPU.Build.0 = Debug|Any CPU + {476F98B4-05BF-42B6-B0B4-E50CD5B71635}.Release|Any CPU.ActiveCfg = Release|Any CPU + {476F98B4-05BF-42B6-B0B4-E50CD5B71635}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AE17B842-5FBE-4C43-B583-5441703DBCE9} + EndGlobalSection +EndGlobal diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Properties/AssemblyInfo.cs b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..eb184e7ac --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ManagedIdentityWebApp")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ManagedIdentityWebApp")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("476f98b4-05bf-42b6-b0b4-e50cd5b71635")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/README.md b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/README.md new file mode 100644 index 000000000..febc4f8fc --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/README.md @@ -0,0 +1,4 @@ +# Managed Service Identity sample # + +For more information on Managed Service Identity (MSI) and how to run this sample follow [this](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-managed-service-identity) link. + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx new file mode 100644 index 000000000..2e946357d --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx @@ -0,0 +1,32 @@ +<%@ Page Async="true" Language="C#" AutoEventWireup="true" CodeBehind="SendReceive.aspx.cs" Inherits="ManagedIdentityWebApp.SendReceive" %> + + + + + + EventHubs Managed Identity Demo + + + +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+
+ + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs new file mode 100644 index 000000000..d738e3226 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs @@ -0,0 +1,56 @@ +using System; +using System.Linq; +using System.Text; +using System.Threading; +using Azure.Messaging.EventHubs; +using Azure.Identity; + +// Always add app to IAM roles +// Don't use on deployment slots but only on root +namespace ManagedIdentityWebApp +{ + public partial class SendReceive : System.Web.UI.Page + { + protected void Page_Load(object sender, EventArgs e) + { + + } + + protected async void btnSend_Click(object sender, EventArgs e) + { + EventHubClient client = new EventHubClient($"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential()); + await using (EventHubProducer producer = client.CreateProducer()) + { + var eventsToPublish = new EventData[] + { + new EventData(Encoding.UTF8.GetBytes(txtData.Text)) + }; + + await producer.SendAsync(eventsToPublish); + txtOutput.Text = $"{DateTime.Now} - SENT{Environment.NewLine}" + txtOutput.Text; + } + } + + protected async void btnReceive_Click(object sender, EventArgs e) + { + EventHubClient client = new EventHubClient($"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential()); + string firstPartition = (await client.GetPartitionIdsAsync()).First(); + var totalReceived = 0; + var receiver = client.CreateConsumer(EventHubConsumer.DefaultConsumerGroupName, firstPartition, EventPosition.Earliest); + var messages = receiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(15)).GetAwaiter().GetResult(); + + if (messages != null) + { + foreach (var message in messages) + { + txtOutput.Text = $"{DateTime.Now} - RECEIVED PartitionId: {firstPartition} data:{Encoding.UTF8.GetString(message.Body.ToArray())}{Environment.NewLine}" + txtOutput.Text; + } + + Interlocked.Add(ref totalReceived, messages.Count()); + } + + receiver.Close(); + txtOutput.Text = $"{DateTime.Now} - RECEIVED TOTAL = {totalReceived}{Environment.NewLine}" + txtOutput.Text; + } + } +} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.designer.cs b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.designer.cs new file mode 100644 index 000000000..f376bf7cf --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.designer.cs @@ -0,0 +1,89 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ManagedIdentityWebApp +{ + + + public partial class SendReceive + { + + /// + /// form1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlForm form1; + + /// + /// txtNamespace control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox txtNamespace; + + /// + /// txtEventHub control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox txtEventHub; + + /// + /// txtData control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox txtData; + + /// + /// btnSend control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnSend; + + /// + /// btnReceive control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnReceive; + + /// + /// txtOutput control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox txtOutput; + + /// + /// hiddenStartingOffset control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.HiddenField hiddenStartingOffset; + } +} diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/StyleSheet.css b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/StyleSheet.css new file mode 100644 index 000000000..18b4dd479 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/StyleSheet.css @@ -0,0 +1,13 @@ +label { + width: 200px; + display: inline-block; +} + +text { + width: 300px; + display: block; +} + +input[type="submit"] { + width: 75px; +} diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.Debug.config b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.Debug.config new file mode 100644 index 000000000..fae9cfefa --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.Release.config b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.Release.config new file mode 100644 index 000000000..da6e960b8 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.config b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.config new file mode 100644 index 000000000..cf90ba0bc --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.config @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config new file mode 100644 index 000000000..6d59be556 --- /dev/null +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 17f6cebc3da32d8cb302d80798772298844a3cc4 Mon Sep 17 00:00:00 2001 From: spelluru Date: Tue, 5 Nov 2019 12:13:00 -0500 Subject: [PATCH 29/66] updated Anomaly Detector and Wind Turbine Data Generator samples for Preview 5 --- .../AnomalyDetector/Producer/Producer.csproj | 2 +- .../AnomalyDetector/Producer/Program.cs | 13 +++++-------- .../WindTurbineDataGenerator/Program.cs | 13 +++++-------- .../WindTurbineDataGenerator.csproj | 10 +++++----- .../WindTurbineDataGenerator/packages.config | 10 +++++----- 5 files changed, 21 insertions(+), 27 deletions(-) diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj index be1913da2..720bc8587 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs index e2b567055..bcdb8f6b8 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs @@ -18,7 +18,7 @@ public class Program private const string TransactionsDumpFile = "mocktransactions.csv"; - private static EventHubClient eventHubClient; + private static EventHubProducerClient producerClient; public static int Main(string[] args) { @@ -27,13 +27,13 @@ public static int Main(string[] args) private static async Task MainAsync(string[] args) { - // create an Event Hubs client using the namespace connection string and the event hub name - eventHubClient = new EventHubClient(EventHubConnectionString, EventHubName); + // create an Event Hubs Producer client using the namespace connection string and the event hub name + producerClient = new EventHubProducerClient(EventHubConnectionString, EventHubName); // send messages to the event hub await SendMessagesToEventHubAsync(1000); - await eventHubClient.CloseAsync(); + await producerClient.CloseAsync(); Console.WriteLine("Press [enter] to exit."); Console.ReadLine(); @@ -58,9 +58,6 @@ private static async Task SendMessagesToEventHubAsync(int numMessagesToSend) TransactionsDumpFile, $"CreditCardId,Timestamp,Location,Amount,Type{Environment.NewLine}"); - // create a producer object that you can use to produce or send messages to the event hub - EventHubProducer producer = eventHubClient.CreateProducer(); - foreach (var t in transactions) { try @@ -92,7 +89,7 @@ private static async Task SendMessagesToEventHubAsync(int numMessagesToSend) var ed = new EventData(Encoding.UTF8.GetBytes(message)); // send the message to the event hub using the producer object - await producer.SendAsync(ed); + await producerClient.SendAsync(ed); } catch (Exception ex) { diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs index abbcf606e..9ee778214 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs @@ -13,9 +13,9 @@ namespace WindTurbineDataGenerator internal class Program { private const string EventHubConnectionString = - "[provide the EH connection string]"; + ""; - private const string EventHubName = "[provide the EH name]"; + private const string EventHubName = ""; private static int Main(string[] args) { @@ -39,11 +39,8 @@ private static async Task StartEventGenerationAsync(CancellationToken cancellati { var random = new Random((int)DateTimeOffset.UtcNow.Ticks); - // create an Event Hubs client using the namespace connection string and the event hub name - EventHubClient client = new EventHubClient(EventHubConnectionString, EventHubName); - - // create a producer object to send messages to the event hub - EventHubProducer producer = client.CreateProducer(); + // create an Event Hubs Producer client using the namespace connection string and the event hub name + EventHubProducerClient producerClient = new EventHubProducerClient(EventHubConnectionString, EventHubName); while (!cancellationToken.IsCancellationRequested) { @@ -63,7 +60,7 @@ private static async Task StartEventGenerationAsync(CancellationToken cancellati Console.Write("."); // send the message to the event hub - await producer.SendAsync(devicesData); + await producerClient.SendAsync(devicesData); } catch (Exception ex) { diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj index 9e5da2d22..e2db9aa27 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj @@ -33,10 +33,10 @@ - ..\packages\Azure.Core.1.0.0-preview.9\lib\netstandard2.0\Azure.Core.dll + ..\packages\Azure.Core.1.0.0\lib\netstandard2.0\Azure.Core.dll - ..\packages\Azure.Messaging.EventHubs.5.0.0-preview.4\lib\netstandard2.0\Azure.Messaging.EventHubs.dll + ..\packages\Azure.Messaging.EventHubs.5.0.0-preview.5\lib\netstandard2.0\Azure.Messaging.EventHubs.dll ..\packages\Microsoft.Azure.Amqp.2.4.2\lib\net45\Microsoft.Azure.Amqp.dll @@ -45,7 +45,7 @@ ..\packages\Microsoft.Azure.EventHubs.1.0.2\lib\net451\Microsoft.Azure.EventHubs.dll - ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0-rc1.19456.4\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll @@ -56,7 +56,7 @@ - ..\packages\System.Diagnostics.DiagnosticSource.4.6.0-rc1.19456.4\lib\net46\System.Diagnostics.DiagnosticSource.dll + ..\packages\System.Diagnostics.DiagnosticSource.4.6.0\lib\net46\System.Diagnostics.DiagnosticSource.dll ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll @@ -108,7 +108,7 @@ True - ..\packages\System.Threading.Channels.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Threading.Channels.dll + ..\packages\System.Threading.Channels.4.6.0\lib\netstandard2.0\System.Threading.Channels.dll ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config index 3a3e6b5ca..d6a2279f3 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config @@ -1,13 +1,13 @@  - - + + - + - + @@ -19,6 +19,6 @@ - + \ No newline at end of file From a4354c1d57e5f59ccfcb32d1d49865f1d9e9189f Mon Sep 17 00:00:00 2001 From: spelluru Date: Thu, 5 Dec 2019 17:30:57 -0500 Subject: [PATCH 30/66] updated Anomaly Detector and WindTurbineDataGenerator samples for Preview 6: --- .../AnomalyDetector/Producer/Producer.csproj | 2 +- .../AnomalyDetector/Producer/Program.cs | 14 +-- .../WindTurbineDataGenerator/Program.cs | 13 +-- .../WindTurbineDataGenerator.csproj | 6 +- .../WindTurbineDataGenerator/packages.config | 4 +- .../ManagedIdentityWebApp.csproj | 101 +++++++++--------- .../ManagedIdentityWebApp/SendReceive.aspx.cs | 38 ++++--- .../ManagedIdentityWebApp/Web.config | 38 ++++++- .../ManagedIdentityWebApp/packages.config | 52 ++++----- 9 files changed, 152 insertions(+), 116 deletions(-) diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj index 720bc8587..be2d08245 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs index bcdb8f6b8..fdfca5d5b 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs @@ -13,19 +13,17 @@ namespace Producer public class Program { private const string EventHubConnectionString = ""; - private const string EventHubName = ""; - private const string TransactionsDumpFile = "mocktransactions.csv"; private static EventHubProducerClient producerClient; - public static int Main(string[] args) + public static int Main() { - return MainAsync(args).GetAwaiter().GetResult(); + return MainAsync().GetAwaiter().GetResult(); } - private static async Task MainAsync(string[] args) + private static async Task MainAsync() { // create an Event Hubs Producer client using the namespace connection string and the event hub name producerClient = new EventHubProducerClient(EventHubConnectionString, EventHubName); @@ -86,10 +84,12 @@ private static async Task SendMessagesToEventHubAsync(int numMessagesToSend) File.AppendAllText(TransactionsDumpFile, line); - var ed = new EventData(Encoding.UTF8.GetBytes(message)); + // prepare a batch of events to send to the event hub. only one event in this case. + EventDataBatch eventBatch = await producerClient.CreateBatchAsync(); + eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes(message))); // send the message to the event hub using the producer object - await producerClient.SendAsync(ed); + await producerClient.SendAsync(eventBatch); } catch (Exception ex) { diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs index 9ee778214..f054161bf 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs @@ -17,7 +17,7 @@ internal class Program private const string EventHubName = ""; - private static int Main(string[] args) + private static int Main() { Console.WriteLine("Starting wind turbine generator. Press to exit"); @@ -47,20 +47,21 @@ private static async Task StartEventGenerationAsync(CancellationToken cancellati try { // Simulate sending data from 100 weather sensors - var devicesData = new List(); - + // prepare a batch of events to send to the event hub. + EventDataBatch eventBatch = await producerClient.CreateBatchAsync(); for (int i = 0; i < 100; i++) { int scaleFactor = random.Next(0, 25); var windTurbineMeasure = GenerateTurbineMeasure("Turbine_" + i, scaleFactor); EventData evData = SerializeWindTurbineToEventData(windTurbineMeasure); - devicesData.Add(evData); + // add the event to the batch + eventBatch.TryAdd(evData); } Console.Write("."); - // send the message to the event hub - await producerClient.SendAsync(devicesData); + // send the batch of events to the event hub + await producerClient.SendAsync(eventBatch); } catch (Exception ex) { diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj index e2db9aa27..e0b22bb67 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj @@ -32,11 +32,11 @@ 4 - - ..\packages\Azure.Core.1.0.0\lib\netstandard2.0\Azure.Core.dll + + ..\packages\Azure.Core.1.0.1\lib\netstandard2.0\Azure.Core.dll - ..\packages\Azure.Messaging.EventHubs.5.0.0-preview.5\lib\netstandard2.0\Azure.Messaging.EventHubs.dll + ..\packages\Azure.Messaging.EventHubs.5.0.0-preview.6\lib\netstandard2.0\Azure.Messaging.EventHubs.dll ..\packages\Microsoft.Azure.Amqp.2.4.2\lib\net45\Microsoft.Azure.Amqp.dll diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config index d6a2279f3..796884c48 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config @@ -1,7 +1,7 @@  - - + + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj index db4d39fe9..df52c2e3d 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj @@ -46,60 +46,57 @@ 8.0 - - packages\Azure.Core.1.0.0-preview.9\lib\netstandard2.0\Azure.Core.dll + + packages\Azure.Core.1.0.1\lib\netstandard2.0\Azure.Core.dll - - packages\Azure.Identity.1.0.0-preview.5\lib\netstandard2.0\Azure.Identity.dll + + packages\Azure.Identity.1.1.0\lib\netstandard2.0\Azure.Identity.dll - packages\Azure.Messaging.EventHubs.5.0.0-preview.4\lib\netstandard2.0\Azure.Messaging.EventHubs.dll + packages\Azure.Messaging.EventHubs.5.0.0-preview.5\lib\netstandard2.0\Azure.Messaging.EventHubs.dll packages\Microsoft.Azure.Amqp.2.4.3\lib\net45\Microsoft.Azure.Amqp.dll - - packages\Microsoft.Azure.Services.AppAuthentication.1.2.1\lib\net472\Microsoft.Azure.Services.AppAuthentication.dll + + packages\Microsoft.Azure.Services.AppAuthentication.1.3.1\lib\net472\Microsoft.Azure.Services.AppAuthentication.dll - packages\Microsoft.Bcl.AsyncInterfaces.1.0.0-rc1.19456.4\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + packages\Microsoft.Bcl.AsyncInterfaces.1.1.0-preview3.19551.4\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll - - packages\Microsoft.Identity.Client.4.1.0\lib\net45\Microsoft.Identity.Client.dll + + packages\Microsoft.Identity.Client.4.7.1\lib\net45\Microsoft.Identity.Client.dll - - packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll + + packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll - - packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll + + packages\Microsoft.IdentityModel.JsonWebTokens.5.6.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll - - packages\Microsoft.IdentityModel.JsonWebTokens.5.5.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll + + packages\Microsoft.IdentityModel.Logging.5.6.0\lib\net461\Microsoft.IdentityModel.Logging.dll - - packages\Microsoft.IdentityModel.Logging.5.5.0\lib\net461\Microsoft.IdentityModel.Logging.dll + + packages\Microsoft.IdentityModel.Tokens.5.6.0\lib\net461\Microsoft.IdentityModel.Tokens.dll - - packages\Microsoft.IdentityModel.Tokens.5.5.0\lib\net461\Microsoft.IdentityModel.Tokens.dll - - - packages\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll + + packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll - - packages\System.Diagnostics.DiagnosticSource.4.6.0-rc1.19456.4\lib\net46\System.Diagnostics.DiagnosticSource.dll + + packages\System.Diagnostics.DiagnosticSource.4.7.0-preview3.19551.4\lib\net46\System.Diagnostics.DiagnosticSource.dll - - packages\System.IdentityModel.Tokens.Jwt.5.5.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll + + packages\System.IdentityModel.Tokens.Jwt.5.6.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll packages\System.IO.4.3.0\lib\net462\System.IO.dll @@ -114,30 +111,30 @@ True True - - packages\System.Net.WebSockets.4.0.0\lib\net46\System.Net.WebSockets.dll + + packages\System.Net.WebSockets.4.3.0\lib\net46\System.Net.WebSockets.dll True True - - packages\System.Net.WebSockets.Client.4.0.2\lib\net46\System.Net.WebSockets.Client.dll + + packages\System.Net.WebSockets.Client.4.3.2\lib\net46\System.Net.WebSockets.Client.dll True True - - packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + packages\System.Numerics.Vectors.4.6.0-preview5.19224.8\lib\net46\System.Numerics.Vectors.dll - - packages\System.Reflection.TypeExtensions.4.5.1\lib\net461\System.Reflection.TypeExtensions.dll + + packages\System.Reflection.TypeExtensions.4.7.0-preview3.19551.4\lib\net461\System.Reflection.TypeExtensions.dll - - packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll + + packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll True True - - packages\System.Runtime.CompilerServices.Unsafe.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + packages\System.Runtime.CompilerServices.Unsafe.4.7.0-preview3.19551.4\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll @@ -147,7 +144,7 @@ - packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll + packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net463\System.Security.Cryptography.Algorithms.dll True True @@ -161,26 +158,26 @@ True True - - packages\System.Security.Cryptography.ProtectedData.4.5.0\lib\net461\System.Security.Cryptography.ProtectedData.dll + + packages\System.Security.Cryptography.ProtectedData.4.7.0-preview3.19551.4\lib\net461\System.Security.Cryptography.ProtectedData.dll - - packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + + packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll True True - - packages\System.Text.Encodings.Web.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Text.Encodings.Web.dll + + packages\System.Text.Encodings.Web.4.7.0-preview3.19551.4\lib\netstandard2.0\System.Text.Encodings.Web.dll - - packages\System.Text.Json.4.6.0-rc1.19456.4\lib\net461\System.Text.Json.dll + + packages\System.Text.Json.4.7.0-preview3.19551.4\lib\net461\System.Text.Json.dll - - packages\System.Threading.Channels.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Threading.Channels.dll + + packages\System.Threading.Channels.4.7.0-preview3.19551.4\lib\netstandard2.0\System.Threading.Channels.dll - - packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + + packages\System.Threading.Tasks.Extensions.4.6.0-preview.18571.3\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs index d738e3226..373a44467 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs @@ -18,8 +18,7 @@ protected void Page_Load(object sender, EventArgs e) protected async void btnSend_Click(object sender, EventArgs e) { - EventHubClient client = new EventHubClient($"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential()); - await using (EventHubProducer producer = client.CreateProducer()) + await using (EventHubProducerClient producer = new EventHubProducerClient($"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential())) { var eventsToPublish = new EventData[] { @@ -33,24 +32,31 @@ protected async void btnSend_Click(object sender, EventArgs e) protected async void btnReceive_Click(object sender, EventArgs e) { - EventHubClient client = new EventHubClient($"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential()); - string firstPartition = (await client.GetPartitionIdsAsync()).First(); - var totalReceived = 0; - var receiver = client.CreateConsumer(EventHubConsumer.DefaultConsumerGroupName, firstPartition, EventPosition.Earliest); - var messages = receiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(15)).GetAwaiter().GetResult(); - - if (messages != null) + await using (EventHubConsumerClient consumerClient = new EventHubConsumerClient("$Default", "0", EventPosition.Earliest, $"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential())) { - foreach (var message in messages) + string firstPartition = (await consumerClient.GetPartitionIdsAsync()).First(); + } + + /* + EventHubConsumerClient receiver = new EventHubConsumerClient("$Default", "0", EventPosition.Earliest, $"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential()); + + string firstPartition = "0"; + var totalReceived = 0; + var messages = receiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(15)).GetAwaiter().GetResult(); + + if (messages != null) { - txtOutput.Text = $"{DateTime.Now} - RECEIVED PartitionId: {firstPartition} data:{Encoding.UTF8.GetString(message.Body.ToArray())}{Environment.NewLine}" + txtOutput.Text; + foreach (var message in messages) + { + txtOutput.Text = $"{DateTime.Now} - RECEIVED PartitionId: {firstPartition} data:{Encoding.UTF8.GetString(message.Body.ToArray())}{Environment.NewLine}" + txtOutput.Text; + } + + Interlocked.Add(ref totalReceived, messages.Count()); } - Interlocked.Add(ref totalReceived, messages.Count()); + receiver.Close(); + txtOutput.Text = $"{DateTime.Now} - RECEIVED TOTAL = {totalReceived}{Environment.NewLine}" + txtOutput.Text; + */ } - - receiver.Close(); - txtOutput.Text = $"{DateTime.Now} - RECEIVED TOTAL = {totalReceived}{Environment.NewLine}" + txtOutput.Text; - } } } \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.config b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.config index cf90ba0bc..59ccd8c22 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.config +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/Web.config @@ -21,7 +21,7 @@ - + @@ -37,7 +37,7 @@ - + @@ -49,12 +49,44 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config index 6d59be556..c1c96527f 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config @@ -1,40 +1,40 @@  - - - + + + - - + + - - - - - - + + + + + + - - + + - - - - - - + + + + + + - + - - - - - - + + + + + + \ No newline at end of file From 2be764e70f34bab33b8917cddf9c1d45a24e4f5a Mon Sep 17 00:00:00 2001 From: spelluru Date: Fri, 6 Dec 2019 12:25:34 -0500 Subject: [PATCH 31/66] updated for Preview 6 --- .../ManagedIdentityWebApp.csproj | 19 +++---- .../ManagedIdentityWebApp/SendReceive.aspx.cs | 51 +++++++++---------- .../ManagedIdentityWebApp/packages.config | 18 +++---- 3 files changed, 43 insertions(+), 45 deletions(-) diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj index df52c2e3d..565dbf00d 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj @@ -53,7 +53,7 @@ packages\Azure.Identity.1.1.0\lib\netstandard2.0\Azure.Identity.dll - packages\Azure.Messaging.EventHubs.5.0.0-preview.5\lib\netstandard2.0\Azure.Messaging.EventHubs.dll + packages\Azure.Messaging.EventHubs.5.0.0-preview.6\lib\netstandard2.0\Azure.Messaging.EventHubs.dll packages\Microsoft.Azure.Amqp.2.4.3\lib\net45\Microsoft.Azure.Amqp.dll @@ -62,7 +62,7 @@ packages\Microsoft.Azure.Services.AppAuthentication.1.3.1\lib\net472\Microsoft.Azure.Services.AppAuthentication.dll - packages\Microsoft.Bcl.AsyncInterfaces.1.1.0-preview3.19551.4\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll @@ -92,7 +92,7 @@ - packages\System.Diagnostics.DiagnosticSource.4.7.0-preview3.19551.4\lib\net46\System.Diagnostics.DiagnosticSource.dll + packages\System.Diagnostics.DiagnosticSource.4.7.0\lib\net46\System.Diagnostics.DiagnosticSource.dll @@ -126,7 +126,7 @@ packages\System.Numerics.Vectors.4.6.0-preview5.19224.8\lib\net46\System.Numerics.Vectors.dll - packages\System.Reflection.TypeExtensions.4.7.0-preview3.19551.4\lib\net461\System.Reflection.TypeExtensions.dll + packages\System.Reflection.TypeExtensions.4.7.0\lib\net461\System.Reflection.TypeExtensions.dll packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll @@ -134,7 +134,7 @@ True - packages\System.Runtime.CompilerServices.Unsafe.4.7.0-preview3.19551.4\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll @@ -159,7 +159,7 @@ True - packages\System.Security.Cryptography.ProtectedData.4.7.0-preview3.19551.4\lib\net461\System.Security.Cryptography.ProtectedData.dll + packages\System.Security.Cryptography.ProtectedData.4.7.0\lib\net461\System.Security.Cryptography.ProtectedData.dll packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll @@ -168,13 +168,13 @@ - packages\System.Text.Encodings.Web.4.7.0-preview3.19551.4\lib\netstandard2.0\System.Text.Encodings.Web.dll + packages\System.Text.Encodings.Web.4.7.0\lib\netstandard2.0\System.Text.Encodings.Web.dll - packages\System.Text.Json.4.7.0-preview3.19551.4\lib\net461\System.Text.Json.dll + packages\System.Text.Json.4.7.0\lib\net461\System.Text.Json.dll - packages\System.Threading.Channels.4.7.0-preview3.19551.4\lib\netstandard2.0\System.Threading.Channels.dll + packages\System.Threading.Channels.4.7.0\lib\netstandard2.0\System.Threading.Channels.dll packages\System.Threading.Tasks.Extensions.4.6.0-preview.18571.3\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll @@ -201,6 +201,7 @@ + Web.config diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs index 373a44467..c092bb6c5 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs @@ -4,6 +4,7 @@ using System.Threading; using Azure.Messaging.EventHubs; using Azure.Identity; +using System.Threading.Tasks; // Always add app to IAM roles // Don't use on deployment slots but only on root @@ -18,45 +19,41 @@ protected void Page_Load(object sender, EventArgs e) protected async void btnSend_Click(object sender, EventArgs e) { - await using (EventHubProducerClient producer = new EventHubProducerClient($"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential())) + await using (EventHubProducerClient producerClient = new EventHubProducerClient($"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential())) { - var eventsToPublish = new EventData[] - { - new EventData(Encoding.UTF8.GetBytes(txtData.Text)) - }; + // create a batch + EventDataBatch eventBatch = await producerClient.CreateBatchAsync(); + + // add events to the batch. only one in this case. + eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes(txtData.Text))); + + // send the batch to the event hub + await producerClient.SendAsync(eventBatch); - await producer.SendAsync(eventsToPublish); txtOutput.Text = $"{DateTime.Now} - SENT{Environment.NewLine}" + txtOutput.Text; } } - protected async void btnReceive_Click(object sender, EventArgs e) { - await using (EventHubConsumerClient consumerClient = new EventHubConsumerClient("$Default", "0", EventPosition.Earliest, $"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential())) + await using (var consumerClient = new EventHubConsumerClient(EventHubConsumerClient.DefaultConsumerGroupName, $"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential())) { - string firstPartition = (await consumerClient.GetPartitionIdsAsync()).First(); - } - - /* - EventHubConsumerClient receiver = new EventHubConsumerClient("$Default", "0", EventPosition.Earliest, $"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential()); - - string firstPartition = "0"; - var totalReceived = 0; - var messages = receiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(15)).GetAwaiter().GetResult(); - - if (messages != null) + int eventsRead = 0; + try { - foreach (var message in messages) + using CancellationTokenSource cancellationSource = new CancellationTokenSource(); + cancellationSource.CancelAfter(TimeSpan.FromSeconds(5)); + + await foreach (PartitionEvent partitionEvent in consumerClient.ReadEventsAsync(cancellationSource.Token)) { - txtOutput.Text = $"{DateTime.Now} - RECEIVED PartitionId: {firstPartition} data:{Encoding.UTF8.GetString(message.Body.ToArray())}{Environment.NewLine}" + txtOutput.Text; + txtOutput.Text = $"Event Read: { Encoding.UTF8.GetString(partitionEvent.Data.Body.ToArray()) }{ Environment.NewLine}" + txtOutput.Text; + eventsRead++; } - - Interlocked.Add(ref totalReceived, messages.Count()); } - - receiver.Close(); - txtOutput.Text = $"{DateTime.Now} - RECEIVED TOTAL = {totalReceived}{Environment.NewLine}" + txtOutput.Text; - */ + catch (TaskCanceledException ex) + { + txtOutput.Text = $"Number of events read: {eventsRead}{ Environment.NewLine}" + txtOutput.Text; + } } + } } } \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config index c1c96527f..b8766ff84 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config @@ -2,11 +2,11 @@ - + - + @@ -15,7 +15,7 @@ - + @@ -23,18 +23,18 @@ - + - + - + - - - + + + \ No newline at end of file From 78ec550eca907c069a2f213f68272b611f40a102 Mon Sep 17 00:00:00 2001 From: spelluru Date: Thu, 9 Jan 2020 16:17:16 -0500 Subject: [PATCH 32/66] updated based on feedback from Serkant and Jesse --- .../AnomalyDetector/Producer/Producer.csproj | 2 +- .../AnomalyDetector/Producer/Program.cs | 47 +++++++++---------- .../DWDumper/App.config | 14 +++++- .../DWDumper/DWDumper.csproj | 40 ++++++++++++++-- .../DWDumper/Program.cs | 38 ++++++++------- .../DWDumper/WindTurbineMeasure.cs | 4 +- .../DWDumper/packages.config | 14 +++++- .../FunctionEGDWDumper/EventGridEvent.cs | 3 ++ .../FunctionEGDWDumper/Function1.cs | 24 +++++----- .../FunctionEGDWDumper.csproj | 4 +- .../FunctionEGDWDumper/WindTurbineMeasure.cs | 6 ++- .../WindTurbineDataGenerator/Program.cs | 31 ++++++------ .../WindTurbineDataGenerator.csproj | 4 +- .../WindTurbineMeasure.cs | 5 +- .../WindTurbineDataGenerator/packages.config | 2 +- .../ManagedIdentityWebApp.csproj | 18 ------- .../ManagedIdentityWebApp/SendReceive.aspx | 2 +- .../ManagedIdentityWebApp/SendReceive.aspx.cs | 21 +++++---- .../ManagedIdentityWebApp/packages.config | 7 --- 19 files changed, 166 insertions(+), 120 deletions(-) diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj index be2d08245..2dd5143ad 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs index fdfca5d5b..e2dbf94df 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs @@ -11,22 +11,17 @@ namespace Producer using System.IO; public class Program - { - private const string EventHubConnectionString = ""; + { + private const string EventHubNamespaceConnectionString = ""; private const string EventHubName = ""; private const string TransactionsDumpFile = "mocktransactions.csv"; private static EventHubProducerClient producerClient; - public static int Main() - { - return MainAsync().GetAwaiter().GetResult(); - } - - private static async Task MainAsync() + static async Task Main() { // create an Event Hubs Producer client using the namespace connection string and the event hub name - producerClient = new EventHubProducerClient(EventHubConnectionString, EventHubName); + producerClient = new EventHubProducerClient(EventHubNamespaceConnectionString, EventHubName); // send messages to the event hub await SendMessagesToEventHubAsync(1000); @@ -35,8 +30,6 @@ private static async Task MainAsync() Console.WriteLine("Press [enter] to exit."); Console.ReadLine(); - - return 0; } // Creates an Event Hub client and sends messages to the event hub. @@ -52,19 +45,22 @@ private static async Task SendMessagesToEventHubAsync(int numMessagesToSend) File.Delete(TransactionsDumpFile); } - File.AppendAllText( + await File.AppendAllTextAsync( TransactionsDumpFile, $"CreditCardId,Timestamp,Location,Amount,Type{Environment.NewLine}"); - foreach (var t in transactions) + int numSuccessfulMessages = 0; + try { - try + // create a batch using the producer client + EventDataBatch eventBatch = await producerClient.CreateBatchAsync(); + foreach (var t in transactions) { // we don't send the transaction type as part of the message. // that is up to the downstream analytics to figure out! // we just pretty print them here so they can easily be compared with the downstream // analytics results. - var message = t.Data.ToJson(); + var message = t.Data.ToJson(); if (t.Type == TransactionType.Suspect) { @@ -84,22 +80,21 @@ private static async Task SendMessagesToEventHubAsync(int numMessagesToSend) File.AppendAllText(TransactionsDumpFile, line); - // prepare a batch of events to send to the event hub. only one event in this case. - EventDataBatch eventBatch = await producerClient.CreateBatchAsync(); + // add the message to the batch eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes(message))); - - // send the message to the event hub using the producer object - await producerClient.SendAsync(eventBatch); - } - catch (Exception ex) - { - Console.WriteLine($"{t.ToJson()}{Environment.NewLine}Exception: {ex.Message}"); + numSuccessfulMessages++; } + // send the batch of messages to the event hub using the producer object + await producerClient.SendAsync(eventBatch); await Task.Delay(10); } - - Console.WriteLine($"{numMessagesToSend} messages sent."); + catch (Exception ex) + { + Console.WriteLine($"{Environment.NewLine}Exception: {ex.Message}"); + } + Console.WriteLine(); + Console.WriteLine($"{numSuccessfulMessages} messages sent successfully."); } } } diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/App.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/App.config index 390b41521..85ce03b61 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/App.config +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/App.config @@ -7,7 +7,19 @@ - + + + + + + + + + + + + + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj index b947b0d03..0a5934ba9 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj @@ -35,12 +35,24 @@ ..\packages\Apache.Avro.1.7.7.2\lib\Avro.dll + + ..\packages\Azure.Core.1.0.1\lib\netstandard2.0\Azure.Core.dll + + + ..\packages\Azure.Storage.Blobs.12.1.0\lib\netstandard2.0\Azure.Storage.Blobs.dll + + + ..\packages\Azure.Storage.Common.12.1.0\lib\netstandard2.0\Azure.Storage.Common.dll + ..\packages\log4net.1.2.10\lib\2.0\log4net.dll ..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll + + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + ..\packages\Microsoft.Data.Edm.5.8.2\lib\net40\Microsoft.Data.Edm.dll @@ -50,18 +62,36 @@ ..\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll - - ..\packages\WindowsAzure.Storage.8.3.0\lib\net45\Microsoft.WindowsAzure.Storage.dll + + ..\packages\WindowsAzure.Storage.9.3.3\lib\net45\Microsoft.WindowsAzure.Storage.dll - - ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll - True + + ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll + + ..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll + + + ..\packages\System.Diagnostics.DiagnosticSource.4.6.0\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Spatial.5.8.2\lib\net40\System.Spatial.dll + + ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs index 2b9e73718..12ca9b714 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs @@ -1,17 +1,18 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.SqlClient; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Avro.File; -using Avro.Generic; -using Newtonsoft.Json; -using Microsoft.WindowsAzure.Storage; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. namespace DWDumper { + using System; + using System.Data; + using System.Data.SqlClient; + using System.Text; + using Avro.File; + using Avro.Generic; + using Newtonsoft.Json; + using Azure.Storage.Blobs; + using System.IO; + /// /// A simple test program to dump a single Avro blob file created by EventHubs Capture into a SQL data warehouse (DW). /// This is useful for testing connections with your SQL DW before integrating this DW dumping code with Azure Functions @@ -19,9 +20,11 @@ namespace DWDumper class Program { private const string StorageConnectionString = "[provide your storage connection string]"; - private const string EventHubsCaptureAvroBlobUri = "[provide the blob path to a single blob file just to test if it can be parsed and dumped to the DW]"; + private const string EventHubsCaptureAvroBlobContainer = "<< Blobs container>>"; + private const string EventHubsCaptureAvroBlobName = "<>"; private const string SqlDwConnection = "[provide the SQL DW connection string]"; + private static int Main(string[] args) { var p = new Program(); @@ -33,14 +36,17 @@ private static int Main(string[] args) public void Dump() { // Get the blob reference - var storageAccount = CloudStorageAccount.Parse(StorageConnectionString); - var blobClient = storageAccount.CreateCloudBlobClient(); - var blob = blobClient.GetBlobReferenceFromServer(new Uri(EventHubsCaptureAvroBlobUri)); + BlobContainerClient blobContainer = new BlobContainerClient(StorageConnectionString, EventHubsCaptureAvroBlobContainer); + BlobClient blob = blobContainer.GetBlobClient(EventHubsCaptureAvroBlobName); + + // Download the content to a memory stream + Stream blobStream = new MemoryStream(); + blob.DownloadToAsync(blobStream); using (var dataTable = GetWindTurbineMetricsTable()) { // Parse the Avro File - using (var avroReader = DataFileReader.OpenReader(blob.OpenRead())) + using (var avroReader = DataFileReader.OpenReader(blobStream)) { while (avroReader.HasNext()) { diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs index 0ab7b9217..5ac8bca68 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs @@ -1,7 +1,9 @@ -using System; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. namespace DWDumper { + using System; // TODO, move this class to a Contracts assembly that is shared across different projects class WindTurbineMeasure { diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/packages.config index 935667da9..3dac4c2f1 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/packages.config +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/packages.config @@ -1,16 +1,26 @@  + + + + - + + + + + + - + + \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs index 8b5d40302..282977503 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + namespace FunctionEGDWDumper { /// diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs index 41944c22f..3de7c4ade 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs @@ -8,20 +8,22 @@ using System.Linq; using System.Net; using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using Avro.File; -using Avro.Generic; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.EventGrid; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Azure.WebJobs.Host; -using Microsoft.WindowsAzure.Storage; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; + +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. namespace FunctionEGDWDumper { + using System.Text; + using Avro.File; + using Avro.Generic; + using Microsoft.Azure.WebJobs; + using Microsoft.Azure.WebJobs.Extensions.EventGrid; + using Microsoft.Azure.WebJobs.Host; + using Microsoft.WindowsAzure.Storage; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; + public static class Function1 { diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj index 84dfa5bc1..72747d8a8 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj @@ -1,4 +1,4 @@ - + net461 @@ -6,7 +6,7 @@ - + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/WindTurbineMeasure.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/WindTurbineMeasure.cs index 0c35262d2..19a41a3b4 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/WindTurbineMeasure.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/WindTurbineMeasure.cs @@ -1,7 +1,11 @@ -using System; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + namespace FunctionEGDWDumper { + using System; + // TODO, move this class to a Contracts assembly that is shared across different projects class WindTurbineMeasure { diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs index f054161bf..7c33b514a 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs @@ -1,22 +1,22 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Newtonsoft.Json; -using Azure.Messaging.EventHubs; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. namespace WindTurbineDataGenerator { + using System; + using System.Diagnostics; + using System.Text; + using System.Threading; + using System.Threading.Tasks; + using Newtonsoft.Json; + using Azure.Messaging.EventHubs; + + internal class Program { - private const string EventHubConnectionString = - ""; - + private const string EventHubNamespaceConnectionString = ""; private const string EventHubName = ""; - + private static int Main() { Console.WriteLine("Starting wind turbine generator. Press to exit"); @@ -40,7 +40,7 @@ private static async Task StartEventGenerationAsync(CancellationToken cancellati var random = new Random((int)DateTimeOffset.UtcNow.Ticks); // create an Event Hubs Producer client using the namespace connection string and the event hub name - EventHubProducerClient producerClient = new EventHubProducerClient(EventHubConnectionString, EventHubName); + EventHubProducerClient producerClient = new EventHubProducerClient(EventHubNamespaceConnectionString, EventHubName); while (!cancellationToken.IsCancellationRequested) { @@ -55,7 +55,8 @@ private static async Task StartEventGenerationAsync(CancellationToken cancellati var windTurbineMeasure = GenerateTurbineMeasure("Turbine_" + i, scaleFactor); EventData evData = SerializeWindTurbineToEventData(windTurbineMeasure); // add the event to the batch - eventBatch.TryAdd(evData); + if (eventBatch.TryAdd(evData) == false) + break; } Console.Write("."); diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj index e0b22bb67..0ca5caa43 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj @@ -47,8 +47,8 @@ ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll - - ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineMeasure.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineMeasure.cs index 35ecad5b8..736adfc97 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineMeasure.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineMeasure.cs @@ -1,7 +1,10 @@ -using System; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. namespace WindTurbineDataGenerator { + using System; + // TODO, move this class to a Contracts assembly that is shared across different projects class WindTurbineMeasure { diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config index 796884c48..5b450a477 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config @@ -5,7 +5,7 @@ - + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj index 565dbf00d..34d40d3ee 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj @@ -58,9 +58,6 @@ packages\Microsoft.Azure.Amqp.2.4.3\lib\net45\Microsoft.Azure.Amqp.dll - - packages\Microsoft.Azure.Services.AppAuthentication.1.3.1\lib\net472\Microsoft.Azure.Services.AppAuthentication.dll - packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll @@ -71,18 +68,6 @@ packages\Microsoft.Identity.Client.4.7.1\lib\net45\Microsoft.Identity.Client.dll - - packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll - - - packages\Microsoft.IdentityModel.JsonWebTokens.5.6.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll - - - packages\Microsoft.IdentityModel.Logging.5.6.0\lib\net461\Microsoft.IdentityModel.Logging.dll - - - packages\Microsoft.IdentityModel.Tokens.5.6.0\lib\net461\Microsoft.IdentityModel.Tokens.dll - packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll @@ -95,9 +80,6 @@ packages\System.Diagnostics.DiagnosticSource.4.7.0\lib\net46\System.Diagnostics.DiagnosticSource.dll - - packages\System.IdentityModel.Tokens.Jwt.5.6.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll - packages\System.IO.4.3.0\lib\net462\System.IO.dll True diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx index 2e946357d..e46961765 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx @@ -11,7 +11,7 @@
- +
diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs index c092bb6c5..c44b44235 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs @@ -1,15 +1,18 @@ -using System; -using System.Linq; -using System.Text; -using System.Threading; -using Azure.Messaging.EventHubs; -using Azure.Identity; -using System.Threading.Tasks; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + // Always add app to IAM roles // Don't use on deployment slots but only on root namespace ManagedIdentityWebApp { + using System; + using System.Text; + using System.Threading; + using Azure.Messaging.EventHubs; + using Azure.Identity; + using System.Threading.Tasks; + public partial class SendReceive : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) @@ -19,7 +22,7 @@ protected void Page_Load(object sender, EventArgs e) protected async void btnSend_Click(object sender, EventArgs e) { - await using (EventHubProducerClient producerClient = new EventHubProducerClient($"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential())) + await using (EventHubProducerClient producerClient = new EventHubProducerClient(txtNamespace.Text, txtEventHub.Text, new DefaultAzureCredential())) { // create a batch EventDataBatch eventBatch = await producerClient.CreateBatchAsync(); @@ -30,7 +33,7 @@ protected async void btnSend_Click(object sender, EventArgs e) // send the batch to the event hub await producerClient.SendAsync(eventBatch); - txtOutput.Text = $"{DateTime.Now} - SENT{Environment.NewLine}" + txtOutput.Text; + txtOutput.Text = $"{DateTime.Now} - SENT{Environment.NewLine}{txtOutput.Text}"; } } protected async void btnReceive_Click(object sender, EventArgs e) diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config index b8766ff84..b4c1da9b3 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config @@ -4,19 +4,12 @@ - - - - - - - From 000b20a68a924e4e27da4dfd2f7c850d37a4d884 Mon Sep 17 00:00:00 2001 From: spelluru Date: Thu, 9 Jan 2020 16:50:11 -0500 Subject: [PATCH 33/66] minor update to UI - fully qualified name --- .../ManagedIdentityWebApp/ManagedIdentityWebApp.csproj | 2 +- .../ManagedIdentityWebApp/SendReceive.aspx | 2 +- .../ManagedIdentityWebApp/StyleSheet.css | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj index 34d40d3ee..e1fbdeb06 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj @@ -183,7 +183,7 @@ - + Web.config diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx index e46961765..cad3dbad9 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx @@ -11,7 +11,7 @@
- +
diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/StyleSheet.css b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/StyleSheet.css index 18b4dd479..cdaafb614 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/StyleSheet.css +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/StyleSheet.css @@ -1,5 +1,5 @@ label { - width: 200px; + width: 540px; display: inline-block; } From 40fa580a53398b5a8d8464d094b95307e0efc610 Mon Sep 17 00:00:00 2001 From: spelluru Date: Thu, 9 Jan 2020 17:30:52 -0500 Subject: [PATCH 34/66] added using statements --- .../AnomalyDetector/Producer/Program.cs | 55 ++++++++++--------- .../DWDumper/Program.cs | 34 ++++++------ .../ManagedIdentityWebApp/SendReceive.aspx.cs | 14 +++-- 3 files changed, 54 insertions(+), 49 deletions(-) diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs index e2dbf94df..d56f8fcd8 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs @@ -53,41 +53,42 @@ await File.AppendAllTextAsync( try { // create a batch using the producer client - EventDataBatch eventBatch = await producerClient.CreateBatchAsync(); - foreach (var t in transactions) + using (EventDataBatch eventBatch = await producerClient.CreateBatchAsync()) { - // we don't send the transaction type as part of the message. - // that is up to the downstream analytics to figure out! - // we just pretty print them here so they can easily be compared with the downstream - // analytics results. - var message = t.Data.ToJson(); - - if (t.Type == TransactionType.Suspect) + foreach (var t in transactions) { - var fc = Console.ForegroundColor; - Console.ForegroundColor = ConsoleColor.Yellow; + // we don't send the transaction type as part of the message. + // that is up to the downstream analytics to figure out! + // we just pretty print them here so they can easily be compared with the downstream + // analytics results. + var message = t.Data.ToJson(); - Console.WriteLine($"Suspect transaction: {message}"); + if (t.Type == TransactionType.Suspect) + { + var fc = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.Yellow; - Console.ForegroundColor = fc; // reset to original - } - else - { - Console.WriteLine($"Regular transaction: {message}"); - } + Console.WriteLine($"Suspect transaction: {message}"); - var line = $"{t.Data.CreditCardId},{t.Data.Timestamp.ToString("o")},{t.Data.Location},{t.Data.Amount},{t.Type}{Environment.NewLine}"; + Console.ForegroundColor = fc; // reset to original + } + else + { + Console.WriteLine($"Regular transaction: {message}"); + } - File.AppendAllText(TransactionsDumpFile, line); + var line = $"{t.Data.CreditCardId},{t.Data.Timestamp.ToString("o")},{t.Data.Location},{t.Data.Amount},{t.Type}{Environment.NewLine}"; - // add the message to the batch - eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes(message))); - numSuccessfulMessages++; - } + File.AppendAllText(TransactionsDumpFile, line); - // send the batch of messages to the event hub using the producer object - await producerClient.SendAsync(eventBatch); - await Task.Delay(10); + // add the message to the batch + eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes(message))); + numSuccessfulMessages++; + } + // send the batch of messages to the event hub using the producer object + await producerClient.SendAsync(eventBatch); + await Task.Delay(10); + } } catch (Exception ex) { diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs index 12ca9b714..e5c25bd71 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs @@ -40,29 +40,31 @@ public void Dump() BlobClient blob = blobContainer.GetBlobClient(EventHubsCaptureAvroBlobName); // Download the content to a memory stream - Stream blobStream = new MemoryStream(); - blob.DownloadToAsync(blobStream); - - using (var dataTable = GetWindTurbineMetricsTable()) + using (Stream blobStream = new MemoryStream()) { - // Parse the Avro File - using (var avroReader = DataFileReader.OpenReader(blobStream)) + blob.DownloadToAsync(blobStream); + + using (var dataTable = GetWindTurbineMetricsTable()) { - while (avroReader.HasNext()) + // Parse the Avro File + using (var avroReader = DataFileReader.OpenReader(blobStream)) { - GenericRecord r = avroReader.Next(); + while (avroReader.HasNext()) + { + GenericRecord r = avroReader.Next(); - byte[] body = (byte[]) r["Body"]; - var windTurbineMeasure = DeserializeToWindTurbineMeasure(body); + byte[] body = (byte[])r["Body"]; + var windTurbineMeasure = DeserializeToWindTurbineMeasure(body); - // Add the row to in memory table - AddWindTurbineMetricToTable(dataTable, windTurbineMeasure); + // Add the row to in memory table + AddWindTurbineMetricToTable(dataTable, windTurbineMeasure); + } } - } - if (dataTable.Rows.Count > 0) - { - BatchInsert(dataTable); + if (dataTable.Rows.Count > 0) + { + BatchInsert(dataTable); + } } } } diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs index c44b44235..038f7aebb 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs @@ -25,13 +25,15 @@ protected async void btnSend_Click(object sender, EventArgs e) await using (EventHubProducerClient producerClient = new EventHubProducerClient(txtNamespace.Text, txtEventHub.Text, new DefaultAzureCredential())) { // create a batch - EventDataBatch eventBatch = await producerClient.CreateBatchAsync(); + using (EventDataBatch eventBatch = await producerClient.CreateBatchAsync()) + { + + // add events to the batch. only one in this case. + eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes(txtData.Text))); - // add events to the batch. only one in this case. - eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes(txtData.Text))); - - // send the batch to the event hub - await producerClient.SendAsync(eventBatch); + // send the batch to the event hub + await producerClient.SendAsync(eventBatch); + } txtOutput.Text = $"{DateTime.Now} - SENT{Environment.NewLine}{txtOutput.Text}"; } From f4f50e872d79c42bc11cdfbc28b47e7883c741c8 Mon Sep 17 00:00:00 2001 From: spelluru Date: Wed, 15 Jan 2020 13:36:20 -0500 Subject: [PATCH 35/66] fixed the receive code --- .../ManagedIdentityWebApp/SendReceive.aspx.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs index 038f7aebb..cc79d1fe4 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs @@ -40,7 +40,7 @@ protected async void btnSend_Click(object sender, EventArgs e) } protected async void btnReceive_Click(object sender, EventArgs e) { - await using (var consumerClient = new EventHubConsumerClient(EventHubConsumerClient.DefaultConsumerGroupName, $"{txtNamespace.Text}.servicebus.windows.net", txtEventHub.Text, new DefaultAzureCredential())) + await using (var consumerClient = new EventHubConsumerClient(EventHubConsumerClient.DefaultConsumerGroupName, txtNamespace.Text, txtEventHub.Text, new DefaultAzureCredential())) { int eventsRead = 0; try From 72fc2bbdb3ac4c84c48aaef576e66066f1df80ae Mon Sep 17 00:00:00 2001 From: spelluru Date: Thu, 30 Jan 2020 17:42:07 -0500 Subject: [PATCH 36/66] Updated samples to use the latest .NET package --- .../AnomalyDetector/Producer/Producer.csproj | 2 +- .../AnomalyDetector/Producer/Program.cs | 1 + .../WindTurbineDataGenerator/Program.cs | 1 + .../WindTurbineDataGenerator/WindTurbineDataGenerator.csproj | 4 ++-- .../WindTurbineDataGenerator/packages.config | 2 +- .../ManagedIdentityWebApp/ManagedIdentityWebApp.csproj | 4 ++-- .../ManagedIdentityWebApp/SendReceive.aspx.cs | 2 ++ .../ManagedIdentityWebApp/packages.config | 2 +- 8 files changed, 11 insertions(+), 7 deletions(-) diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj index 2dd5143ad..a0f3c2c23 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Producer.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs index d56f8fcd8..913bd895d 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/AnomalyDetector/Producer/Program.cs @@ -7,6 +7,7 @@ namespace Producer using System.Text; using System.Threading.Tasks; using Azure.Messaging.EventHubs; + using Azure.Messaging.EventHubs.Producer; using System.Collections.Generic; using System.IO; diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs index 7c33b514a..9a601a763 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs @@ -10,6 +10,7 @@ namespace WindTurbineDataGenerator using System.Threading.Tasks; using Newtonsoft.Json; using Azure.Messaging.EventHubs; + using Azure.Messaging.EventHubs.Producer; internal class Program diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj index 0ca5caa43..528c4f059 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj @@ -35,8 +35,8 @@ ..\packages\Azure.Core.1.0.1\lib\netstandard2.0\Azure.Core.dll - - ..\packages\Azure.Messaging.EventHubs.5.0.0-preview.6\lib\netstandard2.0\Azure.Messaging.EventHubs.dll + + ..\packages\Azure.Messaging.EventHubs.5.0.1\lib\netstandard2.0\Azure.Messaging.EventHubs.dll ..\packages\Microsoft.Azure.Amqp.2.4.2\lib\net45\Microsoft.Azure.Amqp.dll diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config index 5b450a477..7679cc9cd 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config +++ b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config @@ -1,7 +1,7 @@  - + diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj index e1fbdeb06..ae30c2757 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/ManagedIdentityWebApp.csproj @@ -52,8 +52,8 @@ packages\Azure.Identity.1.1.0\lib\netstandard2.0\Azure.Identity.dll - - packages\Azure.Messaging.EventHubs.5.0.0-preview.6\lib\netstandard2.0\Azure.Messaging.EventHubs.dll + + packages\Azure.Messaging.EventHubs.5.0.1\lib\netstandard2.0\Azure.Messaging.EventHubs.dll packages\Microsoft.Azure.Amqp.2.4.3\lib\net45\Microsoft.Azure.Amqp.dll diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs index cc79d1fe4..6531373b7 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/SendReceive.aspx.cs @@ -10,6 +10,8 @@ namespace ManagedIdentityWebApp using System.Text; using System.Threading; using Azure.Messaging.EventHubs; + using Azure.Messaging.EventHubs.Producer; + using Azure.Messaging.EventHubs.Consumer; using Azure.Identity; using System.Threading.Tasks; diff --git a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config index b4c1da9b3..4af44b2bd 100644 --- a/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config +++ b/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp/packages.config @@ -2,7 +2,7 @@ - + From 3527fe90a90b6d265a4867fd64ce58ad36406d9c Mon Sep 17 00:00:00 2001 From: JamesBirdsall Date: Wed, 22 Apr 2020 10:06:23 -0700 Subject: [PATCH 37/66] Add async send sample (#468) Sample demonstrates async send, the benefits of concurrent sends, and how to limit the number of concurrent sends. --- samples/Java/Basic/AsyncSend/README.md | 68 +++++++++++ samples/Java/Basic/AsyncSend/pom.xml | 53 +++++++++ .../samples/AsyncSend/AsyncSend.java | 112 ++++++++++++++++++ samples/Java/pom.xml | 1 + 4 files changed, 234 insertions(+) create mode 100644 samples/Java/Basic/AsyncSend/README.md create mode 100644 samples/Java/Basic/AsyncSend/pom.xml create mode 100644 samples/Java/Basic/AsyncSend/src/main/java/com/microsoft/azure/eventhubs/samples/AsyncSend/AsyncSend.java diff --git a/samples/Java/Basic/AsyncSend/README.md b/samples/Java/Basic/AsyncSend/README.md new file mode 100644 index 000000000..2cd77923a --- /dev/null +++ b/samples/Java/Basic/AsyncSend/README.md @@ -0,0 +1,68 @@ +# Send events asynchronously to Azure Event Hubs using Java + +To run the sample, you need to edit the [sample code](src/main/java/com/microsoft/azure/eventhubs/samples/asyncsend/AsyncSend.java) and provide the following information: + +```java + final String namespaceName = "----EventHubsNamespaceName-----"; + final String eventHubName = "----EventHubName-----"; + final String sasKeyName = "-----SharedAccessSignatureKeyName-----"; + final String sasKey = "---SharedAccessSignatureKey----"; +``` + +## Prerequisites + +Please refer to the [overview README](../../readme.md) for prerequisites and setting up the sample environment, including creating an Event Hubs cloud namespace and an Event Hub. + +## Build and run + +The sample can be built independently with + +```bash +mvn clean package +``` + +and then run with (or just from VS Code or another Java IDE) + +```bash +java -jar ./target/asyncsend-1.0.0-jar-with-dependencies.jar +``` + +## Understanding Async Send + +This sample demonstrates using the asynchronous send() method on the EventHubClient class. + +The corresponding sendSync() method is pretty simple: it waits for the the send operation to +be complete, then returns, indicating success, or throws, indicating an error. Unfortunately, it's +not fast, because it means waiting for the message to go across the network to the service, for +the service to store the message, and then for the result to come back across the network. + +Switching to the asynchronous send() means your code must be more +sophisticated. By its nature, an asynchronous method just starts an operation and does not wait +for it to finish, so your code can be doing something useful while the operation proceeds in the +background. However, that means that the method itself cannot tell +you anything about the result of the operation, because there is no result yet when the method +returns. Java provides a standard class, CompletableFuture, for asynchronous methods to return, +which allows the calling code to obtain the result of the operation at a later time, and the Event +Hubs Java client makes use of that class. CompletableFuture offers some sophisticated abilities, +but this sample simply retrieves the result by calling get(), which will return when the operation +finishes (or has already finished) successfully, or throw an exception if there was an error. + +One of the things your code can be doing while waiting for a send operation to finish is to prepare +and send additional messages, which this sample demonstrates. This is known as concurrent sending +and it is a good way to increase your throughput. The sample sends three groups of 100 messages each, +with one concurrent send, ten concurrent sends, and thirty concurrent sends respectively. It uses a +queue to save the CompletableFuture instances returned by send(), and when the queue grows larger +than the desired number of concurrent operations, it waits for the oldest CompletableFuture to +complete. One concurrent send is equivalent to making a synchronous call: each send must wait for the +previous one to finish. With ten concurrent sends, the average wait time and total execution time is +much smaller, because by the time the 11th send is attempted, the first send is mostly done, and the +same for the 12th send and the second, etc. With thirty concurrent sends, the average wait time is +nearly 0, because the first send is already finished by the time the 31st is attempted, etc. The +useful number of concurrent calls is limited by memory usage, CPU usage, network congestion, and other +factors, and we do not recommend trying more than about 100. + +Error handling is also different when using asynchronous calls. Supposing the get() on the CompletableFuture +throws an error, indicating a failure, but you still want that message and would like to retry sending +it -- how do you know what message failed? This sample demonstrates one possible approach, by storing +the original message with the CompletableFuture. There are many possibilities and which is best +depends on the structure of your application. \ No newline at end of file diff --git a/samples/Java/Basic/AsyncSend/pom.xml b/samples/Java/Basic/AsyncSend/pom.xml new file mode 100644 index 000000000..2b9760505 --- /dev/null +++ b/samples/Java/Basic/AsyncSend/pom.xml @@ -0,0 +1,53 @@ + + 4.0.0 + asyncsend + 1.0.0 + asyncsend + jar + + UTF-8 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + true + lines,vars,source + + + + maven-assembly-plugin + + + package + + single + + + + + + jar-with-dependencies + + + + com.microsoft.azure.eventhubs.samples.AsyncSend.AsyncSend + + + + + + + + + com.microsoft.azure + azure-eventhubs + 3.1.1 + + + diff --git a/samples/Java/Basic/AsyncSend/src/main/java/com/microsoft/azure/eventhubs/samples/AsyncSend/AsyncSend.java b/samples/Java/Basic/AsyncSend/src/main/java/com/microsoft/azure/eventhubs/samples/AsyncSend/AsyncSend.java new file mode 100644 index 000000000..38bfe47e5 --- /dev/null +++ b/samples/Java/Basic/AsyncSend/src/main/java/com/microsoft/azure/eventhubs/samples/AsyncSend/AsyncSend.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) Microsoft. All rights reserved. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +package com.microsoft.azure.eventhubs.samples.AsyncSend; + +import com.microsoft.azure.eventhubs.ConnectionStringBuilder; +import com.microsoft.azure.eventhubs.EventData; +import com.microsoft.azure.eventhubs.EventHubClient; +import com.microsoft.azure.eventhubs.EventHubException; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.time.Instant; +import java.util.LinkedList; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + +public class AsyncSend { + + public static void main(String[] args) + throws EventHubException, ExecutionException, InterruptedException, IOException { + + final ConnectionStringBuilder connStr = new ConnectionStringBuilder() + .setNamespaceName("Your Event Hubs namespace name") // to target National clouds - use .setEndpoint(URI) + .setEventHubName("Your event hub") + .setSasKeyName("Your policy name") + .setSasKey("Your primary SAS key"); + + // The Executor handles all asynchronous tasks and this is passed to the + // EventHubClient instance. This enables the user to segregate their thread + // pool based on the work load. This pool can then be shared across multiple + // EventHubClient instances. + final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); + + // Each EventHubClient instance spins up a new TCP/SSL connection, which is + // expensive. It is always a best practice to reuse these instances. + final EventHubClient ehClient = EventHubClient.createFromConnectionStringSync(connStr.toString(), executorService); + + send100Messages(ehClient, 1); + System.out.println(); + + send100Messages(ehClient, 10); + System.out.println(); + + send100Messages(ehClient, 30); + System.out.println(); + + ehClient.closeSync(); + executorService.shutdown(); + } + + public static void send100Messages(final EventHubClient ehClient, final int inFlightMax) { + System.out.println("Sending 100 messages with " + inFlightMax + " concurrent sends"); + + LinkedList inFlight = new LinkedList(); + long totalWait = 0L; + long totalStart = Instant.now().toEpochMilli(); + + for (int i = 0; i < 100; i++) { + String payload = "Message " + Integer.toString(i); + byte[] payloadBytes = payload.getBytes(Charset.defaultCharset()); + MessageAndResult mar = new MessageAndResult(i, EventData.create(payloadBytes)); + long startWait = Instant.now().toEpochMilli(); + + if (inFlight.size() >= inFlightMax) { + MessageAndResult oldest = inFlight.remove(); + try { + oldest.result.get(); + //System.out.println("Completed send of message " + oldest.messageNumber + ": succeeded"); + } catch (InterruptedException | ExecutionException e) { + System.out.println("Completed send of message " + oldest.messageNumber + ": failed: " + e.toString()); + } + } + + long waitTime = Instant.now().toEpochMilli() - startWait; + totalWait += waitTime; + //System.out.println("Blocked time waiting to send (ms): " + waitTime); + mar.result = ehClient.send(mar.message); + //System.out.println("Started send of message " + mar.messageNumber); + inFlight.add(mar); + } + + System.out.println("All sends started"); + + while (inFlight.size() > 0) { + MessageAndResult oldest = inFlight.remove(); + try { + oldest.result.get(); + //System.out.println("Completed send of message " + oldest.messageNumber + ": succeeded"); + } catch (InterruptedException | ExecutionException e) { + System.out.println("Completed send of message " + oldest.messageNumber + ": failed: " + e.toString()); + } + } + + System.out.println("All sends completed, average blocked time (ms): " + (totalWait / 100L)); + System.out.println("Total time to send 100 messages (ms): " + (Instant.now().toEpochMilli() - totalStart)); + } + + private static class MessageAndResult { + public final int messageNumber; + public final EventData message; + public CompletableFuture result; + + public MessageAndResult(final int messageNumber, final EventData message) { + this.messageNumber = messageNumber; + this.message = message; + } + } +} diff --git a/samples/Java/pom.xml b/samples/Java/pom.xml index 8dceb9e1a..dec4a357c 100644 --- a/samples/Java/pom.xml +++ b/samples/Java/pom.xml @@ -29,6 +29,7 @@ Basic/AdvancedSendOptions Basic/SendBatch Basic/SimpleSend + Basic/AsyncSend Basic/SimpleProxy Benchmarks/AutoScaleOnIngress Benchmarks/IngressBenchmark From 7ed366d0359abf0dcab584e1689aa130f0e9c60e Mon Sep 17 00:00:00 2001 From: spelluru Date: Thu, 30 Apr 2020 01:08:30 -0400 Subject: [PATCH 38/66] updated the readme to point to new samples. Cleaned up too. --- readme.md | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/readme.md b/readme.md index 7531b538d..2ec21ee03 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ Microsoft Azure Event Hubs

-

Microsoft Azure Event Hubs +

Azure Event Hubs samples

follow on Twitter

-We're happy to host our client SDKs and integrations on GitHub as free, open-source projects. We currently support: +This repository contains samples for Azure Event Hubs. -* [Event Hubs for Apache Kafka](https://github.com/Azure/azure-event-hubs-for-kafka) -* [.NET](https://github.com/azure/azure-event-hubs-dotnet) -* [Java](https://github.com/azure/azure-event-hubs-java) -* [C](https://github.com/azure/azure-event-hubs-c) -* [Node.js](https://github.com/azure/azure-event-hubs-node) -* [Python](https://github.com/azure/azure-event-hubs-python) -* [Go](https://github.com/azure/azure-event-hubs-go) -* [Apache Spark connector](https://github.com/Azure/azure-event-hubs-spark) +## Client SDK samples +The .NET and Java client SDK samples in this repository use **old SDKs**. For samples that use new SDKs, see the following repositories. -If you have any feedback, questions, or comments, go to the respective repo and file an issue. **Your involvement is welcome and encouraged!** +- [.NET](https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/eventhub/Azure.Messaging.EventHubs/samples) +- [Java](https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/eventhubs/azure-messaging-eventhubs/src/samples/java/com/azure/messaging/eventhubs) + +You can find samples for other languages and frameworks in the following repositories: +- [JavaScript](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/eventhub/event-hubs/samples) +- [Python](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/eventhub/azure-eventhub/samples) +- [C](https://github.com/azure/azure-event-hubs-c) +- [Go](https://github.com/azure/azure-event-hubs-go) +- [Apache Spark connector](https://github.com/Azure/azure-event-hubs-spark) +- [Event Hubs for Apache Kafka](https://github.com/Azure/azure-event-hubs-for-kafka) -## What is Event Hubs? +If you have any feedback, questions, or comments, go to the respective repo and file an issue. **Your involvement is welcome and encouraged!** -Azure Event Hubs is a hyper-scale data ingestion service, fully-managed by Microsoft, that enables you to collect, store and process trillions of events from websites, apps, IoT devices, and any stream of data. To learn more, please visit our [marketing page](https://azure.microsoft.com/services/event-hubs/). +## Management SDK samples +This repository also contains [management samples](https://github.com/Azure/azure-event-hubs/tree/master/samples/Management) that use the .NET management SDK, PowerShell, and CLI. -## Azure Event Hubs for Apache Kafka -Event Hubs now provides a Kafka endpoint that can be used by your existing Kafka-based applications as an alternative to running your own Kafka cluster. To learn more, check out the new [Azure Event Hubs for Apache Kafka](https://github.com/Azure/azure-event-hubs-for-kafka) repo! +## See also +To learn about Event Hubs, see our [Event Hubs documentation](https://docs.microsoft.com/en-us/azure/event-hubs/). \ No newline at end of file From 5a16c140921d263b22828fe8b19127f6779465b5 Mon Sep 17 00:00:00 2001 From: spelluru Date: Mon, 8 Jun 2020 23:54:07 -0400 Subject: [PATCH 39/66] Updated to use Functions runtime version 3 (latest) --- .../EventHubsCaptureEventGridDemo.sln | 26 +- .../FunctionEGDWDumper/.gitignore | 264 ++++++++++++++++++ .../FunctionEGDWDumper/Function1.cs | 8 +- .../FunctionEGDWDumper.csproj | 20 +- .../spegridehubfuncapp - Zip Deploy.arm.json | 222 +++++++++++++++ .../storage1.arm.json | 41 +++ .../Properties/serviceDependencies.json | 8 + .../Properties/serviceDependencies.local.json | 8 + ...ncies.spegridehubfuncapp - Zip Deploy.json | 10 + .../FunctionEGDWDumper/host.json | 9 + .../FunctionEGDWDumper/local.settings.json | 10 +- .../WindTurbineDataGenerator/Program.cs | 4 +- 12 files changed, 597 insertions(+), 33 deletions(-) create mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/.gitignore create mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/spegridehubfuncapp - Zip Deploy.arm.json create mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/storage1.arm.json create mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.json create mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.local.json create mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.spegridehubfuncapp - Zip Deploy.json diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln b/samples/e2e/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln index 2d7d0cecf..625d6b484 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln +++ b/samples/e2e/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln @@ -1,13 +1,13 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26730.12 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30128.36 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindTurbineDataGenerator", "WindTurbineDataGenerator\WindTurbineDataGenerator.csproj", "{0C87A54A-AD21-46D5-8B75-4247DA32237E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionEGDWDumper", "FunctionEGDWDumper\FunctionEGDWDumper.csproj", "{E29F9E83-073D-4371-929A-A1A045B9596E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DWDumper", "DWDumper\DWDumper.csproj", "{C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionEGDWDumper", "FunctionEGDWDumper\FunctionEGDWDumper.csproj", "{27D28A3D-4157-4ED2-A1C4-5525507CCA04}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindTurbineDataGenerator", "WindTurbineDataGenerator\WindTurbineDataGenerator.csproj", "{0C87A54A-AD21-46D5-8B75-4247DA32237E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,23 +15,23 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Release|Any CPU.Build.0 = Release|Any CPU + {E29F9E83-073D-4371-929A-A1A045B9596E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E29F9E83-073D-4371-929A-A1A045B9596E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E29F9E83-073D-4371-929A-A1A045B9596E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E29F9E83-073D-4371-929A-A1A045B9596E}.Release|Any CPU.Build.0 = Release|Any CPU {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Debug|Any CPU.Build.0 = Debug|Any CPU {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Release|Any CPU.ActiveCfg = Release|Any CPU {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Release|Any CPU.Build.0 = Release|Any CPU - {27D28A3D-4157-4ED2-A1C4-5525507CCA04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {27D28A3D-4157-4ED2-A1C4-5525507CCA04}.Debug|Any CPU.Build.0 = Debug|Any CPU - {27D28A3D-4157-4ED2-A1C4-5525507CCA04}.Release|Any CPU.ActiveCfg = Release|Any CPU - {27D28A3D-4157-4ED2-A1C4-5525507CCA04}.Release|Any CPU.Build.0 = Release|Any CPU + {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {0BDB7260-AF54-438B-B99E-95E7136C1486} + SolutionGuid = {CABDAC3A-BADD-423D-B33B-983C7CBD0F46} EndGlobalSection EndGlobal diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/.gitignore b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/.gitignore new file mode 100644 index 000000000..ff5b00c50 --- /dev/null +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/.gitignore @@ -0,0 +1,264 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# Azure Functions localsettings file +local.settings.json + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs index 41944c22f..ee1918b1e 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs @@ -5,6 +5,7 @@ using System.Data; using System.Data.SqlClient; using System.Globalization; +using System.IO; using System.Linq; using System.Net; using System.Net.Http; @@ -62,17 +63,18 @@ public static void Run([EventGridTrigger]JObject eventGridEvent, TraceWriter log /// Dumps the data from the Avro blob to the data warehouse (DW). /// Before running this, ensure that the DW has the required table created. ///
- private static void Dump(Uri fileUri) + private static async void Dump(Uri fileUri) { // Get the blob reference var storageAccount = CloudStorageAccount.Parse(StorageConnectionString); var blobClient = storageAccount.CreateCloudBlobClient(); - var blob = blobClient.GetBlobReferenceFromServer(fileUri); + var blob = await blobClient.GetBlobReferenceFromServerAsync(fileUri); using (var dataTable = GetWindTurbineMetricsTable()) { // Parse the Avro File - using (var avroReader = DataFileReader.OpenReader(blob.OpenRead())) + Stream blobStream = await blob.OpenReadAsync(null, null, null); + using (var avroReader = DataFileReader.OpenReader(blobStream)) { while (avroReader.HasNext()) { diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj index 84dfa5bc1..70a28dc44 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj @@ -1,15 +1,15 @@ - + - net461 + netcoreapp3.1 + v3 + c542a7d9-5d67-443a-b50f-0ea02bd96fcd - - - - - - - + + + + + @@ -20,4 +20,4 @@ Never - + \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/spegridehubfuncapp - Zip Deploy.arm.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/spegridehubfuncapp - Zip Deploy.arm.json new file mode 100644 index 000000000..41b513598 --- /dev/null +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/spegridehubfuncapp - Zip Deploy.arm.json @@ -0,0 +1,222 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "name": "spegridehubgrp", + "location": "eastus", + "apiVersion": "2019-10-01" + }, + { + "type": "Microsoft.Resources/deployments", + "name": "[concat('spegridehubgrpDeployment', uniqueString(subscription().subscriptionId))]", + "resourceGroup": "spegridehubgrp", + "apiVersion": "2019-10-01", + "dependsOn": [ + "spegridehubgrp" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "id": "/subscriptions/a61d8041-614d-4f85-b928-4b24c8abc76c/resourceGroups/spegridehubgrp/providers/Microsoft.Web/sites/spegridehubfuncapp", + "name": "spegridehubfuncapp", + "type": "Microsoft.Web/sites", + "kind": "functionapp", + "location": "East US", + "properties": { + "name": "spegridehubfuncapp", + "state": "Running", + "hostNames": [ + "spegridehubfuncapp.azurewebsites.net" + ], + "webSpace": "spegridehubgrp-EastUSwebspace", + "selfLink": "https://waws-prod-blu-119.api.azurewebsites.windows.net:454/subscriptions/a61d8041-614d-4f85-b928-4b24c8abc76c/webspaces/spegridehubgrp-EastUSwebspace/sites/spegridehubfuncapp", + "repositorySiteName": "spegridehubfuncapp", + "owner": null, + "usageState": 0, + "enabled": true, + "adminEnabled": true, + "enabledHostNames": [ + "spegridehubfuncapp.azurewebsites.net", + "spegridehubfuncapp.scm.azurewebsites.net" + ], + "siteProperties": { + "metadata": null, + "properties": [ + { + "name": "LinuxFxVersion", + "value": "" + }, + { + "name": "WindowsFxVersion", + "value": null + } + ], + "appSettings": null + }, + "availabilityState": 0, + "sslCertificates": null, + "csrs": [], + "cers": null, + "siteMode": null, + "hostNameSslStates": [ + { + "name": "spegridehubfuncapp.azurewebsites.net", + "sslState": 0, + "ipBasedSslResult": null, + "virtualIP": null, + "thumbprint": null, + "toUpdate": null, + "toUpdateIpBasedSsl": null, + "ipBasedSslState": 0, + "hostType": 0 + }, + { + "name": "spegridehubfuncapp.scm.azurewebsites.net", + "sslState": 0, + "ipBasedSslResult": null, + "virtualIP": null, + "thumbprint": null, + "toUpdate": null, + "toUpdateIpBasedSsl": null, + "ipBasedSslState": 0, + "hostType": 1 + } + ], + "computeMode": null, + "serverFarm": null, + "serverFarmId": "/subscriptions/a61d8041-614d-4f85-b928-4b24c8abc76c/resourceGroups/spegridehubgrp/providers/Microsoft.Web/serverfarms/spegridehubfuncappPlan", + "reserved": false, + "isXenon": false, + "hyperV": false, + "lastModifiedTimeUtc": "2020-06-09T02:15:32.4033333", + "storageRecoveryDefaultState": "Running", + "contentAvailabilityState": 0, + "runtimeAvailabilityState": 0, + "siteConfig": { + "numberOfWorkers": null, + "defaultDocuments": null, + "netFrameworkVersion": null, + "phpVersion": null, + "pythonVersion": null, + "nodeVersion": null, + "powerShellVersion": null, + "linuxFxVersion": null, + "windowsFxVersion": null, + "requestTracingEnabled": null, + "remoteDebuggingEnabled": null, + "remoteDebuggingVersion": null, + "httpLoggingEnabled": null, + "azureMonitorLogCategories": null, + "acrUseManagedIdentityCreds": false, + "acrUserManagedIdentityID": null, + "logsDirectorySizeLimit": null, + "detailedErrorLoggingEnabled": null, + "publishingUsername": null, + "publishingPassword": null, + "appSettings": null, + "metadata": null, + "connectionStrings": null, + "machineKey": null, + "handlerMappings": null, + "documentRoot": null, + "scmType": null, + "use32BitWorkerProcess": null, + "webSocketsEnabled": null, + "alwaysOn": null, + "javaVersion": null, + "javaContainer": null, + "javaContainerVersion": null, + "appCommandLine": null, + "managedPipelineMode": null, + "virtualApplications": null, + "winAuthAdminState": null, + "winAuthTenantState": null, + "customAppPoolIdentityAdminState": null, + "customAppPoolIdentityTenantState": null, + "runtimeADUser": null, + "runtimeADUserPassword": null, + "loadBalancing": null, + "routingRules": null, + "experiments": null, + "limits": null, + "autoHealEnabled": null, + "autoHealRules": null, + "tracingOptions": null, + "vnetName": null, + "cors": null, + "push": null, + "apiDefinition": null, + "apiManagementConfig": null, + "autoSwapSlotName": null, + "localMySqlEnabled": null, + "managedServiceIdentityId": null, + "xManagedServiceIdentityId": null, + "ipSecurityRestrictions": null, + "scmIpSecurityRestrictions": null, + "scmIpSecurityRestrictionsUseMain": null, + "http20Enabled": null, + "minTlsVersion": null, + "ftpsState": null, + "preWarmedInstanceCount": null, + "healthCheckPath": null, + "fileChangeAuditEnabled": null, + "functionsRuntimeScaleMonitoringEnabled": null, + "websiteTimeZone": null, + "minimumElasticInstanceCount": 0 + }, + "deploymentId": "spegridehubfuncapp", + "trafficManagerHostNames": null, + "sku": "Dynamic", + "scmSiteAlsoStopped": false, + "targetSwapSlot": null, + "hostingEnvironment": null, + "hostingEnvironmentProfile": null, + "clientAffinityEnabled": false, + "clientCertEnabled": false, + "clientCertMode": 0, + "clientCertExclusionPaths": null, + "hostNamesDisabled": false, + "domainVerificationIdentifiers": null, + "customDomainVerificationId": "A92BAA23A498CC9938061E0B8402F7BED64FCEB003CF0C501E2595F2D6423CCA", + "kind": "functionapp", + "inboundIpAddress": "40.121.35.221", + "possibleInboundIpAddresses": "40.121.35.221", + "ftpUsername": "spegridehubfuncapp\\$spegridehubfuncapp", + "ftpsHostName": "ftps://waws-prod-blu-119.ftp.azurewebsites.windows.net/site/wwwroot", + "outboundIpAddresses": "40.121.35.221,40.114.109.158,104.211.29.193,13.68.131.60,40.87.86.14", + "possibleOutboundIpAddresses": "40.121.35.221,40.114.109.158,104.211.29.193,13.68.131.60,40.87.86.14,13.68.130.103,40.87.82.124,13.68.137.247", + "containerSize": 1536, + "dailyMemoryTimeQuota": 0, + "suspendedTill": null, + "siteDisabledReason": 0, + "functionExecutionUnitsCache": null, + "maxNumberOfWorkers": null, + "homeStamp": "waws-prod-blu-119", + "cloningInfo": null, + "hostingEnvironmentId": null, + "tags": null, + "resourceGroup": "spegridehubgrp", + "defaultHostName": "spegridehubfuncapp.azurewebsites.net", + "slotSwapStatus": null, + "httpsOnly": false, + "redundancyMode": 0, + "inProgressOperationId": null, + "geoDistributions": null, + "privateEndpointConnections": [], + "buildVersion": null, + "targetBuildVersion": null + }, + "apiVersion": "2015-05-01" + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/storage1.arm.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/storage1.arm.json new file mode 100644 index 000000000..3d50fe537 --- /dev/null +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/storage1.arm.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "name": "spegridehubgrp", + "location": "eastus", + "apiVersion": "2019-10-01" + }, + { + "type": "Microsoft.Resources/deployments", + "name": "[concat('spegridehubgrpDeployment', uniqueString(subscription().subscriptionId))]", + "resourceGroup": "spegridehubgrp", + "apiVersion": "2019-10-01", + "dependsOn": [ + "spegridehubgrp" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + }, + "kind": "Storage", + "name": "spegridehubstorage", + "type": "Microsoft.Storage/storageAccounts", + "location": "eastus", + "apiVersion": "2017-10-01" + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.json new file mode 100644 index 000000000..fcc92d112 --- /dev/null +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.json @@ -0,0 +1,8 @@ +{ + "dependencies": { + "storage1": { + "type": "storage", + "connectionId": "AzureWebJobsStorage" + } + } +} \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.local.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.local.json new file mode 100644 index 000000000..155d87e0d --- /dev/null +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.local.json @@ -0,0 +1,8 @@ +{ + "dependencies": { + "storage1": { + "type": "storage.emulator", + "connectionId": "AzureWebJobsStorage" + } + } +} \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.spegridehubfuncapp - Zip Deploy.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.spegridehubfuncapp - Zip Deploy.json new file mode 100644 index 000000000..32b928626 --- /dev/null +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.spegridehubfuncapp - Zip Deploy.json @@ -0,0 +1,10 @@ +{ + "dependencies": { + "storage1": { + "resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroup')]/providers/Microsoft.Storage/storageAccounts/spegridehubstorage", + "type": "storage.azure", + "connectionId": "AzureWebJobsStorage", + "secretStore": "AzureAppSettings" + } + } +} \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json index 7a73a41bf..bb3b8dadd 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json @@ -1,2 +1,11 @@ { + "version": "2.0", + "logging": { + "applicationInsights": { + "samplingExcludedTypes": "Request", + "samplingSettings": { + "isEnabled": true + } + } + } } \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/local.settings.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/local.settings.json index 8f901f116..4fce9ff39 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/local.settings.json +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/local.settings.json @@ -1,7 +1,7 @@ { - "IsEncrypted": false, - "Values": { - "AzureWebJobsStorage": "", - "AzureWebJobsDashboard": "" - } + "IsEncrypted": false, + "Values": { + "AzureWebJobsStorage": "UseDevelopmentStorage=true", + "FUNCTIONS_WORKER_RUNTIME": "dotnet" + } } \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs index abbcf606e..d34a5f816 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs @@ -13,9 +13,9 @@ namespace WindTurbineDataGenerator internal class Program { private const string EventHubConnectionString = - "[provide the EH connection string]"; + ""; - private const string EventHubName = "[provide the EH name]"; + private const string EventHubName = ""; private static int Main(string[] args) { From 5acf9e8e9cc257078a2a3c0e13a6d012467db962 Mon Sep 17 00:00:00 2001 From: spelluru Date: Mon, 8 Jun 2020 23:57:51 -0400 Subject: [PATCH 40/66] removed publish profile --- .../spegridehubfuncapp - Zip Deploy.arm.json | 222 ------------------ .../storage1.arm.json | 41 ---- .../Properties/serviceDependencies.json | 8 - .../Properties/serviceDependencies.local.json | 8 - ...ncies.spegridehubfuncapp - Zip Deploy.json | 10 - 5 files changed, 289 deletions(-) delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/spegridehubfuncapp - Zip Deploy.arm.json delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/storage1.arm.json delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.json delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.local.json delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.spegridehubfuncapp - Zip Deploy.json diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/spegridehubfuncapp - Zip Deploy.arm.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/spegridehubfuncapp - Zip Deploy.arm.json deleted file mode 100644 index 41b513598..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/spegridehubfuncapp - Zip Deploy.arm.json +++ /dev/null @@ -1,222 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - { - "type": "Microsoft.Resources/resourceGroups", - "name": "spegridehubgrp", - "location": "eastus", - "apiVersion": "2019-10-01" - }, - { - "type": "Microsoft.Resources/deployments", - "name": "[concat('spegridehubgrpDeployment', uniqueString(subscription().subscriptionId))]", - "resourceGroup": "spegridehubgrp", - "apiVersion": "2019-10-01", - "dependsOn": [ - "spegridehubgrp" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - { - "id": "/subscriptions/a61d8041-614d-4f85-b928-4b24c8abc76c/resourceGroups/spegridehubgrp/providers/Microsoft.Web/sites/spegridehubfuncapp", - "name": "spegridehubfuncapp", - "type": "Microsoft.Web/sites", - "kind": "functionapp", - "location": "East US", - "properties": { - "name": "spegridehubfuncapp", - "state": "Running", - "hostNames": [ - "spegridehubfuncapp.azurewebsites.net" - ], - "webSpace": "spegridehubgrp-EastUSwebspace", - "selfLink": "https://waws-prod-blu-119.api.azurewebsites.windows.net:454/subscriptions/a61d8041-614d-4f85-b928-4b24c8abc76c/webspaces/spegridehubgrp-EastUSwebspace/sites/spegridehubfuncapp", - "repositorySiteName": "spegridehubfuncapp", - "owner": null, - "usageState": 0, - "enabled": true, - "adminEnabled": true, - "enabledHostNames": [ - "spegridehubfuncapp.azurewebsites.net", - "spegridehubfuncapp.scm.azurewebsites.net" - ], - "siteProperties": { - "metadata": null, - "properties": [ - { - "name": "LinuxFxVersion", - "value": "" - }, - { - "name": "WindowsFxVersion", - "value": null - } - ], - "appSettings": null - }, - "availabilityState": 0, - "sslCertificates": null, - "csrs": [], - "cers": null, - "siteMode": null, - "hostNameSslStates": [ - { - "name": "spegridehubfuncapp.azurewebsites.net", - "sslState": 0, - "ipBasedSslResult": null, - "virtualIP": null, - "thumbprint": null, - "toUpdate": null, - "toUpdateIpBasedSsl": null, - "ipBasedSslState": 0, - "hostType": 0 - }, - { - "name": "spegridehubfuncapp.scm.azurewebsites.net", - "sslState": 0, - "ipBasedSslResult": null, - "virtualIP": null, - "thumbprint": null, - "toUpdate": null, - "toUpdateIpBasedSsl": null, - "ipBasedSslState": 0, - "hostType": 1 - } - ], - "computeMode": null, - "serverFarm": null, - "serverFarmId": "/subscriptions/a61d8041-614d-4f85-b928-4b24c8abc76c/resourceGroups/spegridehubgrp/providers/Microsoft.Web/serverfarms/spegridehubfuncappPlan", - "reserved": false, - "isXenon": false, - "hyperV": false, - "lastModifiedTimeUtc": "2020-06-09T02:15:32.4033333", - "storageRecoveryDefaultState": "Running", - "contentAvailabilityState": 0, - "runtimeAvailabilityState": 0, - "siteConfig": { - "numberOfWorkers": null, - "defaultDocuments": null, - "netFrameworkVersion": null, - "phpVersion": null, - "pythonVersion": null, - "nodeVersion": null, - "powerShellVersion": null, - "linuxFxVersion": null, - "windowsFxVersion": null, - "requestTracingEnabled": null, - "remoteDebuggingEnabled": null, - "remoteDebuggingVersion": null, - "httpLoggingEnabled": null, - "azureMonitorLogCategories": null, - "acrUseManagedIdentityCreds": false, - "acrUserManagedIdentityID": null, - "logsDirectorySizeLimit": null, - "detailedErrorLoggingEnabled": null, - "publishingUsername": null, - "publishingPassword": null, - "appSettings": null, - "metadata": null, - "connectionStrings": null, - "machineKey": null, - "handlerMappings": null, - "documentRoot": null, - "scmType": null, - "use32BitWorkerProcess": null, - "webSocketsEnabled": null, - "alwaysOn": null, - "javaVersion": null, - "javaContainer": null, - "javaContainerVersion": null, - "appCommandLine": null, - "managedPipelineMode": null, - "virtualApplications": null, - "winAuthAdminState": null, - "winAuthTenantState": null, - "customAppPoolIdentityAdminState": null, - "customAppPoolIdentityTenantState": null, - "runtimeADUser": null, - "runtimeADUserPassword": null, - "loadBalancing": null, - "routingRules": null, - "experiments": null, - "limits": null, - "autoHealEnabled": null, - "autoHealRules": null, - "tracingOptions": null, - "vnetName": null, - "cors": null, - "push": null, - "apiDefinition": null, - "apiManagementConfig": null, - "autoSwapSlotName": null, - "localMySqlEnabled": null, - "managedServiceIdentityId": null, - "xManagedServiceIdentityId": null, - "ipSecurityRestrictions": null, - "scmIpSecurityRestrictions": null, - "scmIpSecurityRestrictionsUseMain": null, - "http20Enabled": null, - "minTlsVersion": null, - "ftpsState": null, - "preWarmedInstanceCount": null, - "healthCheckPath": null, - "fileChangeAuditEnabled": null, - "functionsRuntimeScaleMonitoringEnabled": null, - "websiteTimeZone": null, - "minimumElasticInstanceCount": 0 - }, - "deploymentId": "spegridehubfuncapp", - "trafficManagerHostNames": null, - "sku": "Dynamic", - "scmSiteAlsoStopped": false, - "targetSwapSlot": null, - "hostingEnvironment": null, - "hostingEnvironmentProfile": null, - "clientAffinityEnabled": false, - "clientCertEnabled": false, - "clientCertMode": 0, - "clientCertExclusionPaths": null, - "hostNamesDisabled": false, - "domainVerificationIdentifiers": null, - "customDomainVerificationId": "A92BAA23A498CC9938061E0B8402F7BED64FCEB003CF0C501E2595F2D6423CCA", - "kind": "functionapp", - "inboundIpAddress": "40.121.35.221", - "possibleInboundIpAddresses": "40.121.35.221", - "ftpUsername": "spegridehubfuncapp\\$spegridehubfuncapp", - "ftpsHostName": "ftps://waws-prod-blu-119.ftp.azurewebsites.windows.net/site/wwwroot", - "outboundIpAddresses": "40.121.35.221,40.114.109.158,104.211.29.193,13.68.131.60,40.87.86.14", - "possibleOutboundIpAddresses": "40.121.35.221,40.114.109.158,104.211.29.193,13.68.131.60,40.87.86.14,13.68.130.103,40.87.82.124,13.68.137.247", - "containerSize": 1536, - "dailyMemoryTimeQuota": 0, - "suspendedTill": null, - "siteDisabledReason": 0, - "functionExecutionUnitsCache": null, - "maxNumberOfWorkers": null, - "homeStamp": "waws-prod-blu-119", - "cloningInfo": null, - "hostingEnvironmentId": null, - "tags": null, - "resourceGroup": "spegridehubgrp", - "defaultHostName": "spegridehubfuncapp.azurewebsites.net", - "slotSwapStatus": null, - "httpsOnly": false, - "redundancyMode": 0, - "inProgressOperationId": null, - "geoDistributions": null, - "privateEndpointConnections": [], - "buildVersion": null, - "targetBuildVersion": null - }, - "apiVersion": "2015-05-01" - } - ] - } - } - } - ] -} \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/storage1.arm.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/storage1.arm.json deleted file mode 100644 index 3d50fe537..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/ServiceDependencies/spegridehubfuncapp - Zip Deploy/storage1.arm.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - { - "type": "Microsoft.Resources/resourceGroups", - "name": "spegridehubgrp", - "location": "eastus", - "apiVersion": "2019-10-01" - }, - { - "type": "Microsoft.Resources/deployments", - "name": "[concat('spegridehubgrpDeployment', uniqueString(subscription().subscriptionId))]", - "resourceGroup": "spegridehubgrp", - "apiVersion": "2019-10-01", - "dependsOn": [ - "spegridehubgrp" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - { - "sku": { - "name": "Standard_LRS", - "tier": "Standard" - }, - "kind": "Storage", - "name": "spegridehubstorage", - "type": "Microsoft.Storage/storageAccounts", - "location": "eastus", - "apiVersion": "2017-10-01" - } - ] - } - } - } - ] -} \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.json deleted file mode 100644 index fcc92d112..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "dependencies": { - "storage1": { - "type": "storage", - "connectionId": "AzureWebJobsStorage" - } - } -} \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.local.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.local.json deleted file mode 100644 index 155d87e0d..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.local.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "dependencies": { - "storage1": { - "type": "storage.emulator", - "connectionId": "AzureWebJobsStorage" - } - } -} \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.spegridehubfuncapp - Zip Deploy.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.spegridehubfuncapp - Zip Deploy.json deleted file mode 100644 index 32b928626..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Properties/serviceDependencies.spegridehubfuncapp - Zip Deploy.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "dependencies": { - "storage1": { - "resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroup')]/providers/Microsoft.Storage/storageAccounts/spegridehubstorage", - "type": "storage.azure", - "connectionId": "AzureWebJobsStorage", - "secretStore": "AzureAppSettings" - } - } -} \ No newline at end of file From e9e01dd7b5bb4a32835f5ece855b9d18c579e828 Mon Sep 17 00:00:00 2001 From: spelluru Date: Mon, 7 Dec 2020 21:19:38 -0500 Subject: [PATCH 41/66] updated to use Azure.Messaging.EventHubs 5.2 - latest stable version --- .../WindTurbineDataGenerator/App.config | 8 +++++ .../WindTurbineDataGenerator/Program.cs | 22 +++++++------- .../WindTurbineDataGenerator.csproj | 29 ++++++++++++------- .../WindTurbineDataGenerator/packages.config | 17 ++++++----- 4 files changed, 48 insertions(+), 28 deletions(-) diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config index 8291b54ec..fb51b296b 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config @@ -21,6 +21,14 @@ + + + + + + + + \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs index d34a5f816..6945d2ec1 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Newtonsoft.Json; using Azure.Messaging.EventHubs; +using Azure.Messaging.EventHubs.Producer; namespace WindTurbineDataGenerator { @@ -39,31 +40,30 @@ private static async Task StartEventGenerationAsync(CancellationToken cancellati { var random = new Random((int)DateTimeOffset.UtcNow.Ticks); - // create an Event Hubs client using the namespace connection string and the event hub name - EventHubClient client = new EventHubClient(EventHubConnectionString, EventHubName); - - // create a producer object to send messages to the event hub - EventHubProducer producer = client.CreateProducer(); + // create an Event Hubs Producer client using the namespace connection string and the event hub name + EventHubProducerClient producerClient = new EventHubProducerClient(EventHubConnectionString, EventHubName); while (!cancellationToken.IsCancellationRequested) { try { // Simulate sending data from 100 weather sensors - var devicesData = new List(); - + // prepare a batch of events to send to the event hub. + EventDataBatch eventBatch = await producerClient.CreateBatchAsync(); for (int i = 0; i < 100; i++) { int scaleFactor = random.Next(0, 25); var windTurbineMeasure = GenerateTurbineMeasure("Turbine_" + i, scaleFactor); EventData evData = SerializeWindTurbineToEventData(windTurbineMeasure); - devicesData.Add(evData); + // add the event to the batch + if (eventBatch.TryAdd(evData) == false) + break; } Console.Write("."); - // send the message to the event hub - await producer.SendAsync(devicesData); + // send the batch of events to the event hub + await producerClient.SendAsync(eventBatch); } catch (Exception ex) { @@ -73,7 +73,7 @@ private static async Task StartEventGenerationAsync(CancellationToken cancellati await Task.Delay(1000, cancellationToken); } - } + } private static WindTurbineMeasure GenerateTurbineMeasure(string turbineId, int scaleFactor) { diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj index 9e5da2d22..dac548f6e 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj @@ -32,20 +32,20 @@ 4 - - ..\packages\Azure.Core.1.0.0-preview.9\lib\netstandard2.0\Azure.Core.dll + + ..\packages\Azure.Core.1.5.0\lib\net461\Azure.Core.dll - - ..\packages\Azure.Messaging.EventHubs.5.0.0-preview.4\lib\netstandard2.0\Azure.Messaging.EventHubs.dll + + ..\packages\Azure.Messaging.EventHubs.5.2.0\lib\netstandard2.0\Azure.Messaging.EventHubs.dll - ..\packages\Microsoft.Azure.Amqp.2.4.2\lib\net45\Microsoft.Azure.Amqp.dll + ..\packages\Microsoft.Azure.Amqp.2.4.5\lib\net45\Microsoft.Azure.Amqp.dll ..\packages\Microsoft.Azure.EventHubs.1.0.2\lib\net451\Microsoft.Azure.EventHubs.dll - ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0-rc1.19456.4\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll @@ -56,7 +56,7 @@ - ..\packages\System.Diagnostics.DiagnosticSource.4.6.0-rc1.19456.4\lib\net46\System.Diagnostics.DiagnosticSource.dll + ..\packages\System.Diagnostics.DiagnosticSource.4.6.0\lib\net46\System.Diagnostics.DiagnosticSource.dll ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll @@ -78,8 +78,8 @@ ..\packages\System.Reflection.TypeExtensions.4.5.1\lib\net461\System.Reflection.TypeExtensions.dll - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.6.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll @@ -107,12 +107,21 @@ True True + + ..\packages\System.Text.Encodings.Web.4.6.0\lib\netstandard2.0\System.Text.Encodings.Web.dll + + + ..\packages\System.Text.Json.4.6.0\lib\net461\System.Text.Json.dll + - ..\packages\System.Threading.Channels.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Threading.Channels.dll + ..\packages\System.Threading.Channels.4.6.0\lib\netstandard2.0\System.Threading.Channels.dll ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + + ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll + diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config index 3a3e6b5ca..3283060b8 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config @@ -1,24 +1,27 @@  - - - + + + - + - + - + - + + + + \ No newline at end of file From da5dd91c645dc1e6c517679d0e7d58d80af93a9f Mon Sep 17 00:00:00 2001 From: Lily Ma Date: Tue, 16 Mar 2021 19:56:53 -0700 Subject: [PATCH 42/66] modified readmes to point to Track 2 content; moved files to right folder --- .../Rbac/AzureEventHubsSDK/README.md | 4 ++++ .../Rbac/CustomRole/readme.md | 23 +++++++++++++------ .../Rbac/ManagedIdentityWebApp/README.md | 4 +++- .../SampleEphReceiver/readme.md | 2 ++ .../SampleSender/readme.md | 3 +++ .../ControlAndDataPlane/App.config | 0 .../ControlAndDataPlane.csproj | 0 .../ControlAndDataPlane.sln | 0 .../ControlAndDataPlane/Program.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../ControlAndDataPlane/README.md | 0 .../ControlAndDataPlane/packages.config | 0 .../DotNet}/GeoDRClient/GeoDRClient.sln | 0 .../GeoDRClient/GeoDRClient/App.config | 0 .../GeoDRClient/GeoDRClient.csproj | 0 .../GeoDRClient/GeoDRClient/GeoDRConfig.cs | 0 .../GeoDRClient/GeoDRSampleConfig1.json | 0 .../GeoDRClient/GeoDisasterRecoveryClient.cs | 0 .../GeoDRClient/GeoDRClient/JsonHelper.cs | 0 .../GeoDRClient/GeoDRClient/Program.cs | 0 .../GeoDRClient/GeoDRClient/packages.config | 0 .../DotNet}/GeoDRClient/readme.md | 0 .../EventHubsManagementSample.sln | 0 .../EventHubsManagementSample.cs | 0 .../EventHubsManagementSample.csproj | 0 .../EventHubsManagementSample/Program.cs | 0 .../appsettings.json | 0 .../DotNet/{ => ManagementSample}/README.md | 0 28 files changed, 28 insertions(+), 8 deletions(-) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/App.config (100%) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/ControlAndDataPlane.csproj (100%) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/ControlAndDataPlane.sln (100%) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/Program.cs (100%) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/Properties/AssemblyInfo.cs (100%) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/README.md (100%) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/packages.config (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient.sln (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/App.config (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/GeoDRClient.csproj (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/GeoDRConfig.cs (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/JsonHelper.cs (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/Program.cs (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/packages.config (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/readme.md (100%) rename samples/Management/DotNet/{ => ManagementSample}/EventHubsManagementSample.sln (100%) rename samples/Management/DotNet/{ => ManagementSample}/EventHubsManagementSample/EventHubsManagementSample.cs (100%) rename samples/Management/DotNet/{ => ManagementSample}/EventHubsManagementSample/EventHubsManagementSample.csproj (100%) rename samples/Management/DotNet/{ => ManagementSample}/EventHubsManagementSample/Program.cs (100%) rename samples/Management/DotNet/{ => ManagementSample}/EventHubsManagementSample/appsettings.json (100%) rename samples/Management/DotNet/{ => ManagementSample}/README.md (100%) diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/README.md b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/README.md index 41ced41b3..f9264bd28 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/README.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/README.md @@ -1,3 +1,7 @@ # Role based access sample with Microsoft.Azure.EventHubs SDK # For more information on Role based access (RBAC) and how to run this sample follow [this](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-role-based-access-control) link. + +**Note**: This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly recommend you to use the new library `Azure.Messaging.EventHubs`. + +Leveraging `Azure.Identity`, the new library simplifies the authentication workflow with `DefaultAzureCredential`. Under the hood, `DefaultAzureCredential` combines commonly used credentials, such as managed identity, authentication information set via environment variables or from a logged in Visual Studio Code Azure Account, to authenticate. It attempts to authenticate using the credentials in a specific order. See [here](https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/identity/Azure.Identity#azure-identity-client-library-for-net) for more details. \ No newline at end of file diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/CustomRole/readme.md b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/CustomRole/readme.md index 3a467485b..035a1ca5c 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/CustomRole/readme.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/CustomRole/readme.md @@ -1,12 +1,5 @@ # Receive events with the Event Processor Host in .NET Standard with a custom role which grants Listen claim for Event Hubs and blob claims for Storage accounts. -## Prerequisites - -* [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). -* [.NET Core Visual Studio 2015 or 2017 tools](http://www.microsoft.com/net/core). -* An Azure subscription. -* [An event hub namespace and an event hub](event-hubs-quickstart-namespace-portal.md). -* An Azure Storage account. ## Run the sample @@ -43,3 +36,19 @@ To run the sample, follow these steps: 6. Update the sample with Event Hubs namespace and Storage account name. 7. Run [Sender application](https://github.com/Azure/azure-event-hubs/tree/serkar.AddCustomRbacEhSample/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender) to send some number of messages to your event hub. 8. Run the CustomRole sample to receive those events back. + +**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly recommend you to use the new library `Azure.Messaging.EventHubs`. + +See [this](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/identity/Azure.Identity/samples/DefiningCustomCredentialTypes.md#authenticating-with-the-on-behalf-of-flow) sample that uses the new library to authenticate after the environment variables for client id and secret are set. + + + +## Prerequisites + +* [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). +* [.NET Core Visual Studio 2015 or 2017 tools](http://www.microsoft.com/net/core). +* An Azure subscription. +* [An event hub namespace and an event hub](event-hubs-quickstart-namespace-portal.md). +* An Azure Storage account. + + diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ManagedIdentityWebApp/README.md b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ManagedIdentityWebApp/README.md index febc4f8fc..7f1d7ed92 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ManagedIdentityWebApp/README.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ManagedIdentityWebApp/README.md @@ -1,4 +1,6 @@ # Managed Service Identity sample # -For more information on Managed Service Identity (MSI) and how to run this sample follow [this](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-managed-service-identity) link. +**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly encourage you to use the new library `Azure.Messaging.EventHubs`. Here is the corresponding sample using the new library: [link](https://github.com/Azure/azure-event-hubs/tree/master/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp). + +For more information on Managed Service Identity (MSI) and how to run this sample follow this [link](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-managed-service-identity). diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/readme.md b/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/readme.md index efecf5b65..54ec64de2 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/readme.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/readme.md @@ -2,6 +2,8 @@ This sample shows how to write a .NET Core console application that receives a set of events from an event hub by using the **Event Processor Host** library. You can run the solution as-is, replacing the strings with your event hub and storage account values. The sample is also [available as a tutorial](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-dotnet-standard-getstarted-receive-eph). +**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly encourage you to use the new library `Azure.Messaging.EventHubs`. Here is the corresponding sample using the new library: [link](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs.Processor/samples/Sample04_ProcessingEvents.md). + ## Prerequisites * [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md b/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md index 0054911dc..fcd77503b 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md @@ -2,6 +2,9 @@ This sample shows how to write a .NET Core console application that sends a set of events to an event hub. You can run the solution as-is, replacing the `EhConnectionString` and `EhEntityPath` strings with your event hub values. The sample is also [available as a tutorial](https://docs.microsoft.com/azure/event-hubs/event-hubs-dotnet-standard-getstarted-send). +**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly encourage you to use the new library `Azure.Messaging.EventHubs`. Here is the corresponding sample using the new library: [link](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs/samples/Sample04_PublishingEvents.md). + + ## Prerequisites * [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/App.config b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/App.config similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/App.config rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/App.config diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/ControlAndDataPlane.csproj similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/ControlAndDataPlane.csproj diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/ControlAndDataPlane.sln b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/ControlAndDataPlane.sln similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/ControlAndDataPlane.sln rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/ControlAndDataPlane.sln diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/Program.cs b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/Program.cs similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/Program.cs rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/Program.cs diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/Properties/AssemblyInfo.cs b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/Properties/AssemblyInfo.cs similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/Properties/AssemblyInfo.cs rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/Properties/AssemblyInfo.cs diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/README.md b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/README.md similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/README.md rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/README.md diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/packages.config b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/packages.config similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/packages.config rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/packages.config diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient.sln b/samples/Management/DotNet/GeoDRClient/GeoDRClient.sln similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient.sln rename to samples/Management/DotNet/GeoDRClient/GeoDRClient.sln diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/App.config b/samples/Management/DotNet/GeoDRClient/GeoDRClient/App.config similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/App.config rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/App.config diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRClient.csproj b/samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRClient.csproj similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRClient.csproj rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRClient.csproj diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRConfig.cs b/samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRConfig.cs similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRConfig.cs rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRConfig.cs diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json b/samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs b/samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/JsonHelper.cs b/samples/Management/DotNet/GeoDRClient/GeoDRClient/JsonHelper.cs similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/JsonHelper.cs rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/JsonHelper.cs diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/Program.cs b/samples/Management/DotNet/GeoDRClient/GeoDRClient/Program.cs similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/Program.cs rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/Program.cs diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/packages.config b/samples/Management/DotNet/GeoDRClient/GeoDRClient/packages.config similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/packages.config rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/packages.config diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/readme.md b/samples/Management/DotNet/GeoDRClient/readme.md similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/readme.md rename to samples/Management/DotNet/GeoDRClient/readme.md diff --git a/samples/Management/DotNet/EventHubsManagementSample.sln b/samples/Management/DotNet/ManagementSample/EventHubsManagementSample.sln similarity index 100% rename from samples/Management/DotNet/EventHubsManagementSample.sln rename to samples/Management/DotNet/ManagementSample/EventHubsManagementSample.sln diff --git a/samples/Management/DotNet/EventHubsManagementSample/EventHubsManagementSample.cs b/samples/Management/DotNet/ManagementSample/EventHubsManagementSample/EventHubsManagementSample.cs similarity index 100% rename from samples/Management/DotNet/EventHubsManagementSample/EventHubsManagementSample.cs rename to samples/Management/DotNet/ManagementSample/EventHubsManagementSample/EventHubsManagementSample.cs diff --git a/samples/Management/DotNet/EventHubsManagementSample/EventHubsManagementSample.csproj b/samples/Management/DotNet/ManagementSample/EventHubsManagementSample/EventHubsManagementSample.csproj similarity index 100% rename from samples/Management/DotNet/EventHubsManagementSample/EventHubsManagementSample.csproj rename to samples/Management/DotNet/ManagementSample/EventHubsManagementSample/EventHubsManagementSample.csproj diff --git a/samples/Management/DotNet/EventHubsManagementSample/Program.cs b/samples/Management/DotNet/ManagementSample/EventHubsManagementSample/Program.cs similarity index 100% rename from samples/Management/DotNet/EventHubsManagementSample/Program.cs rename to samples/Management/DotNet/ManagementSample/EventHubsManagementSample/Program.cs diff --git a/samples/Management/DotNet/EventHubsManagementSample/appsettings.json b/samples/Management/DotNet/ManagementSample/EventHubsManagementSample/appsettings.json similarity index 100% rename from samples/Management/DotNet/EventHubsManagementSample/appsettings.json rename to samples/Management/DotNet/ManagementSample/EventHubsManagementSample/appsettings.json diff --git a/samples/Management/DotNet/README.md b/samples/Management/DotNet/ManagementSample/README.md similarity index 100% rename from samples/Management/DotNet/README.md rename to samples/Management/DotNet/ManagementSample/README.md From aa2076560cdbbce0de5a56e86cbb9dde8d0b37cc Mon Sep 17 00:00:00 2001 From: Lily Ma Date: Mon, 22 Mar 2021 17:07:43 -0700 Subject: [PATCH 43/66] addressed review feedback --- .../GeoDRClient/GeoDRClient.sln | 0 .../GeoDRClient/GeoDRClient/App.config | 0 .../GeoDRClient/GeoDRClient.csproj | 0 .../GeoDRClient/GeoDRClient/GeoDRConfig.cs | 0 .../GeoDRClient/GeoDRSampleConfig1.json | 0 .../GeoDRClient/GeoDisasterRecoveryClient.cs | 0 .../GeoDRClient/GeoDRClient/JsonHelper.cs | 0 .../GeoDRClient/GeoDRClient/Program.cs | 0 .../GeoDRClient/GeoDRClient/packages.config | 0 .../GeoDRClient/readme.md | 8 ++++---- .../Rbac/AzureEventHubsSDK/README.md | 7 +++++-- .../Rbac}/ControlAndDataPlane/App.config | 0 .../ControlAndDataPlane.csproj | 0 .../ControlAndDataPlane.sln | 0 .../Rbac}/ControlAndDataPlane/Program.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../Rbac}/ControlAndDataPlane/README.md | 0 .../Rbac}/ControlAndDataPlane/packages.config | 0 .../Rbac/CustomRole/readme.md | 19 +++++++++---------- .../Rbac/ManagedIdentityWebApp/README.md | 2 +- .../SampleSender/readme.md | 14 +++++++------- .../EventHubsManagementSample.sln | 0 .../EventHubsManagementSample.cs | 0 .../EventHubsManagementSample.csproj | 0 .../EventHubsManagementSample/Program.cs | 0 .../appsettings.json | 0 .../DotNet/{ManagementSample => }/README.md | 0 27 files changed, 26 insertions(+), 24 deletions(-) rename samples/{Management/DotNet => DotNet/Microsoft.Azure.EventHubs}/GeoDRClient/GeoDRClient.sln (100%) rename samples/{Management/DotNet => DotNet/Microsoft.Azure.EventHubs}/GeoDRClient/GeoDRClient/App.config (100%) rename samples/{Management/DotNet => DotNet/Microsoft.Azure.EventHubs}/GeoDRClient/GeoDRClient/GeoDRClient.csproj (100%) rename samples/{Management/DotNet => DotNet/Microsoft.Azure.EventHubs}/GeoDRClient/GeoDRClient/GeoDRConfig.cs (100%) rename samples/{Management/DotNet => DotNet/Microsoft.Azure.EventHubs}/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json (100%) rename samples/{Management/DotNet => DotNet/Microsoft.Azure.EventHubs}/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs (100%) rename samples/{Management/DotNet => DotNet/Microsoft.Azure.EventHubs}/GeoDRClient/GeoDRClient/JsonHelper.cs (100%) rename samples/{Management/DotNet => DotNet/Microsoft.Azure.EventHubs}/GeoDRClient/GeoDRClient/Program.cs (100%) rename samples/{Management/DotNet => DotNet/Microsoft.Azure.EventHubs}/GeoDRClient/GeoDRClient/packages.config (100%) rename samples/{Management/DotNet => DotNet/Microsoft.Azure.EventHubs}/GeoDRClient/readme.md (96%) rename samples/DotNet/{Microsoft.ServiceBus => Microsoft.Azure.EventHubs/Rbac}/ControlAndDataPlane/App.config (100%) rename samples/DotNet/{Microsoft.ServiceBus => Microsoft.Azure.EventHubs/Rbac}/ControlAndDataPlane/ControlAndDataPlane.csproj (100%) rename samples/DotNet/{Microsoft.ServiceBus => Microsoft.Azure.EventHubs/Rbac}/ControlAndDataPlane/ControlAndDataPlane.sln (100%) rename samples/DotNet/{Microsoft.ServiceBus => Microsoft.Azure.EventHubs/Rbac}/ControlAndDataPlane/Program.cs (100%) rename samples/DotNet/{Microsoft.ServiceBus => Microsoft.Azure.EventHubs/Rbac}/ControlAndDataPlane/Properties/AssemblyInfo.cs (100%) rename samples/DotNet/{Microsoft.ServiceBus => Microsoft.Azure.EventHubs/Rbac}/ControlAndDataPlane/README.md (100%) rename samples/DotNet/{Microsoft.ServiceBus => Microsoft.Azure.EventHubs/Rbac}/ControlAndDataPlane/packages.config (100%) rename samples/Management/DotNet/{ManagementSample => }/EventHubsManagementSample.sln (100%) rename samples/Management/DotNet/{ManagementSample => }/EventHubsManagementSample/EventHubsManagementSample.cs (100%) rename samples/Management/DotNet/{ManagementSample => }/EventHubsManagementSample/EventHubsManagementSample.csproj (100%) rename samples/Management/DotNet/{ManagementSample => }/EventHubsManagementSample/Program.cs (100%) rename samples/Management/DotNet/{ManagementSample => }/EventHubsManagementSample/appsettings.json (100%) rename samples/Management/DotNet/{ManagementSample => }/README.md (100%) diff --git a/samples/Management/DotNet/GeoDRClient/GeoDRClient.sln b/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient.sln similarity index 100% rename from samples/Management/DotNet/GeoDRClient/GeoDRClient.sln rename to samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient.sln diff --git a/samples/Management/DotNet/GeoDRClient/GeoDRClient/App.config b/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/App.config similarity index 100% rename from samples/Management/DotNet/GeoDRClient/GeoDRClient/App.config rename to samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/App.config diff --git a/samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRClient.csproj b/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRClient.csproj similarity index 100% rename from samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRClient.csproj rename to samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRClient.csproj diff --git a/samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRConfig.cs b/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRConfig.cs similarity index 100% rename from samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRConfig.cs rename to samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRConfig.cs diff --git a/samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json b/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json similarity index 100% rename from samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json rename to samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json diff --git a/samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs b/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs similarity index 100% rename from samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs rename to samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs diff --git a/samples/Management/DotNet/GeoDRClient/GeoDRClient/JsonHelper.cs b/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/JsonHelper.cs similarity index 100% rename from samples/Management/DotNet/GeoDRClient/GeoDRClient/JsonHelper.cs rename to samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/JsonHelper.cs diff --git a/samples/Management/DotNet/GeoDRClient/GeoDRClient/Program.cs b/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/Program.cs similarity index 100% rename from samples/Management/DotNet/GeoDRClient/GeoDRClient/Program.cs rename to samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/Program.cs diff --git a/samples/Management/DotNet/GeoDRClient/GeoDRClient/packages.config b/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/packages.config similarity index 100% rename from samples/Management/DotNet/GeoDRClient/GeoDRClient/packages.config rename to samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/packages.config diff --git a/samples/Management/DotNet/GeoDRClient/readme.md b/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/readme.md similarity index 96% rename from samples/Management/DotNet/GeoDRClient/readme.md rename to samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/readme.md index 30a6c02a5..f3d264d40 100644 --- a/samples/Management/DotNet/GeoDRClient/readme.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/readme.md @@ -52,7 +52,7 @@ For more information on creating a Service Principal, refer to the following art The Geo DR actions could be * CreatePairing -For creating a paired region. After this, you should see metadata (i.e. event hubs, consumer groups, throughput units etc. replicated to the secondary namespace). +For creating a paired region. After this, you should see metadata (i.e. Event Hubs, consumer groups, throughput units etc. replicated to the secondary namespace). * FailOver Simulating a failover. After this action, the secondary namespace becomes the primary @@ -64,7 +64,7 @@ For breaking the pairing between a primary and secondary namespace For deleting an alias, that contains information about the primary-secondary pairing * GetConnectionStrings -In a Geo DR enabled namespace, the Event Hubs should be accessed only via the alias. This is because, the alias can point to either the primary event hub or the failed over event hub. This way, the user does not have to adjust the connection strings in his/her apps to point to a different event hub in the case of a failover. +In a Geo DR enabled namespace, the Event Hubs should be accessed only via the alias. This is because, the alias can point to either the primary Event Hub or the failed over Event Hub. This way, the user does not have to adjust the connection strings in his/her apps to point to a different Event Hub in the case of a failover. Examples * EventHubsGeoDRManagementSample.exe CreatePairing GeoDRSampleConfig.json @@ -86,7 +86,7 @@ The following section describes the steps for performing Geo-diaster recovery, d. Changing the names of an alias is not allowed. e. Changing the secondary namespace is not allowed. 3. Create an alias and provide the primary and secondary namespaces to complete the pairing. -4. Get the required connection strings on the alias to connect to your event hubs. +4. Get the required connection strings on the alias to connect to your Event Hubs. 5. Once the namespaces are paired with an alias, the metadata is replicated periodically in both namespaces. **Note:** Creating a pairing, failing over, breaking the pairing, deleting the alias have all retries build in. All before mentioned operations will retry 10 times with 10 minutes in between each attempt. @@ -95,7 +95,7 @@ The following section describes the steps for performing Geo-diaster recovery, After this step, the seconday namespace becomes the primary namespace. 1. Initiate a fail-over. This step is only performed on the secondary namespace. The geo-pairing is broken and the alias now points to the secondary namespace. **Note:** The Failover can take a few minutes to complete. -2. Senders and receivers still connect to the event hubs using the alias. The failover does not disrupt the connection. +2. Senders and receivers still connect to the Event Hubs using the alias. The failover does not disrupt the connection. 3. Because the pairing is broken, the old primary namespace no longer has a replication status associated with it. 4. The metadata synchronization between the primary and secondary namespaces also stops diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/README.md b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/README.md index f9264bd28..db941fc65 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/README.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/README.md @@ -2,6 +2,9 @@ For more information on Role based access (RBAC) and how to run this sample follow [this](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-role-based-access-control) link. -**Note**: This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly recommend you to use the new library `Azure.Messaging.EventHubs`. +**Note**: This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. +We strongly recommend you to use the current version of the library `Azure.Messaging.EventHubs`. -Leveraging `Azure.Identity`, the new library simplifies the authentication workflow with `DefaultAzureCredential`. Under the hood, `DefaultAzureCredential` combines commonly used credentials, such as managed identity, authentication information set via environment variables or from a logged in Visual Studio Code Azure Account, to authenticate. It attempts to authenticate using the credentials in a specific order. See [here](https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/identity/Azure.Identity#azure-identity-client-library-for-net) for more details. \ No newline at end of file +Authorization was one of the most consistent areas of feedback for the Azure SDKs from our customers. Libraries for different Azure services did not have a consistent approach to authorization, roles, etc. The APIs also did not offer a good, approachable, and consistent story for integrating with Azure Active Directory principals. As such, many developers felt that the learning curve was difficult. + +The [Azure.Identity](https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/identity/Azure.Identity#azure-identity-client-library-for-net) library is intended to address that feedback and provide an approachable and flexible authentication experience across the Azure SDKs, including the `Azure.Messaging.EventHubs` one. diff --git a/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/App.config b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/App.config similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/App.config rename to samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/App.config diff --git a/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/ControlAndDataPlane.csproj b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/ControlAndDataPlane.csproj rename to samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj diff --git a/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/ControlAndDataPlane.sln b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/ControlAndDataPlane.sln similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/ControlAndDataPlane.sln rename to samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/ControlAndDataPlane.sln diff --git a/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/Program.cs b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/Program.cs similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/Program.cs rename to samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/Program.cs diff --git a/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/Properties/AssemblyInfo.cs b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/Properties/AssemblyInfo.cs similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/Properties/AssemblyInfo.cs rename to samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/Properties/AssemblyInfo.cs diff --git a/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/README.md b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/README.md similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/README.md rename to samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/README.md diff --git a/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/packages.config b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/packages.config similarity index 100% rename from samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/packages.config rename to samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/packages.config diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/CustomRole/readme.md b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/CustomRole/readme.md index 035a1ca5c..7854f29f4 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/CustomRole/readme.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/CustomRole/readme.md @@ -3,10 +3,14 @@ ## Run the sample -To run the sample, follow these steps: +**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly recommend you to use the current library `Azure.Messaging.EventHubs`. + +See [sample](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/identity/Azure.Identity/samples/DefiningCustomCredentialTypes.md#authenticating-with-the-on-behalf-of-flow) that uses the new library to authenticate after the environment variables for client id and secret are set. + +To run the sample in this folder, which uses the legacy library, follow these steps: 1. Clone or download this GitHub repo. -2. [Create an Event Hubs namespace and an event hub](https://docs.microsoft.com/azure/event-hubs/event-hubs-create). +2. [Create an Event Hubs namespace and an Event Hub](https://docs.microsoft.com/azure/event-hubs/event-hubs-create). 3. Create a Storage account to host a blob container, needed for lease management by the Event Processor Host. 3. [Create a new custom role](https://docs.microsoft.com/en-us/azure/role-based-access-control/custom-roles) with the definition below. 4. [Create a new AAD (Azure Active Directory) application](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal). @@ -34,21 +38,16 @@ To run the sample, follow these steps: ``` 6. Update the sample with Event Hubs namespace and Storage account name. -7. Run [Sender application](https://github.com/Azure/azure-event-hubs/tree/serkar.AddCustomRbacEhSample/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender) to send some number of messages to your event hub. +7. Run [Sender application](https://github.com/Azure/azure-event-hubs/tree/serkar.AddCustomRbacEhSample/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender) to send some number of messages to your Event Hub. 8. Run the CustomRole sample to receive those events back. -**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly recommend you to use the new library `Azure.Messaging.EventHubs`. - -See [this](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/identity/Azure.Identity/samples/DefiningCustomCredentialTypes.md#authenticating-with-the-on-behalf-of-flow) sample that uses the new library to authenticate after the environment variables for client id and secret are set. - - ## Prerequisites * [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). -* [.NET Core Visual Studio 2015 or 2017 tools](http://www.microsoft.com/net/core). +* [.NET Core SDK](http://www.microsoft.com/net/core). * An Azure subscription. -* [An event hub namespace and an event hub](event-hubs-quickstart-namespace-portal.md). +* [An Event Hub namespace and an Event Hub](event-hubs-quickstart-namespace-portal.md). * An Azure Storage account. diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ManagedIdentityWebApp/README.md b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ManagedIdentityWebApp/README.md index 7f1d7ed92..c1c2af8d3 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ManagedIdentityWebApp/README.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ManagedIdentityWebApp/README.md @@ -1,6 +1,6 @@ # Managed Service Identity sample # -**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly encourage you to use the new library `Azure.Messaging.EventHubs`. Here is the corresponding sample using the new library: [link](https://github.com/Azure/azure-event-hubs/tree/master/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp). +**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly encourage you to use the current library `Azure.Messaging.EventHubs`. See the [corresponding sample](https://github.com/Azure/azure-event-hubs/tree/master/samples/DotNet/Azure.Messaging.EventHubs/ManagedIdentityWebApp) that uses the current library. For more information on Managed Service Identity (MSI) and how to run this sample follow this [link](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-managed-service-identity). diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md b/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md index fcd77503b..d230ba05b 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md @@ -1,32 +1,32 @@ # Send events to Azure Event Hubs in .NET Standard -This sample shows how to write a .NET Core console application that sends a set of events to an event hub. You can run the solution as-is, replacing the `EhConnectionString` and `EhEntityPath` strings with your event hub values. The sample is also [available as a tutorial](https://docs.microsoft.com/azure/event-hubs/event-hubs-dotnet-standard-getstarted-send). +This sample shows how to write a .NET Core console application that sends a set of events to an Event Hub. You can run the solution as-is, replacing the `EhConnectionString` and `EhEntityPath` strings with your Event Hub values. The sample is also [available as a tutorial](https://docs.microsoft.com/azure/event-hubs/event-hubs-dotnet-standard-getstarted-send). -**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly encourage you to use the new library `Azure.Messaging.EventHubs`. Here is the corresponding sample using the new library: [link](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs/samples/Sample04_PublishingEvents.md). +**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly encourage you to use the current library `Azure.Messaging.EventHubs`. See the [corresponding sample](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs/samples/Sample04_PublishingEvents.md) that uses the current library. ## Prerequisites * [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). -* [.NET Core Visual Studio 2015 or 2017 tools](http://www.microsoft.com/net/core). +* [.NET Core SDK](http://www.microsoft.com/net/core). * An Azure subscription. -* [An event hub namespace and an event hub](event-hubs-quickstart-namespace-portal.md). +* [An Event Hub namespace and an Event Hub](event-hubs-quickstart-namespace-portal.md). ## Run the sample To run the sample, follow these steps: 1. Clone or download this GitHub repo. -2. [Create an Event Hubs namespace and an event hub](https://docs.microsoft.com/azure/event-hubs/event-hubs-create). +2. [Create an Event Hubs namespace and an Event Hub](https://docs.microsoft.com/azure/event-hubs/event-hubs-create). 3. In Visual Studio, select **File**, then **Open Project/Soultion**. Navigate to the \azure-event-hubs\samples\DotNet\Microsoft.Azure.EventHubs\SampleSender folder. 4. Load the SampleSender.sln solution file into Visual Studio. 5. Add the [Microsoft.Azure.EventHubs](https://www.nuget.org/packages/Microsoft.Azure.EventHubs/) NuGet package to the project. -6. In Program.cs, replace the placeholders in brackets with the proper values that were obtained when creating the event hub. Make sure that the `Event Hubs connection string` is the namespace-level connection string, and not the event hub string: +6. In Program.cs, replace the placeholders in brackets with the proper values that were obtained when creating the Event Hub. Make sure that the `Event Hubs connection string` is the namespace-level connection string, and not the Event Hub string: ```csharp private const string EhConnectionString = "Event Hubs connection string"; private const string EhEntityPath = "Event Hub name"; ``` 7. Run the program, and ensure that there are no errors. -Congratulations! You have now sent events to an event hub. To receive these events, see the [SampleEphReceiver](https://github.com/Azure/azure-event-hubs/tree/master/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver) sample. +Congratulations! You have now sent events to an Event Hub. To receive these events, see the [SampleEphReceiver](https://github.com/Azure/azure-event-hubs/tree/master/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver) sample. diff --git a/samples/Management/DotNet/ManagementSample/EventHubsManagementSample.sln b/samples/Management/DotNet/EventHubsManagementSample.sln similarity index 100% rename from samples/Management/DotNet/ManagementSample/EventHubsManagementSample.sln rename to samples/Management/DotNet/EventHubsManagementSample.sln diff --git a/samples/Management/DotNet/ManagementSample/EventHubsManagementSample/EventHubsManagementSample.cs b/samples/Management/DotNet/EventHubsManagementSample/EventHubsManagementSample.cs similarity index 100% rename from samples/Management/DotNet/ManagementSample/EventHubsManagementSample/EventHubsManagementSample.cs rename to samples/Management/DotNet/EventHubsManagementSample/EventHubsManagementSample.cs diff --git a/samples/Management/DotNet/ManagementSample/EventHubsManagementSample/EventHubsManagementSample.csproj b/samples/Management/DotNet/EventHubsManagementSample/EventHubsManagementSample.csproj similarity index 100% rename from samples/Management/DotNet/ManagementSample/EventHubsManagementSample/EventHubsManagementSample.csproj rename to samples/Management/DotNet/EventHubsManagementSample/EventHubsManagementSample.csproj diff --git a/samples/Management/DotNet/ManagementSample/EventHubsManagementSample/Program.cs b/samples/Management/DotNet/EventHubsManagementSample/Program.cs similarity index 100% rename from samples/Management/DotNet/ManagementSample/EventHubsManagementSample/Program.cs rename to samples/Management/DotNet/EventHubsManagementSample/Program.cs diff --git a/samples/Management/DotNet/ManagementSample/EventHubsManagementSample/appsettings.json b/samples/Management/DotNet/EventHubsManagementSample/appsettings.json similarity index 100% rename from samples/Management/DotNet/ManagementSample/EventHubsManagementSample/appsettings.json rename to samples/Management/DotNet/EventHubsManagementSample/appsettings.json diff --git a/samples/Management/DotNet/ManagementSample/README.md b/samples/Management/DotNet/README.md similarity index 100% rename from samples/Management/DotNet/ManagementSample/README.md rename to samples/Management/DotNet/README.md From 8576c5ef0d768e892de8eda580df24ed18199f17 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Fri, 2 Apr 2021 14:57:22 -0700 Subject: [PATCH 44/66] Simplify readme for RBAC --- .../Rbac/AzureEventHubsSDK/README.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/README.md b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/README.md index db941fc65..9c69c3576 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/README.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/README.md @@ -1,10 +1,6 @@ -# Role based access sample with Microsoft.Azure.EventHubs SDK # +# Role based access sample with Microsoft.Azure.EventHubs SDK -For more information on Role based access (RBAC) and how to run this sample follow [this](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-role-based-access-control) link. +See [Authorize access to Event Hubs resources using Azure Active Directory](https://docs.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory) for information on Role based access (RBAC). -**Note**: This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. -We strongly recommend you to use the current version of the library `Azure.Messaging.EventHubs`. - -Authorization was one of the most consistent areas of feedback for the Azure SDKs from our customers. Libraries for different Azure services did not have a consistent approach to authorization, roles, etc. The APIs also did not offer a good, approachable, and consistent story for integrating with Azure Active Directory principals. As such, many developers felt that the learning curve was difficult. - -The [Azure.Identity](https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/identity/Azure.Identity#azure-identity-client-library-for-net) library is intended to address that feedback and provide an approachable and flexible authentication experience across the Azure SDKs, including the `Azure.Messaging.EventHubs` one. +**Note**: This sample shows different ways to authenticate using Azure Active Directory with the legacy Event Hubs library `Microsoft.Azure.EventHubs`. +For the current version of the library `Azure.Messaging.EventHubs`, please see the [sample that makes use of credentials from Azure.Identity](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs/samples/Sample06_IdentityAndSharedAccessCredentials.md). From 719324bed39237ff86d8e6b77fcccb74375e0e09 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Fri, 2 Apr 2021 15:25:10 -0700 Subject: [PATCH 45/66] Re-order steps for custom role sample for clarity --- .../Rbac/CustomRole/readme.md | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/CustomRole/readme.md b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/CustomRole/readme.md index 7854f29f4..64ed0c7c1 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/CustomRole/readme.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/CustomRole/readme.md @@ -1,25 +1,25 @@ # Receive events with the Event Processor Host in .NET Standard with a custom role which grants Listen claim for Event Hubs and blob claims for Storage accounts. +**Note:** The sample in this folder uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly recommend you to use the current library `Azure.Messaging.EventHubs`. This file has instructions for both. -## Run the sample - -**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly recommend you to use the current library `Azure.Messaging.EventHubs`. +## Prerequisites -See [sample](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/identity/Azure.Identity/samples/DefiningCustomCredentialTypes.md#authenticating-with-the-on-behalf-of-flow) that uses the new library to authenticate after the environment variables for client id and secret are set. +- [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). +- [.NET Core SDK](http://www.microsoft.com/net/core). +- An [Azure subscription](https://azure.microsoft.com/free/). -To run the sample in this folder, which uses the legacy library, follow these steps: +## Set up for custom role -1. Clone or download this GitHub repo. -2. [Create an Event Hubs namespace and an Event Hub](https://docs.microsoft.com/azure/event-hubs/event-hubs-create). -3. Create a Storage account to host a blob container, needed for lease management by the Event Processor Host. +1. [Create an Event Hubs namespace and an Event Hub](https://docs.microsoft.com/azure/event-hubs/event-hubs-create). +2. Create a Storage account to host a blob container, needed to store checkpoints and information required for balance load among partitions. 3. [Create a new custom role](https://docs.microsoft.com/en-us/azure/role-based-access-control/custom-roles) with the definition below. 4. [Create a new AAD (Azure Active Directory) application](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal). 5. Assign AAD application to both Event Hubs namespace and Storage account with the custom role you just created. ``` { - "Name": "Custom role for RBAC sample", - "Id": "8ddab47f-cf99-4b04-8fc3-1d2d857fb931", + "Name": "Custom role for RBAC sample", + "Id": "8ddab47f-cf99-4b04-8fc3-1d2d857fb931", "Description": "Test role", "IsCustom": true, "Actions": [ @@ -37,17 +37,20 @@ To run the sample in this folder, which uses the legacy library, follow these st } ``` -6. Update the sample with Event Hubs namespace and Storage account name. -7. Run [Sender application](https://github.com/Azure/azure-event-hubs/tree/serkar.AddCustomRbacEhSample/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender) to send some number of messages to your Event Hub. -8. Run the CustomRole sample to receive those events back. +## Run the sample for legacy library Microsoft.Azure.EventHubs +After following the [set up steps](#set-up-for-custom-role), to run the sample in this folder to receive events, which uses the legacy library, follow these steps: -## Prerequisites +1. Clone or download this GitHub repo. +2. Run [Sender application](https://github.com/Azure/azure-event-hubs/tree/serkar.AddCustomRbacEhSample/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender) to send some number of events to your Event Hub instance. +3. Run the CustomRole sample to receive those events back. -* [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). -* [.NET Core SDK](http://www.microsoft.com/net/core). -* An Azure subscription. -* [An Event Hub namespace and an Event Hub](event-hubs-quickstart-namespace-portal.md). -* An Azure Storage account. +## Run the sample for current library Azure.Messaging.EventHubs +After following the [set up steps](#set-up-for-custom-role), to the run the sample to receive events using the current library, follow these steps: +1. Follow the sample in [Publish events using Azure.Messaging.EventHubs](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs/samples/Sample04_PublishingEvents.md) to send some number of events to your Event Hub instance. +2. Follow the sample in [Processing events with identity-based authorization using Azure.Messaging.EventHubs.Processor](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs.Processor/samples/Sample05_IdentityAndSharedAccessCredentials.md#processing-events-with-identity-based-authorization) to receive the events. To make use of the custom role, set the below environment variables that will be picked up by the `DefaultAzureCredential` used in the sample. + - AZURE_TENANT_ID + - AZURE_CLIENT_ID + - AZURE_CLIENT_SECRET From de8fe2385eb27bd4115ac00fbec807a1d0c9430a Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Fri, 2 Apr 2021 15:36:14 -0700 Subject: [PATCH 46/66] Consolidate intro and note, use quick start links --- .../SampleEphReceiver/readme.md | 26 ++++++++++--------- .../SampleSender/readme.md | 22 +++++++--------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/readme.md b/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/readme.md index 54ec64de2..e7a9eac27 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/readme.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/readme.md @@ -1,16 +1,16 @@ # Receive events with the Event Processor Host in .NET Standard -This sample shows how to write a .NET Core console application that receives a set of events from an event hub by using the **Event Processor Host** library. You can run the solution as-is, replacing the strings with your event hub and storage account values. The sample is also [available as a tutorial](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-dotnet-standard-getstarted-receive-eph). +**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs.Processor` to write a .NET Core console application that receives a set of events from an Event Hub instance. We strongly encourage you to refer to the [quick start that uses the new library `Azure.Messaging.EventHubs.Processor`](https://docs.microsoft.com/azure/event-hubs/event-hubs-dotnet-standard-getstarted-send#receive-events) instead. -**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly encourage you to use the new library `Azure.Messaging.EventHubs`. Here is the corresponding sample using the new library: [link](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs.Processor/samples/Sample04_ProcessingEvents.md). +You can run the solution as-is, replacing the strings with your event hub and storage account values. ## Prerequisites -* [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). -* [.NET Core Visual Studio 2015 or 2017 tools](http://www.microsoft.com/net/core). -* An Azure subscription. -* [An event hub namespace and an event hub](event-hubs-quickstart-namespace-portal.md). -* An Azure Storage account. +- [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). +- [.NET Core Visual Studio 2015 or 2017 tools](http://www.microsoft.com/net/core). +- An [Azure subscription](https://azure.microsoft.com/free/). +- [An event hub namespace and an event hub](event-hubs-quickstart-namespace-portal.md). +- An Azure Storage account. ## Run the sample @@ -22,17 +22,19 @@ To run the sample, follow these steps: 4. Load the SampleEphReceiver.sln solution file into Visual Studio. 5. Add the [Microsoft.Azure.EventHubs](https://www.nuget.org/packages/Microsoft.Azure.EventHubs/) and [Microsoft.Azure.EventHubs.Processor](https://www.nuget.org/packages/Microsoft.Azure.EventHubs.Processor/) NuGet packages to the project. 6. In Program.cs, replace the following constants with the corresponding values for the event hub connection string, event hub name: - ```csharp - private const string EventHubConnectionString = "Event Hubs connection string"; - private const string EventHubName = "Event Hub name"; - ``` -7. Create a Storage account to host a blob container, needed for lease management by the Event Processor Host. + ```csharp + private const string EventHubConnectionString = "Event Hubs connection string"; + private const string EventHubName = "Event Hub name"; + ``` +7. Create a Storage account to host a blob container, needed for lease management by the Event Processor Host. 8. In Program.cs, replace the storage account container name, storage account name, and storage account key (the container will be created if not present): + ``` private const string StorageContainerName = "Storage account container name"; private const string StorageAccountName = "Storage account name"; private const string StorageAccountKey = "Storage account key"; ``` + 9. Run the program, and ensure that there are no errors. Congratulations! You have now received events from an event hub by using the Event Processor Host. To send events, see the [SampleSender](https://github.com/Azure/azure-event-hubs/tree/master/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender) sample. diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md b/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md index d230ba05b..1c2322946 100644 --- a/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md +++ b/samples/DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md @@ -1,16 +1,15 @@ # Send events to Azure Event Hubs in .NET Standard -This sample shows how to write a .NET Core console application that sends a set of events to an Event Hub. You can run the solution as-is, replacing the `EhConnectionString` and `EhEntityPath` strings with your Event Hub values. The sample is also [available as a tutorial](https://docs.microsoft.com/azure/event-hubs/event-hubs-dotnet-standard-getstarted-send). - -**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs`. We strongly encourage you to use the current library `Azure.Messaging.EventHubs`. See the [corresponding sample](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs/samples/Sample04_PublishingEvents.md) that uses the current library. +**Note:** This sample uses the legacy Event Hubs library `Microsoft.Azure.EventHubs.Processor` to write a .NET Core console application that sends a set of events to an Event Hub instance. We strongly encourage you to refer to the [quick start that uses the new library `Azure.Messaging.EventHubs`](https://docs.microsoft.com/azure/event-hubs/event-hubs-dotnet-standard-getstarted-send#send-events) instead. +You can run the solution as-is, replacing the strings with your Event Hub instance details like connection string and name. ## Prerequisites -* [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). -* [.NET Core SDK](http://www.microsoft.com/net/core). -* An Azure subscription. -* [An Event Hub namespace and an Event Hub](event-hubs-quickstart-namespace-portal.md). +- [Microsoft Visual Studio 2015 or 2017](http://www.visualstudio.com). +- [.NET Core SDK](http://www.microsoft.com/net/core). +- An [Azure subscription](https://azure.microsoft.com/free/). +- [An Event Hub namespace and an Event Hub](event-hubs-quickstart-namespace-portal.md). ## Run the sample @@ -22,11 +21,10 @@ To run the sample, follow these steps: 4. Load the SampleSender.sln solution file into Visual Studio. 5. Add the [Microsoft.Azure.EventHubs](https://www.nuget.org/packages/Microsoft.Azure.EventHubs/) NuGet package to the project. 6. In Program.cs, replace the placeholders in brackets with the proper values that were obtained when creating the Event Hub. Make sure that the `Event Hubs connection string` is the namespace-level connection string, and not the Event Hub string: - ```csharp - private const string EhConnectionString = "Event Hubs connection string"; - private const string EhEntityPath = "Event Hub name"; - ``` + ```csharp + private const string EhConnectionString = "Event Hubs connection string"; + private const string EhEntityPath = "Event Hub name"; + ``` 7. Run the program, and ensure that there are no errors. Congratulations! You have now sent events to an Event Hub. To receive these events, see the [SampleEphReceiver](https://github.com/Azure/azure-event-hubs/tree/master/samples/DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver) sample. - From 97caf5121323d8bf81a3257b1e3fa528e606022e Mon Sep 17 00:00:00 2001 From: Lily Ma Date: Tue, 6 Apr 2021 18:52:33 -0700 Subject: [PATCH 47/66] moved samples to approach directories --- .../Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/App.config | 0 .../ControlAndDataPlane/ControlAndDataPlane.csproj | 0 .../ControlAndDataPlane/ControlAndDataPlane.sln | 0 .../Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/Program.cs | 0 .../ControlAndDataPlane/Properties/AssemblyInfo.cs | 0 .../Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/README.md | 0 .../ControlAndDataPlane/packages.config | 0 .../{ => EventHubsManagementSample}/EventHubsManagementSample.sln | 0 .../Management/DotNet/{ => EventHubsManagementSample}/README.md | 0 .../DotNet}/GeoDRClient/GeoDRClient.sln | 0 .../DotNet}/GeoDRClient/GeoDRClient/App.config | 0 .../DotNet}/GeoDRClient/GeoDRClient/GeoDRClient.csproj | 0 .../DotNet}/GeoDRClient/GeoDRClient/GeoDRConfig.cs | 0 .../DotNet}/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json | 0 .../DotNet}/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs | 0 .../DotNet}/GeoDRClient/GeoDRClient/JsonHelper.cs | 0 .../DotNet}/GeoDRClient/GeoDRClient/Program.cs | 0 .../DotNet}/GeoDRClient/GeoDRClient/packages.config | 0 .../DotNet}/GeoDRClient/readme.md | 0 19 files changed, 0 insertions(+), 0 deletions(-) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/App.config (100%) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/ControlAndDataPlane.csproj (100%) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/ControlAndDataPlane.sln (100%) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/Program.cs (100%) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/Properties/AssemblyInfo.cs (100%) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/README.md (100%) rename samples/DotNet/{Microsoft.Azure.EventHubs/Rbac => Microsoft.ServiceBus}/ControlAndDataPlane/packages.config (100%) rename samples/Management/DotNet/{ => EventHubsManagementSample}/EventHubsManagementSample.sln (100%) rename samples/Management/DotNet/{ => EventHubsManagementSample}/README.md (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient.sln (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/App.config (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/GeoDRClient.csproj (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/GeoDRConfig.cs (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/JsonHelper.cs (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/Program.cs (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/GeoDRClient/packages.config (100%) rename samples/{DotNet/Microsoft.Azure.EventHubs => Management/DotNet}/GeoDRClient/readme.md (100%) diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/App.config b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/App.config similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/App.config rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/App.config diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/ControlAndDataPlane.csproj similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/ControlAndDataPlane.csproj rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/ControlAndDataPlane.csproj diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/ControlAndDataPlane.sln b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/ControlAndDataPlane.sln similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/ControlAndDataPlane.sln rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/ControlAndDataPlane.sln diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/Program.cs b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/Program.cs similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/Program.cs rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/Program.cs diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/Properties/AssemblyInfo.cs b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/Properties/AssemblyInfo.cs similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/Properties/AssemblyInfo.cs rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/Properties/AssemblyInfo.cs diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/README.md b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/README.md similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/README.md rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/README.md diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/packages.config b/samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/packages.config similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/Rbac/ControlAndDataPlane/packages.config rename to samples/DotNet/Microsoft.ServiceBus/ControlAndDataPlane/packages.config diff --git a/samples/Management/DotNet/EventHubsManagementSample.sln b/samples/Management/DotNet/EventHubsManagementSample/EventHubsManagementSample.sln similarity index 100% rename from samples/Management/DotNet/EventHubsManagementSample.sln rename to samples/Management/DotNet/EventHubsManagementSample/EventHubsManagementSample.sln diff --git a/samples/Management/DotNet/README.md b/samples/Management/DotNet/EventHubsManagementSample/README.md similarity index 100% rename from samples/Management/DotNet/README.md rename to samples/Management/DotNet/EventHubsManagementSample/README.md diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient.sln b/samples/Management/DotNet/GeoDRClient/GeoDRClient.sln similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient.sln rename to samples/Management/DotNet/GeoDRClient/GeoDRClient.sln diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/App.config b/samples/Management/DotNet/GeoDRClient/GeoDRClient/App.config similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/App.config rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/App.config diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRClient.csproj b/samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRClient.csproj similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRClient.csproj rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRClient.csproj diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRConfig.cs b/samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRConfig.cs similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRConfig.cs rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRConfig.cs diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json b/samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDRSampleConfig1.json diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs b/samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/GeoDisasterRecoveryClient.cs diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/JsonHelper.cs b/samples/Management/DotNet/GeoDRClient/GeoDRClient/JsonHelper.cs similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/JsonHelper.cs rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/JsonHelper.cs diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/Program.cs b/samples/Management/DotNet/GeoDRClient/GeoDRClient/Program.cs similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/Program.cs rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/Program.cs diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/packages.config b/samples/Management/DotNet/GeoDRClient/GeoDRClient/packages.config similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/GeoDRClient/packages.config rename to samples/Management/DotNet/GeoDRClient/GeoDRClient/packages.config diff --git a/samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/readme.md b/samples/Management/DotNet/GeoDRClient/readme.md similarity index 100% rename from samples/DotNet/Microsoft.Azure.EventHubs/GeoDRClient/readme.md rename to samples/Management/DotNet/GeoDRClient/readme.md From 136235345b8ac82cca100dab2e96acaa4c635951 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Thu, 8 Apr 2021 17:54:25 -0700 Subject: [PATCH 48/66] Remove duplicate sample for EventHubsCaptureEventGridDemo --- .../DWDumper/App.config | 26 --- .../DWDumper/DWDumper.csproj | 112 ------------- .../DWDumper/Program.cs | 121 -------------- .../DWDumper/Properties/AssemblyInfo.cs | 36 ---- .../DWDumper/WindTurbineMeasure.cs | 16 -- .../DWDumper/packages.config | 26 --- .../EventHubsCaptureEventGridDemo.sln | 37 ----- .../FunctionEGDWDumper/EventGridEvent.cs | 32 ---- .../FunctionEGDWDumper/Function1.cs | 155 ------------------ .../FunctionEGDWDumper.csproj | 23 --- .../FunctionEGDWDumper/WindTurbineMeasure.cs | 18 -- .../FunctionEGDWDumper/host.json | 2 - .../FunctionEGDWDumper/local.settings.json | 7 - .../EventHubsCaptureEventGridDemo/Readme.md | 3 - .../WindTurbineDataGenerator/App.config | 26 --- .../WindTurbineDataGenerator/Program.cs | 97 ----------- .../Properties/AssemblyInfo.cs | 36 ---- .../WindTurbineDataGenerator.csproj | 133 --------------- .../WindTurbineMeasure.cs | 17 -- .../WindTurbineDataGenerator/packages.config | 24 --- .../scripts/CreateDataWarehouseTable.sql | 8 - 21 files changed, 955 deletions(-) delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/App.config delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Properties/AssemblyInfo.cs delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/packages.config delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/WindTurbineMeasure.cs delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/local.settings.json delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/Readme.md delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Properties/AssemblyInfo.cs delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineMeasure.cs delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config delete mode 100644 samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/scripts/CreateDataWarehouseTable.sql diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/App.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/App.config deleted file mode 100644 index 85ce03b61..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/App.config +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj deleted file mode 100644 index 0a5934ba9..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj +++ /dev/null @@ -1,112 +0,0 @@ - - - - - Debug - AnyCPU - {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3} - Exe - DWDumper - DWDumper - v4.6.1 - 512 - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Apache.Avro.1.7.7.2\lib\Avro.dll - - - ..\packages\Azure.Core.1.0.1\lib\netstandard2.0\Azure.Core.dll - - - ..\packages\Azure.Storage.Blobs.12.1.0\lib\netstandard2.0\Azure.Storage.Blobs.dll - - - ..\packages\Azure.Storage.Common.12.1.0\lib\netstandard2.0\Azure.Storage.Common.dll - - - ..\packages\log4net.1.2.10\lib\2.0\log4net.dll - - - ..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll - - - ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll - - - ..\packages\Microsoft.Data.Edm.5.8.2\lib\net40\Microsoft.Data.Edm.dll - - - ..\packages\Microsoft.Data.OData.5.8.2\lib\net40\Microsoft.Data.OData.dll - - - ..\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll - - - ..\packages\WindowsAzure.Storage.9.3.3\lib\net45\Microsoft.WindowsAzure.Storage.dll - - - ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll - - - - ..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll - - - - ..\packages\System.Diagnostics.DiagnosticSource.4.6.0\lib\net46\System.Diagnostics.DiagnosticSource.dll - - - ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll - - - - ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll - - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll - - - ..\packages\System.Spatial.5.8.2\lib\net40\System.Spatial.dll - - - ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs deleted file mode 100644 index e5c25bd71..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Program.cs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DWDumper -{ - using System; - using System.Data; - using System.Data.SqlClient; - using System.Text; - using Avro.File; - using Avro.Generic; - using Newtonsoft.Json; - using Azure.Storage.Blobs; - using System.IO; - - /// - /// A simple test program to dump a single Avro blob file created by EventHubs Capture into a SQL data warehouse (DW). - /// This is useful for testing connections with your SQL DW before integrating this DW dumping code with Azure Functions - /// - class Program - { - private const string StorageConnectionString = "[provide your storage connection string]"; - private const string EventHubsCaptureAvroBlobContainer = "<< Blobs container>>"; - private const string EventHubsCaptureAvroBlobName = "<>"; - private const string SqlDwConnection = "[provide the SQL DW connection string]"; - - - private static int Main(string[] args) - { - var p = new Program(); - p.Dump(); - - return 0; - } - - public void Dump() - { - // Get the blob reference - BlobContainerClient blobContainer = new BlobContainerClient(StorageConnectionString, EventHubsCaptureAvroBlobContainer); - BlobClient blob = blobContainer.GetBlobClient(EventHubsCaptureAvroBlobName); - - // Download the content to a memory stream - using (Stream blobStream = new MemoryStream()) - { - blob.DownloadToAsync(blobStream); - - using (var dataTable = GetWindTurbineMetricsTable()) - { - // Parse the Avro File - using (var avroReader = DataFileReader.OpenReader(blobStream)) - { - while (avroReader.HasNext()) - { - GenericRecord r = avroReader.Next(); - - byte[] body = (byte[])r["Body"]; - var windTurbineMeasure = DeserializeToWindTurbineMeasure(body); - - // Add the row to in memory table - AddWindTurbineMetricToTable(dataTable, windTurbineMeasure); - } - } - - if (dataTable.Rows.Count > 0) - { - BatchInsert(dataTable); - } - } - } - } - - private void BatchInsert(DataTable table) - { - // Write the data to SQL DW using SqlBulkCopy - using (var sqlDwConnection = new SqlConnection(SqlDwConnection)) - { - sqlDwConnection.Open(); - - using (var bulkCopy = new SqlBulkCopy(sqlDwConnection)) - { - bulkCopy.BulkCopyTimeout = 30; - bulkCopy.DestinationTableName = "dbo.Fact_WindTurbineMetrics"; - bulkCopy.WriteToServer(table); - } - } - } - - private WindTurbineMeasure DeserializeToWindTurbineMeasure(byte[] body) - { - string payload = Encoding.ASCII.GetString(body); - return JsonConvert.DeserializeObject(payload); - } - - private DataTable GetWindTurbineMetricsTable() - { - var dt = new DataTable(); - dt.Columns.AddRange - ( - new DataColumn[5] - { - new DataColumn("DeviceId", typeof(string)), - new DataColumn("MeasureTime", typeof(DateTime)), - new DataColumn("GeneratedPower", typeof(float)), - new DataColumn("WindSpeed", typeof(float)), - new DataColumn("TurbineSpeed", typeof(float)) - } - ); - - return dt; - } - - private void AddWindTurbineMetricToTable(DataTable table, WindTurbineMeasure wtm) - { - table.Rows.Add(wtm.DeviceId, wtm.MeasureTime, wtm.GeneratedPower, wtm.WindSpeed, wtm.TurbineSpeed); - Console.WriteLine( - "DeviceId: {0}, MeasureTime: {1}, GeneratedPower: {2}, WindSpeed: {3}, TurbineSpeed: {4}", - wtm.DeviceId, wtm.MeasureTime, wtm.GeneratedPower, wtm.WindSpeed, wtm.TurbineSpeed); - } - } - -} diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Properties/AssemblyInfo.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Properties/AssemblyInfo.cs deleted file mode 100644 index d12e26ed9..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("DWDumper")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("DWDumper")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("c9e1d3c8-0c0d-45eb-a3b5-15f95efc01e3")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs deleted file mode 100644 index 5ac8bca68..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DWDumper -{ - using System; - // TODO, move this class to a Contracts assembly that is shared across different projects - class WindTurbineMeasure - { - public string DeviceId { get; set; } - public DateTime MeasureTime { get; set; } - public float GeneratedPower { get; set; } - public float WindSpeed { get; set; } - public float TurbineSpeed { get; set; } - } -} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/packages.config deleted file mode 100644 index 3dac4c2f1..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/DWDumper/packages.config +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln deleted file mode 100644 index 2d7d0cecf..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln +++ /dev/null @@ -1,37 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26730.12 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindTurbineDataGenerator", "WindTurbineDataGenerator\WindTurbineDataGenerator.csproj", "{0C87A54A-AD21-46D5-8B75-4247DA32237E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DWDumper", "DWDumper\DWDumper.csproj", "{C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionEGDWDumper", "FunctionEGDWDumper\FunctionEGDWDumper.csproj", "{27D28A3D-4157-4ED2-A1C4-5525507CCA04}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Release|Any CPU.Build.0 = Release|Any CPU - {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Release|Any CPU.Build.0 = Release|Any CPU - {27D28A3D-4157-4ED2-A1C4-5525507CCA04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {27D28A3D-4157-4ED2-A1C4-5525507CCA04}.Debug|Any CPU.Build.0 = Debug|Any CPU - {27D28A3D-4157-4ED2-A1C4-5525507CCA04}.Release|Any CPU.ActiveCfg = Release|Any CPU - {27D28A3D-4157-4ED2-A1C4-5525507CCA04}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {0BDB7260-AF54-438B-B99E-95E7136C1486} - EndGlobalSection -EndGlobal diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs deleted file mode 100644 index 282977503..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace FunctionEGDWDumper -{ - /// - /// These classes were generated from the EventGrid event schema. - /// comments for understanding how the EventGrid schema was obtained. - /// - public class EventGridEHEvent - { - public string topic { get; set; } - public string subject { get; set; } - public string eventType { get; set; } - public string eventTime { get; set; } - public string id { get; set; } - public Data data { get; set; } - } - - public class Data - { - public string fileUrl { get; set; } - public string fileType { get; set; } - public string partitionId { get; set; } - public int sizeInBytes { get; set; } - public int eventCount { get; set; } - public int firstSequenceNumber { get; set; } - public int lastSequenceNumber { get; set; } - public string firstEnqueueTime { get; set; } - public string lastEnqueueTime { get; set; } - } -} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs deleted file mode 100644 index 3de7c4ade..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs +++ /dev/null @@ -1,155 +0,0 @@ -// This is the default URL for triggering event grid function in the local environment. -// http://localhost:7071/admin/extensions/EventGridExtensionConfig?functionName={functionname} - -using System; -using System.Data; -using System.Data.SqlClient; -using System.Globalization; -using System.Linq; -using System.Net; -using System.Net.Http; - -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace FunctionEGDWDumper -{ - using System.Text; - using Avro.File; - using Avro.Generic; - using Microsoft.Azure.WebJobs; - using Microsoft.Azure.WebJobs.Extensions.EventGrid; - using Microsoft.Azure.WebJobs.Host; - using Microsoft.WindowsAzure.Storage; - using Newtonsoft.Json; - using Newtonsoft.Json.Linq; - - - public static class Function1 - { - private static readonly string StorageConnectionString = Environment.GetEnvironmentVariable("StorageConnectionString"); - private static readonly string SqlDwConnection = Environment.GetEnvironmentVariable("SqlDwConnection"); - - /// - /// Use the accompanying .sql script to create this table in the data warehouse - /// - private const string TableName = "dbo.Fact_WindTurbineMetrics"; - - [FunctionName("EventGridTriggerMigrateData")] - public static void Run([EventGridTrigger]JObject eventGridEvent, TraceWriter log) - { - log.Info("C# EventGrid trigger function processed a request."); - log.Info(eventGridEvent.ToString(Formatting.Indented)); - - try - { - // Copy to a static Album instance - EventGridEHEvent ehEvent = eventGridEvent.ToObject(); - - // Get the URL from the event that points to the Capture file - var uri = new Uri(ehEvent.data.fileUrl); - - // Get data from the file and migrate to data warehouse - Dump(uri); - } - catch (Exception e) - { - string s = string.Format(CultureInfo.InvariantCulture, - "Error processing request. Exception: {0}, Request: {1}", e, eventGridEvent.ToString()); - log.Error(s); - } - } - - /// - /// Dumps the data from the Avro blob to the data warehouse (DW). - /// Before running this, ensure that the DW has the required table created. - /// - private static void Dump(Uri fileUri) - { - // Get the blob reference - var storageAccount = CloudStorageAccount.Parse(StorageConnectionString); - var blobClient = storageAccount.CreateCloudBlobClient(); - var blob = blobClient.GetBlobReferenceFromServer(fileUri); - - using (var dataTable = GetWindTurbineMetricsTable()) - { - // Parse the Avro File - using (var avroReader = DataFileReader.OpenReader(blob.OpenRead())) - { - while (avroReader.HasNext()) - { - GenericRecord r = avroReader.Next(); - - byte[] body = (byte[])r["Body"]; - var windTurbineMeasure = DeserializeToWindTurbineMeasure(body); - - // Add the row to in memory table - AddWindTurbineMetricToTable(dataTable, windTurbineMeasure); - } - } - - if (dataTable.Rows.Count > 0) - { - BatchInsert(dataTable); - } - } - } - - /// - /// Open connection to data warehouse. Write the parsed data to the table. - /// - private static void BatchInsert(DataTable table) - { - // Write the data to SQL DW using SqlBulkCopy - using (var sqlDwConnection = new SqlConnection(SqlDwConnection)) - { - sqlDwConnection.Open(); - - using (var bulkCopy = new SqlBulkCopy(sqlDwConnection)) - { - bulkCopy.BulkCopyTimeout = 30; - bulkCopy.DestinationTableName = TableName; - bulkCopy.WriteToServer(table); - } - } - } - - /// - /// Deserialize data and return object with expected properties. - /// - private static WindTurbineMeasure DeserializeToWindTurbineMeasure(byte[] body) - { - string payload = Encoding.ASCII.GetString(body); - return JsonConvert.DeserializeObject(payload); - } - - /// - /// Define the in-memory table to store the data. The columns match the columns in the .sql script. - /// - private static DataTable GetWindTurbineMetricsTable() - { - var dt = new DataTable(); - dt.Columns.AddRange - ( - new DataColumn[5] - { - new DataColumn("DeviceId", typeof(string)), - new DataColumn("MeasureTime", typeof(DateTime)), - new DataColumn("GeneratedPower", typeof(float)), - new DataColumn("WindSpeed", typeof(float)), - new DataColumn("TurbineSpeed", typeof(float)) - } - ); - - return dt; - } - - /// - /// For each parsed record, add a row to the in-memory table. - /// - private static void AddWindTurbineMetricToTable(DataTable table, WindTurbineMeasure wtm) - { - table.Rows.Add(wtm.DeviceId, wtm.MeasureTime, wtm.GeneratedPower, wtm.WindSpeed, wtm.TurbineSpeed); - } - } -} diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj deleted file mode 100644 index 72747d8a8..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - net461 - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - Never - - - diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/WindTurbineMeasure.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/WindTurbineMeasure.cs deleted file mode 100644 index 19a41a3b4..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/WindTurbineMeasure.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - - -namespace FunctionEGDWDumper -{ - using System; - - // TODO, move this class to a Contracts assembly that is shared across different projects - class WindTurbineMeasure - { - public string DeviceId { get; set; } - public DateTime MeasureTime { get; set; } - public float GeneratedPower { get; set; } - public float WindSpeed { get; set; } - public float TurbineSpeed { get; set; } - } -} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json deleted file mode 100644 index 7a73a41bf..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/local.settings.json b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/local.settings.json deleted file mode 100644 index 8f901f116..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/local.settings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "IsEncrypted": false, - "Values": { - "AzureWebJobsStorage": "", - "AzureWebJobsDashboard": "" - } -} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/Readme.md b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/Readme.md deleted file mode 100644 index ed3773221..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/Readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# Migrate captured Event Hubs data to a SQL Data Warehouse using Event Grid and Azure Function - -See this [tutorial article](https://docs.microsoft.com/azure/event-hubs/store-captured-data-data-warehouse) for details on using this sample. It shows you how to capture data from your event hub into a SQL data warehouse by using an Azure function triggered by an event grid. diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config deleted file mode 100644 index 8291b54ec..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs deleted file mode 100644 index 9a601a763..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace WindTurbineDataGenerator -{ - using System; - using System.Diagnostics; - using System.Text; - using System.Threading; - using System.Threading.Tasks; - using Newtonsoft.Json; - using Azure.Messaging.EventHubs; - using Azure.Messaging.EventHubs.Producer; - - - internal class Program - { - private const string EventHubNamespaceConnectionString = ""; - private const string EventHubName = ""; - - private static int Main() - { - Console.WriteLine("Starting wind turbine generator. Press to exit"); - - // Start generation of events - var cts = new CancellationTokenSource(); - - var t0 = StartEventGenerationAsync(cts.Token); - - Console.ReadLine(); - cts.Cancel(); - - var t1 = Task.Delay(TimeSpan.FromSeconds(3)); - Task.WhenAny(t0, t1).GetAwaiter().GetResult(); - - return 0; - } - - private static async Task StartEventGenerationAsync(CancellationToken cancellationToken) - { - var random = new Random((int)DateTimeOffset.UtcNow.Ticks); - - // create an Event Hubs Producer client using the namespace connection string and the event hub name - EventHubProducerClient producerClient = new EventHubProducerClient(EventHubNamespaceConnectionString, EventHubName); - - while (!cancellationToken.IsCancellationRequested) - { - try - { - // Simulate sending data from 100 weather sensors - // prepare a batch of events to send to the event hub. - EventDataBatch eventBatch = await producerClient.CreateBatchAsync(); - for (int i = 0; i < 100; i++) - { - int scaleFactor = random.Next(0, 25); - var windTurbineMeasure = GenerateTurbineMeasure("Turbine_" + i, scaleFactor); - EventData evData = SerializeWindTurbineToEventData(windTurbineMeasure); - // add the event to the batch - if (eventBatch.TryAdd(evData) == false) - break; - } - - Console.Write("."); - - // send the batch of events to the event hub - await producerClient.SendAsync(eventBatch); - } - catch (Exception ex) - { - Debug.WriteLine("Error generating turbine data. Exception: {0}", ex); - Console.Write("E"); - } - - await Task.Delay(1000, cancellationToken); - } - } - - private static WindTurbineMeasure GenerateTurbineMeasure(string turbineId, int scaleFactor) - { - return new WindTurbineMeasure - { - DeviceId = turbineId, - MeasureTime = DateTime.UtcNow, - GeneratedPower = 2.5F * scaleFactor, // in MegaWatts/hour - WindSpeed = 15 * scaleFactor, // miles per hour - TurbineSpeed = 0.3F * scaleFactor // RPMs - }; - } - - private static EventData SerializeWindTurbineToEventData(WindTurbineMeasure wtm) - { - var messageString = JsonConvert.SerializeObject(wtm); - var bytes = Encoding.ASCII.GetBytes(messageString); - return new EventData(bytes); - } - } -} diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Properties/AssemblyInfo.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Properties/AssemblyInfo.cs deleted file mode 100644 index 3287a2bd9..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("WindTurbineDataGenerator")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("WindTurbineDataGenerator")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("0c87a54a-ad21-46d5-8b75-4247da32237e")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj deleted file mode 100644 index 528c4f059..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj +++ /dev/null @@ -1,133 +0,0 @@ - - - - - Debug - AnyCPU - {0C87A54A-AD21-46D5-8B75-4247DA32237E} - Exe - WindTurbineDataGenerator - WindTurbineDataGenerator - v4.6.1 - 512 - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Azure.Core.1.0.1\lib\netstandard2.0\Azure.Core.dll - - - ..\packages\Azure.Messaging.EventHubs.5.0.1\lib\netstandard2.0\Azure.Messaging.EventHubs.dll - - - ..\packages\Microsoft.Azure.Amqp.2.4.2\lib\net45\Microsoft.Azure.Amqp.dll - - - ..\packages\Microsoft.Azure.EventHubs.1.0.2\lib\net451\Microsoft.Azure.EventHubs.dll - - - ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll - - - ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll - - - - ..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll - - - - ..\packages\System.Diagnostics.DiagnosticSource.4.6.0\lib\net46\System.Diagnostics.DiagnosticSource.dll - - - ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll - - - ..\packages\System.Net.WebSockets.4.0.0\lib\net46\System.Net.WebSockets.dll - True - True - - - ..\packages\System.Net.WebSockets.Client.4.0.2\lib\net46\System.Net.WebSockets.Client.dll - True - True - - - - ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll - - - ..\packages\System.Reflection.TypeExtensions.4.5.1\lib\net461\System.Reflection.TypeExtensions.dll - - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll - - - - ..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll - True - True - - - ..\packages\System.Security.Cryptography.Algorithms.4.2.0\lib\net461\System.Security.Cryptography.Algorithms.dll - True - True - - - ..\packages\System.Security.Cryptography.Encoding.4.0.0\lib\net46\System.Security.Cryptography.Encoding.dll - True - True - - - ..\packages\System.Security.Cryptography.Primitives.4.0.0\lib\net46\System.Security.Cryptography.Primitives.dll - True - True - - - ..\packages\System.Security.Cryptography.X509Certificates.4.1.0\lib\net461\System.Security.Cryptography.X509Certificates.dll - True - True - - - ..\packages\System.Threading.Channels.4.6.0\lib\netstandard2.0\System.Threading.Channels.dll - - - ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineMeasure.cs b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineMeasure.cs deleted file mode 100644 index 736adfc97..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineMeasure.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace WindTurbineDataGenerator -{ - using System; - - // TODO, move this class to a Contracts assembly that is shared across different projects - class WindTurbineMeasure - { - public string DeviceId { get; set; } - public DateTime MeasureTime { get; set; } - public float GeneratedPower { get; set; } - public float WindSpeed { get; set; } - public float TurbineSpeed { get; set; } - } -} \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config deleted file mode 100644 index 7679cc9cd..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/scripts/CreateDataWarehouseTable.sql b/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/scripts/CreateDataWarehouseTable.sql deleted file mode 100644 index 163f9eea3..000000000 --- a/samples/DotNet/Azure.Messaging.EventHubs/EventHubsCaptureEventGridDemo/scripts/CreateDataWarehouseTable.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE [dbo].[Fact_WindTurbineMetrics] ( - [DeviceId] nvarchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, - [MeasureTime] datetime NULL, - [GeneratedPower] float NULL, - [WindSpeed] float NULL, - [TurbineSpeed] float NULL -) -WITH (CLUSTERED COLUMNSTORE INDEX, DISTRIBUTION = ROUND_ROBIN); \ No newline at end of file From 809eb4c970aaff9ef7fc784ffe6905befa9b6dce Mon Sep 17 00:00:00 2001 From: "Wenjie Yu (Wicresoft North America Ltd)" Date: Thu, 15 Apr 2021 16:18:32 +0800 Subject: [PATCH 49/66] Clean up of the EventHubsCaptureEventGridDemo sample in the azure-event-hubs repo --- .../DWDumper/DWDumper.csproj | 15 +++++++++------ .../DWDumper/Program.cs | 12 ++++++++---- .../DWDumper/packages.config | 2 +- .../FunctionEGDWDumper/Function1.cs | 14 +++++++++----- .../FunctionEGDWDumper/FunctionEGDWDumper.csproj | 2 +- .../WindTurbineDataGenerator.csproj | 3 --- .../WindTurbineDataGenerator/packages.config | 1 - 7 files changed, 28 insertions(+), 21 deletions(-) diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj index b947b0d03..25ff5787b 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj +++ b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj @@ -35,12 +35,18 @@ ..\packages\Apache.Avro.1.7.7.2\lib\Avro.dll + + C:\Users\v-wenjyu\.nuget\packages\azure.core\1.8.1\lib\netstandard2.0\Azure.Core.dll + + + C:\Users\v-wenjyu\.nuget\packages\azure.storage.blobs\12.8.1\lib\netstandard2.0\Azure.Storage.Blobs.dll + + + C:\Users\v-wenjyu\.nuget\packages\azure.storage.common\12.7.1\lib\netstandard2.0\Azure.Storage.Common.dll + ..\packages\log4net.1.2.10\lib\2.0\log4net.dll - - ..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll - ..\packages\Microsoft.Data.Edm.5.8.2\lib\net40\Microsoft.Data.Edm.dll @@ -50,9 +56,6 @@ ..\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll - - ..\packages\WindowsAzure.Storage.8.3.0\lib\net45\Microsoft.WindowsAzure.Storage.dll - ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll True diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Program.cs b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Program.cs index 2b9e73718..68f0f72ea 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Program.cs +++ b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Program.cs @@ -8,7 +8,7 @@ using Avro.File; using Avro.Generic; using Newtonsoft.Json; -using Microsoft.WindowsAzure.Storage; +using Azure.Storage.Blobs; namespace DWDumper { @@ -33,9 +33,13 @@ private static int Main(string[] args) public void Dump() { // Get the blob reference - var storageAccount = CloudStorageAccount.Parse(StorageConnectionString); - var blobClient = storageAccount.CreateCloudBlobClient(); - var blob = blobClient.GetBlobReferenceFromServer(new Uri(EventHubsCaptureAvroBlobUri)); + string connectionString = "ConnectionString"; + string containerName = "containerName"; + string blobName = "blobName"; + + BlobContainerClient container = new BlobContainerClient(connectionString, containerName); + container.Create(); + BlobClient blob = container.GetBlobClient(blobName); using (var dataTable = GetWindTurbineMetricsTable()) { diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/packages.config b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/packages.config index 935667da9..5f6abdf49 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/packages.config +++ b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/packages.config @@ -12,5 +12,5 @@ - + \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs index ee1918b1e..d4f82cdda 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs @@ -17,7 +17,7 @@ using Microsoft.Azure.WebJobs.Extensions.EventGrid; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.Azure.WebJobs.Host; -using Microsoft.WindowsAzure.Storage; +using Azure.Storage.Blobs; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -66,14 +66,18 @@ public static void Run([EventGridTrigger]JObject eventGridEvent, TraceWriter log private static async void Dump(Uri fileUri) { // Get the blob reference - var storageAccount = CloudStorageAccount.Parse(StorageConnectionString); - var blobClient = storageAccount.CreateCloudBlobClient(); - var blob = await blobClient.GetBlobReferenceFromServerAsync(fileUri); + string connectionString = "ConnectionString"; + string containerName = "containerName"; + string blobName = "blobName"; + + BlobContainerClient container = new BlobContainerClient(connectionString, containerName); + container.Create(); + BlobClient blob = container.GetBlobClient(blobName); using (var dataTable = GetWindTurbineMetricsTable()) { // Parse the Avro File - Stream blobStream = await blob.OpenReadAsync(null, null, null); + Stream blobStream = await blob.OpenReadAsync(null); using (var avroReader = DataFileReader.OpenReader(blobStream)) { while (avroReader.HasNext()) diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj index 70a28dc44..fefff615e 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj index dac548f6e..ee1da6e49 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj @@ -41,9 +41,6 @@ ..\packages\Microsoft.Azure.Amqp.2.4.5\lib\net45\Microsoft.Azure.Amqp.dll - - ..\packages\Microsoft.Azure.EventHubs.1.0.2\lib\net451\Microsoft.Azure.EventHubs.dll - ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config index 3283060b8..831adba3d 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config @@ -3,7 +3,6 @@ - From 71ed5eaf8d41492f67ceb3f5fa03f420db2f8d08 Mon Sep 17 00:00:00 2001 From: Ramya Rao Date: Thu, 15 Apr 2021 18:35:59 -0700 Subject: [PATCH 50/66] Add pointers to new packages in readme files at the root and for .Net legacy package (#478) * Add pointers to new packages in readme files * re-arrange readme * Update Java readme too --- .../EventHubsSenderReceiverRbac/README.md | 7 ++-- samples/DotNet/Microsoft.ServiceBus/README.md | 1 + samples/Java/README.md | 36 ++++++++++--------- samples/README.md | 29 +++++++++------ 4 files changed, 44 insertions(+), 29 deletions(-) create mode 100644 samples/DotNet/Microsoft.ServiceBus/README.md diff --git a/samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/README.md b/samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/README.md index 9e4cd2c30..f6ac37747 100644 --- a/samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/README.md +++ b/samples/DotNet/Microsoft.ServiceBus/RBAC/EventHubsSenderReceiverRbac/README.md @@ -1,3 +1,6 @@ -# Role based access sample # +# Role based access sample with WindowsAzure.ServiceBus SDK -For more information on Role based access (RBAC) and how to run this sample follow [this](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-role-based-access-control) link. +See [Authorize access to Event Hubs resources using Azure Active Directory](https://docs.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory) for information on Role based access (RBAC). + +**Note**: This sample shows different ways to authenticate using Azure Active Directory with the legacy Event Hubs library `WindowsAzure.ServiceBus`. +For the current version of the library `Azure.Messaging.EventHubs`, please see the [sample that makes use of credentials from Azure.Identity](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs/samples/Sample06_IdentityAndSharedAccessCredentials.md). diff --git a/samples/DotNet/Microsoft.ServiceBus/README.md b/samples/DotNet/Microsoft.ServiceBus/README.md new file mode 100644 index 000000000..0b572d12a --- /dev/null +++ b/samples/DotNet/Microsoft.ServiceBus/README.md @@ -0,0 +1 @@ +> **Note:** : This folder has samples for the legacy package WindowsAzure.ServiceBus that can be used for Azure Event Hubs. There is a newer package [Azure.Messaging.EventHubs](https://www.nuget.org/packages/Azure.Messaging.EventHubs) available as of February 2020. Please refer to [samples for the Azure.Messaging.EventHubs client library](https://docs.microsoft.com/samples/azure/azure-sdk-for-net/azuremessagingeventhubs-samples/) instead. diff --git a/samples/Java/README.md b/samples/Java/README.md index 158c4012c..a773808ef 100644 --- a/samples/Java/README.md +++ b/samples/Java/README.md @@ -1,32 +1,34 @@ # Azure Event Hubs Java samples -Azure Event Hubs is a highly scalable data streaming platform and event ingestion service, capable of receiving and processing millions of events per second. The samples present here enables Java developers to easily ingest and process events from your event hub. +**Note:**: The samples present here enables Java developers to easily ingest and process events from an instance of [Azure Event Hubs](https://docs.microsoft.com/azure/event-hubs/event-hubs-about) using the legacy libraries `com.microsoft.azure:azure-eventhubs` and `com.microsoft.azure:azure-eventhubs-eph`. We strongly recommend you to use the current library `com.azure:azure-messaging-eventhubs` instead. + +- [Java samples for current Azure Event Hubs client library](https://docs.microsoft.com/en-us/samples/azure/azure-sdk-for-java/eventhubs-samples/) +- [Java samples for current Azure Event Hubs Checkpoint Store client library](https://docs.microsoft.com/samples/azure/azure-sdk-for-java/eventhubs-samples/) ## Prerequisites -1. The samples depend on the Java JDK 1.8 and are built using Maven. You can [download Maven](https://maven.apache.org/download.cgi). [Install and configure Maven](https://maven.apache.org/install.html). The sample require Maven version > 3.3.9. -2. You need an Azure Subscription, if you do not have one - create a [free account](https://azure.microsoft.com/free/?ref=microsoft.com&utm_source=microsoft.com&utm_medium=docs&utm_campaign=visualstudio) before you begin -3. [An Event Hubs namespace and an event hub where you ingest the data](https://docs.microsoft.com/azure/event-hubs/event-hubs-create) -4. [A SAS key to access the event hub](https://docs.microsoft.com/azure/event-hubs/event-hubs-create#SAS) +1. The samples depend on the Java JDK 1.8 and are built using Maven. You can [download Maven](https://maven.apache.org/download.cgi). [Install and configure Maven](https://maven.apache.org/install.html). The sample require Maven version > 3.3.9. +2. You need an Azure Subscription, if you do not have one - create a [free account](https://azure.microsoft.com/free/?ref=microsoft.com&utm_source=microsoft.com&utm_medium=docs&utm_campaign=visualstudio) before you begin +3. [An Event Hubs namespace and an event hub where you ingest the data](https://docs.microsoft.com/azure/event-hubs/event-hubs-create) +4. [A SAS key to access the event hub](https://docs.microsoft.com/azure/event-hubs/event-hubs-create#SAS) ### Sending events -* **SendBatch** - The [SendBatch](./Basic/SendBatch) sample illustrates how to ingest batches of events into your event hub. -* **SimpleSend** - The [SimpleSend](./Basic/SimpleSend) sample illustrates how to ingest events into your event hub. -* **AdvanceSendOptions** - The [AdvancedSendOptions](./Basic/AdvancedSendOptions) sample illustrates the various options available with Event Hubs to ingest events. - -### Processing events +- **SendBatch** - The [SendBatch](./Basic/SendBatch) sample illustrates how to ingest batches of events into your event hub. +- **SimpleSend** - The [SimpleSend](./Basic/SimpleSend) sample illustrates how to ingest events into your event hub. +- **AdvanceSendOptions** - The [AdvancedSendOptions](./Basic/AdvancedSendOptions) sample illustrates the various options available with Event Hubs to ingest events. -* **ReceiveByDateTime** - The [ReceiveByDateTime](./Basic/ReceiveByDateTime) sample illustrates how to receive events from an event hub partition using a specific date-time offset. -* **ReceiveUsingOffset** - The [ReceiveUsingOffset](./Basic/ReceiveUsingOffset) sample illustrates how to receive events from an event hub partition using a specific data offset. -* **ReceiveUsingSequenceNumber** - The [ReceiveUsingSequenceNumber](./Basic/ReceiveUsingSequenceNumber) sample illustrates how can receive from an event hub partitions using a sequence number. -* **EventProcessorSample** - The [EventProcessorSample](./Basic/EventProcessorSample) sample illustrates how to receive events from an event hub using the event processor host, which provides automatic partition selection and fail-over across multiple concurrent receivers. +### Processing events +- **ReceiveByDateTime** - The [ReceiveByDateTime](./Basic/ReceiveByDateTime) sample illustrates how to receive events from an event hub partition using a specific date-time offset. +- **ReceiveUsingOffset** - The [ReceiveUsingOffset](./Basic/ReceiveUsingOffset) sample illustrates how to receive events from an event hub partition using a specific data offset. +- **ReceiveUsingSequenceNumber** - The [ReceiveUsingSequenceNumber](./Basic/ReceiveUsingSequenceNumber) sample illustrates how can receive from an event hub partitions using a sequence number. +- **EventProcessorSample** - The [EventProcessorSample](./Basic/EventProcessorSample) sample illustrates how to receive events from an event hub using the event processor host, which provides automatic partition selection and fail-over across multiple concurrent receivers. ### Benchmarks -* **AutoScaleOnIngress** - The [AutoScaleOnIngress](./Benchmarks/AutoScaleOnIngress) sample illustrates how an event hub can automatically scale up on high loads. The sample will send events at a rate that just exceed the configured rate of an event hub, causing the event hub to scale up. -* **IngressBenchmark** - The [IngressBenchmark](./Benchmarks/IngressBenchmark) sample allows measuring the ingress rate. +- **AutoScaleOnIngress** - The [AutoScaleOnIngress](./Benchmarks/AutoScaleOnIngress) sample illustrates how an event hub can automatically scale up on high loads. The sample will send events at a rate that just exceed the configured rate of an event hub, causing the event hub to scale up. +- **IngressBenchmark** - The [IngressBenchmark](./Benchmarks/IngressBenchmark) sample allows measuring the ingress rate. ## Build and run @@ -40,4 +42,4 @@ The samples are dropped into the respective sample's ./target subfolder. The bui ```bash java -jar ./target/{project}-1.0.0-jar-with-dependencies.jar -``` \ No newline at end of file +``` diff --git a/samples/README.md b/samples/README.md index 9e340fb12..fe936aa22 100644 --- a/samples/README.md +++ b/samples/README.md @@ -1,25 +1,34 @@ # Azure Event Hubs samples -## .NET +**Note:** This repository holds samples for the legacy libraries for Azure Event Hubs for .NET and Java developers. We highly recommend you to upgrade to the newer packages. -### Microsoft.Azure.EventHubs -Any samples within the `Azure.Microsoft.EventHubs` folder target the newer .NET Standard library. +.NET legacy packages -#### SampleSender +- Microsoft.Azure.EventHubs (**legacy**) +- Microsoft.Azure.EventHubs.Processor (**legacy**) +- WindowsAzure.ServiceBus (**legacy**) -[This sample](./DotNet/Microsoft.Azure.EventHubs/SampleSender/readme.md) shows how to write a .NET Core console application that sends a set of messages to an Event Hub. +Java legacy packages -#### SampleEphReceiver +- com.microsoft.azure:azure-eventhubs (**legacy**) +- com.microsoft.azure:azure-eventhubs-eph (**legacy**) -[This sample](./DotNet/Microsoft.Azure.EventHubs/SampleEphReceiver/readme.md) shows how to write a .NET Core console application that receives messages from an Event Hub using the **EventProcessorHost**. +Samples for **latest** .NET packages for Azure Event Hubs -## Java +- [Azure.Messaging.EventHubs](https://docs.microsoft.com/samples/azure/azure-sdk-for-net/azuremessagingeventhubs-samples/) +- [Azure.Messaging.EventHubs.Processor](https://docs.microsoft.com/samples/azure/azure-sdk-for-net/azuremessagingeventhubsprocessor-samples/) -[Go here](./Java) for the Java language samples. +Samples for **latest** Java packages for Azure Event Hubs + +- [com.azure:azure-messaging-eventhubs](https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/eventhubs/azure-messaging-eventhubs/src/samples) +- [com.azure:azure-messaging-eventhubs-checkpointstore-blob](https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/eventhubs/azure-messaging-eventhubs-checkpointstore-blob/src/samples) ## Miscellaneous +### Manage Event Hubs resources + +The samples under the folder `Management` in this repository show how to manage your Event Hubs resources via CLI, the .NET package `Microsoft.Azure.Management.EventHub` and PowerShell + ### proton-c-sender-dotnet-framework-receiver [This sample](./Miscellaneous/proton-c-sender-dotnet-framework-receiver/README.md) shows how to use Azure Event Hubs with clients that use different protocols. This scenario sends using an Apache Proton C++ client, and receives using the .NET Framework client. - From d9614163d97d5c7d53e64fa0438caec66583712e Mon Sep 17 00:00:00 2001 From: "Wenjie Yu (Wicresoft North America Ltd)" Date: Mon, 19 Apr 2021 11:45:13 +0800 Subject: [PATCH 51/66] Updating to use EventHubsCaptureAvroBlobUri to create the BlobClient directly,and modify reference of packages. --- .../DWDumper/DWDumper.csproj | 10 +--------- .../EventHubsCaptureEventGridDemo/DWDumper/Program.cs | 9 ++------- .../FunctionEGDWDumper/Function1.cs | 8 +------- 3 files changed, 4 insertions(+), 23 deletions(-) diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj index 25ff5787b..55d4efc56 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj +++ b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj @@ -35,15 +35,6 @@ ..\packages\Apache.Avro.1.7.7.2\lib\Avro.dll - - C:\Users\v-wenjyu\.nuget\packages\azure.core\1.8.1\lib\netstandard2.0\Azure.Core.dll - - - C:\Users\v-wenjyu\.nuget\packages\azure.storage.blobs\12.8.1\lib\netstandard2.0\Azure.Storage.Blobs.dll - - - C:\Users\v-wenjyu\.nuget\packages\azure.storage.common\12.7.1\lib\netstandard2.0\Azure.Storage.Common.dll - ..\packages\log4net.1.2.10\lib\2.0\log4net.dll @@ -71,6 +62,7 @@ + diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Program.cs b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Program.cs index 68f0f72ea..055680845 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Program.cs +++ b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Program.cs @@ -32,14 +32,9 @@ private static int Main(string[] args) public void Dump() { - // Get the blob reference - string connectionString = "ConnectionString"; - string containerName = "containerName"; - string blobName = "blobName"; + // Get the blob reference - BlobContainerClient container = new BlobContainerClient(connectionString, containerName); - container.Create(); - BlobClient blob = container.GetBlobClient(blobName); + BlobClient blob = new BlobClient(new Uri(EventHubsCaptureAvroBlobUri)); using (var dataTable = GetWindTurbineMetricsTable()) { diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs index d4f82cdda..fd314c6d7 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs @@ -66,13 +66,7 @@ public static void Run([EventGridTrigger]JObject eventGridEvent, TraceWriter log private static async void Dump(Uri fileUri) { // Get the blob reference - string connectionString = "ConnectionString"; - string containerName = "containerName"; - string blobName = "blobName"; - - BlobContainerClient container = new BlobContainerClient(connectionString, containerName); - container.Create(); - BlobClient blob = container.GetBlobClient(blobName); + BlobClient blob = new BlobClient(fileUri); using (var dataTable = GetWindTurbineMetricsTable()) { From 4cadf098f0a7e4a64fd52cb83e68561e105095ce Mon Sep 17 00:00:00 2001 From: "Wenjie Yu (Wicresoft North America Ltd)" Date: Wed, 21 Apr 2021 10:24:01 +0800 Subject: [PATCH 52/66] Updating the Reference --- .../EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj | 5 ++++- .../WindTurbineDataGenerator/packages.config | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj index 55d4efc56..2d18effc2 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj +++ b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj @@ -35,6 +35,10 @@ ..\packages\Apache.Avro.1.7.7.2\lib\Avro.dll + + False + ..\packages\Azure.Storage.Blobs.12.8.1\lib\netstandard2.0\Azure.Storage.Blobs.dll + ..\packages\log4net.1.2.10\lib\2.0\log4net.dll @@ -62,7 +66,6 @@ - diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config index 831adba3d..6dfb23305 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config @@ -1,7 +1,7 @@  - + From 5c333eba2e386dac7a09a61c46f482d906498da5 Mon Sep 17 00:00:00 2001 From: sagar027 Date: Fri, 3 Sep 2021 04:34:54 +0530 Subject: [PATCH 53/66] Sample using Event Hub Log4j Appender (#482) * sample added for Log4j Event Hub appender * updated ReadME * updated files --- .../Java/Basic/Log4jAppenderSample/README.md | 14 ++++ .../Java/Basic/Log4jAppenderSample/pom.xml | 74 +++++++++++++++++++ .../Log4JEventHubAppenderSample.java | 29 ++++++++ .../src/main/resources/log4j2.xml | 22 ++++++ samples/Java/pom.xml | 3 +- 5 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 samples/Java/Basic/Log4jAppenderSample/README.md create mode 100644 samples/Java/Basic/Log4jAppenderSample/pom.xml create mode 100644 samples/Java/Basic/Log4jAppenderSample/src/main/java/com/microsoft/azure/eventhubs/samples/log4jeventhubappendersample/Log4JEventHubAppenderSample.java create mode 100644 samples/Java/Basic/Log4jAppenderSample/src/main/resources/log4j2.xml diff --git a/samples/Java/Basic/Log4jAppenderSample/README.md b/samples/Java/Basic/Log4jAppenderSample/README.md new file mode 100644 index 000000000..c2b73a695 --- /dev/null +++ b/samples/Java/Basic/Log4jAppenderSample/README.md @@ -0,0 +1,14 @@ +# EventHub Appender Java Sample + +This sample demonstrates the use of EventHubAppender for streaming/sending log4j2 logs to Azure Event Hub. +The EventHubAppender extension (Log4j plugin) code can be found at https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/eventhubs/microsoft-azure-eventhubs-extensions + +Note : The above extension depends on [this version of Azure Event Hubs library](https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/eventhubs/microsoft-azure-eventhubs). + +Steps to run the project : + 1. Clone the repository. + 2. Update the value of 'eventHubConnectionString' in src/main/resources/log4j2.xml file. (This is the config file) + 3. Update the value of 'classpathPrefix' element in the pom.xml file of the project + 4. Run 'mvn clean' + 5. Run 'mvn package' + 6. Run 'java -cp target/my-app-1.0-SNAPSHOT.jar:/*: com.eventhubappendersample.app.App' diff --git a/samples/Java/Basic/Log4jAppenderSample/pom.xml b/samples/Java/Basic/Log4jAppenderSample/pom.xml new file mode 100644 index 000000000..8e1bbe499 --- /dev/null +++ b/samples/Java/Basic/Log4jAppenderSample/pom.xml @@ -0,0 +1,74 @@ + + 4.0.0 + log4jeventhubappendersample + log4jeventhubappendersample + jar + 1.0.0 + + UTF-8 + + + + org.apache.logging.log4j + log4j-api + 2.13.0 + + + org.apache.logging.log4j + log4j-core + [2.13.2,) + + + com.microsoft.azure + azure-eventhubs-extensions + 3.3.0 + + + org.slf4j + slf4j-api + 1.7.32 + + + + org.slf4j + slf4j-simple + 1.7.32 + + + + + + + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + true + lines,vars,source + + + + maven-assembly-plugin + + + package + + single + + + + + + jar-with-dependencies + + + + com.microsoft.azure.eventhubs.samples.log4jeventhubappendersample.Log4JEventHubAppenderSample + + + + + + + diff --git a/samples/Java/Basic/Log4jAppenderSample/src/main/java/com/microsoft/azure/eventhubs/samples/log4jeventhubappendersample/Log4JEventHubAppenderSample.java b/samples/Java/Basic/Log4jAppenderSample/src/main/java/com/microsoft/azure/eventhubs/samples/log4jeventhubappendersample/Log4JEventHubAppenderSample.java new file mode 100644 index 000000000..b4ac6b84a --- /dev/null +++ b/samples/Java/Basic/Log4jAppenderSample/src/main/java/com/microsoft/azure/eventhubs/samples/log4jeventhubappendersample/Log4JEventHubAppenderSample.java @@ -0,0 +1,29 @@ +package com.microsoft.azure.eventhubs.samples.log4jeventhubappendersample; + +import java.util.concurrent.TimeUnit; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * Hello world! + * + */ +public class Log4JEventHubAppenderSample +{ + private static final Logger logger = LogManager.getLogger(Log4JEventHubAppenderSample.class); + public static void main( String[] args ) + { + int i; + for(i=0; i<=10;i++) + { + try { + TimeUnit.SECONDS.sleep(1); + logger.error("Hello World " + i); + } + + catch(InterruptedException e) + { + } + } + } +} diff --git a/samples/Java/Basic/Log4jAppenderSample/src/main/resources/log4j2.xml b/samples/Java/Basic/Log4jAppenderSample/src/main/resources/log4j2.xml new file mode 100644 index 000000000..8f163e613 --- /dev/null +++ b/samples/Java/Basic/Log4jAppenderSample/src/main/resources/log4j2.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/Java/pom.xml b/samples/Java/pom.xml index dec4a357c..9df62a3b4 100644 --- a/samples/Java/pom.xml +++ b/samples/Java/pom.xml @@ -30,7 +30,8 @@ Basic/SendBatch Basic/SimpleSend Basic/AsyncSend - Basic/SimpleProxy + Basic/SimpleProxy + Basic/Log4jAppenderSample Benchmarks/AutoScaleOnIngress Benchmarks/IngressBenchmark From 15b99a523f40e7f642ef0f423aed9b8a13656ef2 Mon Sep 17 00:00:00 2001 From: Ramya Rao Date: Wed, 22 Sep 2021 16:41:52 -0700 Subject: [PATCH 54/66] Update readme with pointers to newer samples (#481) This PR copies over content from https://github.com/Azure/azure-event-hubs/blob/master/samples/README.md to ensure we point users to newer packages --- readme.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 2ec21ee03..c561e16aa 100644 --- a/readme.md +++ b/readme.md @@ -15,10 +15,29 @@ This repository contains samples for Azure Event Hubs. ## Client SDK samples -The .NET and Java client SDK samples in this repository use **old SDKs**. For samples that use new SDKs, see the following repositories. -- [.NET](https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/eventhub/Azure.Messaging.EventHubs/samples) -- [Java](https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/eventhubs/azure-messaging-eventhubs/src/samples/java/com/azure/messaging/eventhubs) +> **Note:** This repository holds samples for the legacy libraries for Azure Event Hubs for .NET and Java developers. We highly recommend you to upgrade to the newer packages. + +.NET legacy packages + +- Microsoft.Azure.EventHubs (**legacy**) +- Microsoft.Azure.EventHubs.Processor (**legacy**) +- WindowsAzure.ServiceBus (**legacy**) + +Java legacy packages + +- com.microsoft.azure:azure-eventhubs (**legacy**) +- com.microsoft.azure:azure-eventhubs-eph (**legacy**) + +Samples for **latest** .NET packages for Azure Event Hubs + +- [Azure.Messaging.EventHubs](https://docs.microsoft.com/samples/azure/azure-sdk-for-net/azuremessagingeventhubs-samples/) +- [Azure.Messaging.EventHubs.Processor](https://docs.microsoft.com/samples/azure/azure-sdk-for-net/azuremessagingeventhubsprocessor-samples/) + +Samples for **latest** Java packages for Azure Event Hubs + +- [com.azure:azure-messaging-eventhubs](https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/eventhubs/azure-messaging-eventhubs/src/samples) +- [com.azure:azure-messaging-eventhubs-checkpointstore-blob](https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/eventhubs/azure-messaging-eventhubs-checkpointstore-blob/src/samples) You can find samples for other languages and frameworks in the following repositories: - [JavaScript](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/eventhub/event-hubs/samples) @@ -35,4 +54,4 @@ This repository also contains [management samples](https://github.com/Azure/azur ## See also -To learn about Event Hubs, see our [Event Hubs documentation](https://docs.microsoft.com/en-us/azure/event-hubs/). \ No newline at end of file +To learn about Event Hubs, see our [Event Hubs documentation](https://docs.microsoft.com/en-us/azure/event-hubs/). From 3cb13d5d87385b97121144b0615bec5109415c5a Mon Sep 17 00:00:00 2001 From: Madusha Gunasekera Date: Thu, 23 Sep 2021 05:12:27 +0530 Subject: [PATCH 55/66] Fix incorrect redirection (#467) --- samples/Java/Basic/SimpleSend/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Java/Basic/SimpleSend/README.md b/samples/Java/Basic/SimpleSend/README.md index 285fa2798..76c1d4200 100644 --- a/samples/Java/Basic/SimpleSend/README.md +++ b/samples/Java/Basic/SimpleSend/README.md @@ -2,7 +2,7 @@ The [Send events to Azure Event Hubs using Java](https://docs.microsoft.com/azure/event-hubs/event-hubs-java-get-started-send) tutorial walks you through ingesting into your event hub using Java with this code. -To run the sample, you need to edit the [sample code](src/main/java/com/microsoft/azure/eventhubs/samples/simplesend/SimpleSend.java) and provide the following information: +To run the sample, you need to edit the [sample code](src/main/java/com/microsoft/azure/eventhubs/samples/SimpleSend/SimpleSend.java) and provide the following information: ```java final String namespaceName = "----EventHubsNamespaceName-----"; From 0b193ff1da9769fd741ba12e33850c3e2d78442c Mon Sep 17 00:00:00 2001 From: Tom Pratt Date: Mon, 7 Mar 2022 11:39:18 -0800 Subject: [PATCH 56/66] fix code comment (#485) --- .../samples/eventprocessorsample/EventProcessorSample.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java b/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java index 870feb2d0..38c651918 100644 --- a/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java +++ b/samples/Java/Basic/EventProcessorSample/src/main/java/com/microsoft/azure/eventhubs/samples/eventprocessorsample/EventProcessorSample.java @@ -28,7 +28,7 @@ public static void main(String args[]) throws InterruptedException, ExecutionExc // account. All instances of EventProcessorHost which will be consuming from the same Event Hub and consumer // group must use the same Azure Storage account and container name. String consumerGroupName = "$Default"; - String namespaceName = "----ServiceBusNamespaceName----"; + String namespaceName = "----EventHubNamespaceName----"; String eventHubName = "----EventHubName----"; String sasKeyName = "----SharedAccessSignatureKeyName----"; String sasKey = "----SharedAccessSignatureKey----"; From df6152208cc8deea7c0fb89914e19be513470824 Mon Sep 17 00:00:00 2001 From: Sannidhya Glodha <62641016+Saglodha@users.noreply.github.com> Date: Thu, 7 Apr 2022 20:59:16 +0530 Subject: [PATCH 57/66] Addition of Schema to Schema groups via Powershell This sample would act as reference to add schema to schema groups in event hubs via PowerShell --- .../Addingschematoschemagroup.ps1 | 45 +++++++++++++++++++ .../AddingSchematoSchemagroups/ReadMe.md | 44 ++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 samples/Management/PowerShell/AddingSchematoSchemagroups/Addingschematoschemagroup.ps1 create mode 100644 samples/Management/PowerShell/AddingSchematoSchemagroups/ReadMe.md diff --git a/samples/Management/PowerShell/AddingSchematoSchemagroups/Addingschematoschemagroup.ps1 b/samples/Management/PowerShell/AddingSchematoSchemagroups/Addingschematoschemagroup.ps1 new file mode 100644 index 000000000..b9ae1187f --- /dev/null +++ b/samples/Management/PowerShell/AddingSchematoSchemagroups/Addingschematoschemagroup.ps1 @@ -0,0 +1,45 @@ + +#Step 1 - Pass in AD Application details below to be able to fetch authorization token against legitimate Service Principal. +$Fields = @{ + grant_type = "client_credentials" + client_id = "" + resource = "https://eventhubs.azure.net" + client_secret = "" + }; + + + $response = Invoke-RestMethod –Uri "https://login.microsoftonline.com//oauth2/token" –ContentType "application/x-www-form-urlencoded" –Method POST –Body $Fields + + #response would have bearer token in the properties that we would use to trigger next call. + + #Step 2- You can declare schema JSON associated to schema in $Body variable below + $Body = @" + { + "namespace": "com.azure.schemaregistry.samples", + "type": "record", + "name": "Order", + "fields": [ + { + "name": "id", + "type": "string" + }, + { + "name": "amount", + "type": "double" + } + ] +} +"@ + +#Step 3- This Uri needs to have details added- namespace name, schema group name and schema name respectively. +$uri = 'https://.servicebus.windows.net/$schemagroups//schemas/?api-version=2020-09-01-preview' + +#Step 4- These headers would be sent along with the API Call +$headers = @{ + "Content-Type" = "application/atom+xml;type=entry;charset=utf-8" + "Serialization-Type" = "Avro" + "Authorization" = "Bearer " + $response.access_token +} + +#Step 5- This step shows the final call that we make to add schema under the schema groups, +Invoke-RestMethod -Method "PUT" -Uri $uri -Headers $headers -Body $Body -ContentType "application/json" diff --git a/samples/Management/PowerShell/AddingSchematoSchemagroups/ReadMe.md b/samples/Management/PowerShell/AddingSchematoSchemagroups/ReadMe.md new file mode 100644 index 000000000..4dd04e09e --- /dev/null +++ b/samples/Management/PowerShell/AddingSchematoSchemagroups/ReadMe.md @@ -0,0 +1,44 @@ +# Addition of Schema under Schema groups + +With release of [Schema registry](https://docs.microsoft.com/en-us/azure/event-hubs/schema-registry-overview#what-is-azure-schema-registry) feature in Event Hubs, it becomes easier to store different kinds of schemas under schema groups and have seamless interaction between producer and consumer application. Since addition of schema under schema groups is a data plane operation ( not intended to hit management endpoint) hence, there is no publicly available PS Cmdlet to abstract this functionality. + +This sample is meant to serve as reference code for adding schemas under schema groups using PowerShell. + +# Prerequisites + +Please ensure that following steps are followed before following the sample code: + +1. Updated PS module in Windows machine or you could use Azure CloudShell via https://shell.azure.com + +2. Create AD application for authentication,here are additional details: https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal +3. Please keep a note of Application ID, secret that you had created in last step ( you would be using this in PS sample) +4. Assign the service principal Schema registry contributor role (To know more about how to assign a role: https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal?tabs=current ), so that it could make changes to schema groups. Here is quick read about Schema registry contributor role and permissions it posseses : https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#schema-registry-contributor-preview +5. Finally, update the following placeholders in sample code with information associated to your environment: +- Application_ID: Application ID of AD Application +- Application_Secret: Secret value associated to Application +- resource: needs to be set as "https://eventhubs.azure.net", since we are authenticating against data endpoint +- Tenant_Id: Tenant ID of Associated AD tenant +- Namespace_Name: Name of Event Hubs namespace +- SchemaGroup_Name: Name of schema groups under event hub namespace +- Schema_Name: Name of schema to be added under Schema group + +# Script Overview + +This PS sample can be spliced into two REST calls that are being made. + +1. Once we have the AD application details as talked above, we would make first API call to fetch the authorization token needed to successfully make schema addition call. +2. After fetching and formatting the bearer token, we trigger another API call to add schema under schema groups. Once this code runs successfully, you should be able to find the newly added schema under schema groups on Azure Portal. + +# Additional Reference: + +Here are some additional reference links that could be helpful: + +- Schema Registry in Event Hubs - https://docs.microsoft.com/en-us/azure/event-hubs/schema-registry-overview +- Event hubs Overview- https://docs.microsoft.com/en-us/azure/event-hubs/ + +# Conclusion + +We would love to hear about your feedback about this sample. We would be happy to see any pull requests if in case you are interested to contribute to our community. + +Stay tuned for future updates from Azure Messaging team. Happy scripting! + From af22936614ddb5752e7285a5be239e446c432eb9 Mon Sep 17 00:00:00 2001 From: Sannidhya Glodha <62641016+Saglodha@users.noreply.github.com> Date: Thu, 7 Apr 2022 21:00:49 +0530 Subject: [PATCH 58/66] Add schema to schema groups via Bash This sample would act as reference to add schema to schema groups in event hubs via Bash script --- .../CLI/AddschematoSchemaGroups/AD.sh | 9 ++++ .../CLI/AddschematoSchemaGroups/ReadMe.md | 43 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 samples/Management/CLI/AddschematoSchemaGroups/AD.sh create mode 100644 samples/Management/CLI/AddschematoSchemaGroups/ReadMe.md diff --git a/samples/Management/CLI/AddschematoSchemaGroups/AD.sh b/samples/Management/CLI/AddschematoSchemaGroups/AD.sh new file mode 100644 index 000000000..123f024dd --- /dev/null +++ b/samples/Management/CLI/AddschematoSchemaGroups/AD.sh @@ -0,0 +1,9 @@ +#Step 1- first step is to get the bearer token using client credential flow. We should set the resource to be URL encoded string for eventhubs.azure.net +response=$(curl -X POST -d 'grant_type=client_credentials&client_id=&client_secret=&resource=https%3A%2F%2Feventhubs.azure.net' https://login.microsoftonline.com//oauth2/token) + +#formatting token to drop "" quotes and suffixing bearer for final use +token="Bearer `echo $response | jq ."access_token" | tr -d '"'`" + +#Step 2-Making a REST call to dataplane endpoint to add schema to schema groups +curl -X PUT -d '{"namespace": "com.azure.schemaregistry.samples","type": "record","name": "Order","fields": [{"name": "id","type": "string"},{"name": "amount","type": "double"}]}' -H "Content-Type:application/json" -H "Authorization:$token" -H "Serialization-Type:Avro" \ +'https://.servicebus.windows.net/$schemagroups//schemas/?api-version=2020-09-01-preview' \ No newline at end of file diff --git a/samples/Management/CLI/AddschematoSchemaGroups/ReadMe.md b/samples/Management/CLI/AddschematoSchemaGroups/ReadMe.md new file mode 100644 index 000000000..a11ba8f02 --- /dev/null +++ b/samples/Management/CLI/AddschematoSchemaGroups/ReadMe.md @@ -0,0 +1,43 @@ +# Addition of Schema under Schema groups + +With release of [Schema registry](https://docs.microsoft.com/en-us/azure/event-hubs/schema-registry-overview#what-is-azure-schema-registry) feature in Event Hubs, it becomes easier to store different kinds of schemas under schema groups and have seamless interaction between producer and consumer application. Since addition of schema under schema groups is a data plane operation ( not intended to hit management endpoint) hence, there is no publicly available PS Cmdlet to abstract this functionality. + +This sample is meant to serve as reference code for adding schemas under schema groups using Bash. + +# Prerequisites + +Please ensure that following steps are followed before following the sample code: + +1. Local machine with linux/mac OS or you could use Azure CloudShell via https://shell.azure.com + +2. Create AD application for authentication,here are additional details: https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal +3. Please keep a note of Application ID, secret that you had created in last step ( you would be using this in PS sample) +4. Assign the service principal Schema registry contributor role (To know more about how to assign a role: https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal?tabs=current ), so that it could make changes to schema groups. Here is quick read about Schema registry contributor role and permissions it posseses : https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#schema-registry-contributor-preview +5. Finally, update the following placeholders in sample code with information associated to your environment: +- Application_ID: Application ID of AD Application +- Application_Secret: Secret value associated to Application +- Tenant_Id: Tenant ID of Associated AD tenant +- Namespace_Name: Name of Event Hubs namespace +- SchemaGroup_Name: Name of schema groups under event hub namespace +- Schema_Name: Name of schema to be added under Schema group + +# Script Overview + +This PS sample can be spliced into two REST calls that are being made. + +1. Once we have the AD application details as talked above, we would make first API call to fetch the authorization token needed to successfully make schema addition call. +2. After fetching and formatting the bearer token, we trigger another API call to add schema under schema groups. Once this code runs successfully, you should be able to find the newly added schema under schema groups on Azure Portal. + +# Additional Reference: + +Here are some additional reference links that could be helpful: + +- Schema Registry in Event Hubs - https://docs.microsoft.com/en-us/azure/event-hubs/schema-registry-overview +- Event hubs Overview- https://docs.microsoft.com/en-us/azure/event-hubs/ + +# Conclusion + +We would love to hear about your feedback about this sample. We would be happy to see any pull requests if in case you are interested to contribute to our community. + +Stay tuned for future updates from Azure Messaging team. Happy scripting! + From ab93acf42b5e0edc38a16053dfc14db0e8f55602 Mon Sep 17 00:00:00 2001 From: Sannidhya Glodha <62641016+Saglodha@users.noreply.github.com> Date: Thu, 28 Apr 2022 12:53:59 +0530 Subject: [PATCH 59/66] Added PS variables Added PS variables and committed suggested changes --- .../Addingschematoschemagroup.ps1 | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/samples/Management/PowerShell/AddingSchematoSchemagroups/Addingschematoschemagroup.ps1 b/samples/Management/PowerShell/AddingSchematoSchemagroups/Addingschematoschemagroup.ps1 index b9ae1187f..889bbe217 100644 --- a/samples/Management/PowerShell/AddingSchematoSchemagroups/Addingschematoschemagroup.ps1 +++ b/samples/Management/PowerShell/AddingSchematoSchemagroups/Addingschematoschemagroup.ps1 @@ -7,11 +7,12 @@ $Fields = @{ client_secret = "" }; - + #update tenant ID to the correct tenant where you would like to get authorization token from $response = Invoke-RestMethod –Uri "https://login.microsoftonline.com//oauth2/token" –ContentType "application/x-www-form-urlencoded" –Method POST –Body $Fields - + #response would have bearer token in the properties that we would use to trigger next call. - + $token = $response.access_token + #Step 2- You can declare schema JSON associated to schema in $Body variable below $Body = @" { @@ -32,13 +33,19 @@ $Fields = @{ "@ #Step 3- This Uri needs to have details added- namespace name, schema group name and schema name respectively. -$uri = 'https://.servicebus.windows.net/$schemagroups//schemas/?api-version=2020-09-01-preview' + +$NamespaceName = '' +$SchemaGroupName = '' +$SchemaName = '' + + +$uri = "https://$NamespaceName.servicebus.windows.net/$schemagroups/$SchemaGroupName/schemas/$SchemaName`?api-version=2020-09-01-preview" #Step 4- These headers would be sent along with the API Call $headers = @{ "Content-Type" = "application/atom+xml;type=entry;charset=utf-8" "Serialization-Type" = "Avro" - "Authorization" = "Bearer " + $response.access_token + "Authorization" = "Bearer " + $token } #Step 5- This step shows the final call that we make to add schema under the schema groups, From f8c279553f6bce6d89b9dc4b1bc5b728f07f4b2e Mon Sep 17 00:00:00 2001 From: Sreedhar Pelluru Date: Thu, 5 May 2022 23:38:25 -0400 Subject: [PATCH 60/66] Updating the sample to use latest packages --- .../EventHubsCaptureEventGridDemo.sln | 68 ++-- .../FunctionEGDWDumper/Data.cs | 29 ++ .../FunctionEGDWDumper/Function1.cs | 305 +++++++++--------- .../FunctionEGDWDumper.csproj | 46 +-- .../FunctionEGDWDumper/host.json | 20 +- .../EventHubsCaptureEventGridDemo/Readme.md | 144 +-------- .../WindTurbineDataGenerator/App.config | 76 +++-- .../WindTurbineDataGenerator/Program.cs | 3 +- .../WindTurbineDataGenerator.csproj | 294 +++++++++-------- .../WindTurbineDataGenerator/packages.config | 54 ++-- 10 files changed, 476 insertions(+), 563 deletions(-) create mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Data.cs diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln b/samples/e2e/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln index 625d6b484..bbdbb344a 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln +++ b/samples/e2e/EventHubsCaptureEventGridDemo/EventHubsCaptureEventGridDemo.sln @@ -1,37 +1,31 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30128.36 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionEGDWDumper", "FunctionEGDWDumper\FunctionEGDWDumper.csproj", "{E29F9E83-073D-4371-929A-A1A045B9596E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DWDumper", "DWDumper\DWDumper.csproj", "{C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindTurbineDataGenerator", "WindTurbineDataGenerator\WindTurbineDataGenerator.csproj", "{0C87A54A-AD21-46D5-8B75-4247DA32237E}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E29F9E83-073D-4371-929A-A1A045B9596E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E29F9E83-073D-4371-929A-A1A045B9596E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E29F9E83-073D-4371-929A-A1A045B9596E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E29F9E83-073D-4371-929A-A1A045B9596E}.Release|Any CPU.Build.0 = Release|Any CPU - {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}.Release|Any CPU.Build.0 = Release|Any CPU - {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {CABDAC3A-BADD-423D-B33B-983C7CBD0F46} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32407.343 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindTurbineDataGenerator", "WindTurbineDataGenerator\WindTurbineDataGenerator.csproj", "{0C87A54A-AD21-46D5-8B75-4247DA32237E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionEGDWDumper", "FunctionEGDWDumper\FunctionEGDWDumper.csproj", "{231010C2-FC1F-4393-ABD6-4209523A652B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C87A54A-AD21-46D5-8B75-4247DA32237E}.Release|Any CPU.Build.0 = Release|Any CPU + {231010C2-FC1F-4393-ABD6-4209523A652B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {231010C2-FC1F-4393-ABD6-4209523A652B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {231010C2-FC1F-4393-ABD6-4209523A652B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {231010C2-FC1F-4393-ABD6-4209523A652B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CABDAC3A-BADD-423D-B33B-983C7CBD0F46} + EndGlobalSection +EndGlobal diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Data.cs b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Data.cs new file mode 100644 index 000000000..8b5d40302 --- /dev/null +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Data.cs @@ -0,0 +1,29 @@ +namespace FunctionEGDWDumper +{ + /// + /// These classes were generated from the EventGrid event schema. + /// comments for understanding how the EventGrid schema was obtained. + /// + public class EventGridEHEvent + { + public string topic { get; set; } + public string subject { get; set; } + public string eventType { get; set; } + public string eventTime { get; set; } + public string id { get; set; } + public Data data { get; set; } + } + + public class Data + { + public string fileUrl { get; set; } + public string fileType { get; set; } + public string partitionId { get; set; } + public int sizeInBytes { get; set; } + public int eventCount { get; set; } + public int firstSequenceNumber { get; set; } + public int lastSequenceNumber { get; set; } + public string firstEnqueueTime { get; set; } + public string lastEnqueueTime { get; set; } + } +} \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs index fd314c6d7..324e92aa0 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/Function1.cs @@ -1,153 +1,152 @@ -// This is the default URL for triggering event grid function in the local environment. -// http://localhost:7071/admin/extensions/EventGridExtensionConfig?functionName={functionname} - -using System; -using System.Data; -using System.Data.SqlClient; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using Avro.File; -using Avro.Generic; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.EventGrid; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.Azure.WebJobs.Host; -using Azure.Storage.Blobs; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace FunctionEGDWDumper -{ - - public static class Function1 - { - private static readonly string StorageConnectionString = Environment.GetEnvironmentVariable("StorageConnectionString"); - private static readonly string SqlDwConnection = Environment.GetEnvironmentVariable("SqlDwConnection"); - - /// - /// Use the accompanying .sql script to create this table in the data warehouse - /// - private const string TableName = "dbo.Fact_WindTurbineMetrics"; - - [FunctionName("EventGridTriggerMigrateData")] - public static void Run([EventGridTrigger]JObject eventGridEvent, TraceWriter log) - { - log.Info("C# EventGrid trigger function processed a request."); - log.Info(eventGridEvent.ToString(Formatting.Indented)); - - try - { - // Copy to a static Album instance - EventGridEHEvent ehEvent = eventGridEvent.ToObject(); - - // Get the URL from the event that points to the Capture file - var uri = new Uri(ehEvent.data.fileUrl); - - // Get data from the file and migrate to data warehouse - Dump(uri); - } - catch (Exception e) - { - string s = string.Format(CultureInfo.InvariantCulture, - "Error processing request. Exception: {0}, Request: {1}", e, eventGridEvent.ToString()); - log.Error(s); - } - } - - /// - /// Dumps the data from the Avro blob to the data warehouse (DW). - /// Before running this, ensure that the DW has the required table created. - /// - private static async void Dump(Uri fileUri) - { - // Get the blob reference - BlobClient blob = new BlobClient(fileUri); - - using (var dataTable = GetWindTurbineMetricsTable()) - { - // Parse the Avro File - Stream blobStream = await blob.OpenReadAsync(null); - using (var avroReader = DataFileReader.OpenReader(blobStream)) - { - while (avroReader.HasNext()) - { - GenericRecord r = avroReader.Next(); - - byte[] body = (byte[])r["Body"]; - var windTurbineMeasure = DeserializeToWindTurbineMeasure(body); - - // Add the row to in memory table - AddWindTurbineMetricToTable(dataTable, windTurbineMeasure); - } - } - - if (dataTable.Rows.Count > 0) - { - BatchInsert(dataTable); - } - } - } - - /// - /// Open connection to data warehouse. Write the parsed data to the table. - /// - private static void BatchInsert(DataTable table) - { - // Write the data to SQL DW using SqlBulkCopy - using (var sqlDwConnection = new SqlConnection(SqlDwConnection)) - { - sqlDwConnection.Open(); - - using (var bulkCopy = new SqlBulkCopy(sqlDwConnection)) - { - bulkCopy.BulkCopyTimeout = 30; - bulkCopy.DestinationTableName = TableName; - bulkCopy.WriteToServer(table); - } - } - } - - /// - /// Deserialize data and return object with expected properties. - /// - private static WindTurbineMeasure DeserializeToWindTurbineMeasure(byte[] body) - { - string payload = Encoding.ASCII.GetString(body); - return JsonConvert.DeserializeObject(payload); - } - - /// - /// Define the in-memory table to store the data. The columns match the columns in the .sql script. - /// - private static DataTable GetWindTurbineMetricsTable() - { - var dt = new DataTable(); - dt.Columns.AddRange - ( - new DataColumn[5] - { - new DataColumn("DeviceId", typeof(string)), - new DataColumn("MeasureTime", typeof(DateTime)), - new DataColumn("GeneratedPower", typeof(float)), - new DataColumn("WindSpeed", typeof(float)), - new DataColumn("TurbineSpeed", typeof(float)) - } - ); - - return dt; - } - - /// - /// For each parsed record, add a row to the in-memory table. - /// - private static void AddWindTurbineMetricToTable(DataTable table, WindTurbineMeasure wtm) - { - table.Rows.Add(wtm.DeviceId, wtm.MeasureTime, wtm.GeneratedPower, wtm.WindSpeed, wtm.TurbineSpeed); - } - } -} +// Default URL for triggering event grid function in the local environment. +// http://localhost:7071/runtime/webhooks/EventGrid?functionName={functionname} +using System; +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Extensions.EventGrid; +using Microsoft.Extensions.Logging; + +using System.Data; +using System.Data.SqlClient; +using System.Globalization; +using System.IO; +using System.Text; +using Avro.File; +using Avro.Generic; +using Azure.Storage.Blobs; +using Newtonsoft.Json; + +using Azure.Messaging.EventGrid; +using Azure; +using Azure.Storage; + +namespace FunctionEGDWDumper +{ + public static class Function1 + { + private static readonly string StorageAccountName = Environment.GetEnvironmentVariable("StorageAccountName"); + private static readonly string StorageAccessKey = Environment.GetEnvironmentVariable("StorageAccessKey"); + private static readonly string SqlDwConnection = Environment.GetEnvironmentVariable("SqlDwConnection"); + + /// + /// Use the accompanying .sql script to create this table in the data warehouse + /// + private const string TableName = "dbo.Fact_WindTurbineMetrics"; + + [FunctionName("MyEventGridTriggerMigrateData")] + public static void Run([EventGridTrigger]EventGridEvent eventGridEvent, ILogger log) + { + log.LogInformation("C# EventGrid trigger function processed a request."); + log.LogInformation(eventGridEvent.Data.ToString()); + + try + { + // Get the URL from the event that points to the Capture file + Data data = eventGridEvent.Data.ToObjectFromJson(); + var uri = new Uri(data.fileUrl); + log.LogInformation($"file URL: {data.fileUrl}"); + + // Get data from the file and migrate to data warehouse + Dump(uri, log); + } + catch (Exception e) + { + string s = string.Format(CultureInfo.InvariantCulture, + "Error processing request. Exception: {0}, Request: {1}", e, eventGridEvent.ToString()); + log.LogError(s); + } + } + + /// + /// Dumps the data from the Avro blob to the data warehouse (DW). + /// Before running this, ensure that the DW has the required table created. + /// + private static async void Dump(Uri fileUri, ILogger log) + { + // Get the blob reference + BlobClient blob = new BlobClient(fileUri, new StorageSharedKeyCredential(StorageAccountName, StorageAccessKey)); + + using (var dataTable = GetWindTurbineMetricsTable()) + { + // Parse the Avro File + Stream blobStream = await blob.OpenReadAsync(null); + using (var avroReader = DataFileReader.OpenReader(blobStream)) + { + while (avroReader.HasNext()) + { + GenericRecord r = avroReader.Next(); + + byte[] body = (byte[])r["Body"]; + var windTurbineMeasure = DeserializeToWindTurbineMeasure(body); + + // Add the row to in memory table + AddWindTurbineMetricToTable(dataTable, windTurbineMeasure); + } + } + + if (dataTable.Rows.Count > 0) + { + log.LogInformation("Batch insert into the dedicated SQL pool."); + BatchInsert(dataTable, log); + } + } + } + + /// + /// Open connection to data warehouse. Write the parsed data to the table. + /// + private static void BatchInsert(DataTable table, ILogger log) + { + // Write the data to SQL DW using SqlBulkCopy + using (var sqlDwConnection = new SqlConnection(SqlDwConnection)) + { + sqlDwConnection.Open(); + + log.LogInformation("Bulk copying data."); + using (var bulkCopy = new SqlBulkCopy(sqlDwConnection)) + { + bulkCopy.BulkCopyTimeout = 30; + bulkCopy.DestinationTableName = TableName; + bulkCopy.WriteToServer(table); + } + } + } + + /// + /// Deserialize data and return object with expected properties. + /// + private static WindTurbineMeasure DeserializeToWindTurbineMeasure(byte[] body) + { + string payload = Encoding.ASCII.GetString(body); + return JsonConvert.DeserializeObject(payload); + } + + /// + /// Define the in-memory table to store the data. The columns match the columns in the .sql script. + /// + private static DataTable GetWindTurbineMetricsTable() + { + var dt = new DataTable(); + dt.Columns.AddRange + ( + new DataColumn[5] + { + new DataColumn("DeviceId", typeof(string)), + new DataColumn("MeasureTime", typeof(DateTime)), + new DataColumn("GeneratedPower", typeof(float)), + new DataColumn("WindSpeed", typeof(float)), + new DataColumn("TurbineSpeed", typeof(float)) + } + ); + + return dt; + } + + /// + /// For each parsed record, add a row to the in-memory table. + /// + private static void AddWindTurbineMetricToTable(DataTable table, WindTurbineMeasure wtm) + { + table.Rows.Add(wtm.DeviceId, wtm.MeasureTime, wtm.GeneratedPower, wtm.WindSpeed, wtm.TurbineSpeed); + } + } +} diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj index fefff615e..24b52c22f 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/FunctionEGDWDumper.csproj @@ -1,23 +1,23 @@ - - - netcoreapp3.1 - v3 - c542a7d9-5d67-443a-b50f-0ea02bd96fcd - - - - - - - - - - - PreserveNewest - - - PreserveNewest - Never - - - \ No newline at end of file + + + netcoreapp3.1 + v4 + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + Never + + + diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json index bb3b8dadd..809a3f20b 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json +++ b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/host.json @@ -1,11 +1,11 @@ -{ - "version": "2.0", - "logging": { - "applicationInsights": { - "samplingExcludedTypes": "Request", - "samplingSettings": { - "isEnabled": true - } - } - } +{ + "version": "2.0", + "logging": { + "applicationInsights": { + "samplingSettings": { + "isEnabled": true, + "excludedTypes": "Request" + } + } + } } \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/Readme.md b/samples/e2e/EventHubsCaptureEventGridDemo/Readme.md index b74ec2631..46939ee51 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/Readme.md +++ b/samples/e2e/EventHubsCaptureEventGridDemo/Readme.md @@ -1,143 +1,3 @@ -# Migrate Captured Event Hubs data to a SQL Data Warehouse using Event Grid and Azure Function +# Migrate captured Event Hubs data to Azure Synapse Analytics using Event Grid and Azure Functions -Event Hubs [Capture](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-capture-overview) is the easiest way to automatically deliver streamed data in Event Hubs to an Azure Blob storage or Azure Data Lake store. You can subsequently process and deliver the data to any other storage destinations of your choice, such as SQL Data Warehouse or Cosmos DB. In this tutorial, we will demonstrate how you can pipe Captured data from your event hub into a SQL Database Warehouse by using an [Event Grid](https://docs.microsoft.com/azure/event-grid/overview) triggered Azure Function. - -### What is covered in this tutorial: - -![Visual Studio](./media/EventGridIntegrationOverview.PNG) - -* First, we create an Azure Event Hub with Capture enabled and set an Azure blob storage as the destination. Data generated by WindTurbineGenerator will be streamed into the event hub and automatically Captured into Azure Storage as Avro files. -* Next, we create an Azure Event Grid subscription with the Event Hubs namespace as its source and the Azure Function endpoint as its destination. -* Whenever a new Avro file is delivered to the Storage blob by Event Hubs Capture, Event Grid notifies the Azure Function with the blob URI. The Function then does the required processing to migrate the data from the Storage blob to a SQL Database data warehouse. - -There are no worker services involved in polling for these Avro files, which eliminates management overhead and significantly lower COGS, especially in a cloud-scale production environment! - -This sample solution contains files that do the following: -1. *WindTurbineDataGenerator* – A simple publisher that sends wind turbine data to a Capture-enabled event hub -1. *FunctionDWDumper* – An Azure Function that receives an Event Grid notification an Avro file is Captured to the Azure Storage blob. It receives the blob’s URI path, reads its contents and pushes this data to a SQL Data Warehouse. - -# Prerequisites -* [Visual studio 2017 Version 15.3.2 or greater](https://www.visualstudio.com/vs/) -* While installing, ensure that you install the following workloads: .NET desktop development, Azure development, ASP.NET and web development, Node.js development, Python development - -![Visual Studio](./media/EventCaptureGridDemo1.png) - -# Detailed steps -### Overview: -1. Deploy the infrastructure for this solution -2. Create a table in SQL Data Warehouse -3. Publish code to the Functions App -4. Create an Event Grid subscription from the Functions app, with your Event Hubs Namespace as the source and your Function endpoint as the destination. -5. Run WindTurbineDataGenerator.exe to generate data streams to the Event Hub. -6. Observe the Captured data that has been migrated to your SQL Data Warehouse table by the Azure Function - -## 1. Deploy the infrastructure -Deploy the infrastructure needed for this tutorial by using this [Azure Resource Manager template](https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/event-grid/EventHubsDataMigration.json). This creates the following resources: -- Event Hub with Capture enabled -- Storage account for the files from Capture -- Azure app service plan for hosting the Functions app -- Function app for processing Captured event files (Function code to be added in Step 3) -- SQL Server for hosting the Data Warehouse -- SQL Data Warehouse for storing the migrated data (SQL table to be added in Step 2) -To deploy the template using Azure CLI, use: - -```azurecli-interactive -az group create -l westcentralus -n rgDataMigrationSample - -az group deployment create \ - --resource-group rgDataMigrationSample \ - --template-uri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/event-grid/EventHubsDataMigration.json \ - --parameters eventHubNamespaceName= eventHubName=hubdatamigration sqlServerName= sqlServerUserName= sqlServerPassword= sqlServerDatabaseName= storageName= functionAppName= -``` -To deploy the template using PowerShell, use: - -```powershell -New-AzureRmResourceGroup -Name rgDataMigration -Location westcentralus - -New-AzureRmResourceGroupDeployment -ResourceGroupName rgDataMigration -TemplateUri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/event-grid/EventHubsDataMigration.json -eventHubNamespaceName -eventHubName hubdatamigration -sqlServerName -sqlServerUserName -sqlServerDatabaseName -storageName -functionAppName -``` - -## 2. Create a table in SQL Data Warehouse -Create a table in your Data Warehouse by running the *CreateDataWarehouseTable.sql* script using Visual Studio or the Query Editor in the portal. - -## 3. Publish code to the Functions App - -1. Open the project solution *EventHubsCaptureEventGridDemo.sln* in Visual Studio 2017 (15.3.2 or greater). - -1. In Solution Explorer, right-click *FunctionEGDWDumper*, and select **Publish**. - - ![Publish function app](./media/publish-function-app.png) - -1. Select **Azure Function App** and **Select Existing**. Select **Publish**. - - ![Target function app](./media/pick-target.png) - -1. Select the function app that you deployed through the template. Select **OK**. - - ![Select function app](./media/select-function-app.png) - -1. When Visual Studio has configured the profile, select **Publish**. - - ![Select publish](./media/select-publish.png) - -After publishing the function, you are ready to subscribe to the Capture event! - - -## 4. Create an Event Grid subscription from the Functions app - -1. Go to the [Azure portal](https://portal.azure.com/). Select your resource group and function app. - - ![View function app](./media/view-function-app.png) - -1. Select the function. - - ![Select function](./media/select-function.png) - -1. Select **Add Event Grid subscription**. - - ![Add subscription](./media/add-event-grid-subscription.png) - -1. Give the event grid subscription a name. Use **Event Hubs Namespaces** as the event type. Provide values to select your instance of the Event Hubs namespace. Leave the subscriber endpoint as the provided value. Select **Create**. - - ![Create subscription](./media/set-subscription-values.png) - -## 5. Run WindTurbineDataGenerator.exe to generate data -You have now set up your Event Hub, SQL data warehouse, Azure Function App, and Event Grid subscription. Upon completing the simple configuration below, you can run WindTurbineDataGenerator.exe to generate data streams to the Event Hub. - -1. In the portal, select your event hub namespace. Select **Connection Strings**. - - ![Select connection strings](./media/event-hub-connection.png) - -2. Select **RootManageSharedAccessKey** - - ![Select key](./media/show-root-key.png) - -3. Copy **Connection string - primary Key** - - ![Copy key](./media/copy-key.png) - -4. Go back to your Visual Studio project. In the *WindTurbineDataGenerator* project, open *program.cs*. - -5. Replace the two constant values. Use the copied value for **EventHubConnectionString**. Use **hubdatamigration** the event hub name. - - ```cs - private const string EventHubConnectionString = "Endpoint=sb://demomigrationnamespace.servicebus.windows.net/..."; - private const string EventHubName = "hubdatamigration"; - ``` - -6. Build the solution, then run the WindTurbineGenerator.exe application. - -## 6. Observe the Captured data migrate to your SQL Data Warehouse table -After a couple of minutes, query the table in your data warehouse. You will observe that data generated by the WindTurbineDataGenerator has been streamed to your Event Hub, Captured into an Azure Storage container, and then migrated into the SQL data table by Azure Function. - -## Next steps -You can use powerful data visualization tools with your data warehouse to achieve your Actionable insights. - -This article shows how to use [Power BI with SQL Data Warehouse](https://docs.microsoft.com/azure/sql-data-warehouse/sql-data-warehouse-integrate-power-bi) - -Now you are all set to plug in the UI you need to get valuable business insights for your management. - -# Conclusion -We look forward to your feedback after you give this tutorial a try! We also love to see pull requests so if you would like to contribute to our community. - -Stay tuned for more samples from the Azure Messaging team, and till next time! +For detailed information about this sample, see the tutorial [Tutorial: Migrate captured Event Hubs data to Azure Synapse Analytics using Event Grid and Azure Functions](https://docs.microsoft.com/azure/event-hubs/store-captured-data-data-warehouse). diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config index fb51b296b..3b0c70459 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/App.config @@ -1,34 +1,42 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs index 6945d2ec1..b4062035c 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/Program.cs @@ -16,13 +16,14 @@ internal class Program private const string EventHubConnectionString = ""; - private const string EventHubName = ""; + private const string EventHubName = "hubdatamigration"; private static int Main(string[] args) { Console.WriteLine("Starting wind turbine generator. Press to exit"); // Start generation of events + var cts = new CancellationTokenSource(); var t0 = StartEventGenerationAsync(cts.Token); diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj index ee1da6e49..9969d2337 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/WindTurbineDataGenerator.csproj @@ -1,139 +1,157 @@ - - - - - Debug - AnyCPU - {0C87A54A-AD21-46D5-8B75-4247DA32237E} - Exe - WindTurbineDataGenerator - WindTurbineDataGenerator - v4.6.1 - 512 - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Azure.Core.1.5.0\lib\net461\Azure.Core.dll - - - ..\packages\Azure.Messaging.EventHubs.5.2.0\lib\netstandard2.0\Azure.Messaging.EventHubs.dll - - - ..\packages\Microsoft.Azure.Amqp.2.4.5\lib\net45\Microsoft.Azure.Amqp.dll - - - ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll - - - ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll - - - - ..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll - - - - ..\packages\System.Diagnostics.DiagnosticSource.4.6.0\lib\net46\System.Diagnostics.DiagnosticSource.dll - - - ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll - - - ..\packages\System.Net.WebSockets.4.0.0\lib\net46\System.Net.WebSockets.dll - True - True - - - ..\packages\System.Net.WebSockets.Client.4.0.2\lib\net46\System.Net.WebSockets.Client.dll - True - True - - - - ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll - - - ..\packages\System.Reflection.TypeExtensions.4.5.1\lib\net461\System.Reflection.TypeExtensions.dll - - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.6.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll - - - - ..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll - True - True - - - ..\packages\System.Security.Cryptography.Algorithms.4.2.0\lib\net461\System.Security.Cryptography.Algorithms.dll - True - True - - - ..\packages\System.Security.Cryptography.Encoding.4.0.0\lib\net46\System.Security.Cryptography.Encoding.dll - True - True - - - ..\packages\System.Security.Cryptography.Primitives.4.0.0\lib\net46\System.Security.Cryptography.Primitives.dll - True - True - - - ..\packages\System.Security.Cryptography.X509Certificates.4.1.0\lib\net461\System.Security.Cryptography.X509Certificates.dll - True - True - - - ..\packages\System.Text.Encodings.Web.4.6.0\lib\netstandard2.0\System.Text.Encodings.Web.dll - - - ..\packages\System.Text.Json.4.6.0\lib\net461\System.Text.Json.dll - - - ..\packages\System.Threading.Channels.4.6.0\lib\netstandard2.0\System.Threading.Channels.dll - - - ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll - - - ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll - - - - - - - - - - - - - - - - - - + + + + + Debug + AnyCPU + {0C87A54A-AD21-46D5-8B75-4247DA32237E} + Exe + WindTurbineDataGenerator + WindTurbineDataGenerator + v4.8 + 512 + true + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Azure.Core.1.20.0\lib\net461\Azure.Core.dll + + + ..\packages\Azure.Core.Amqp.1.2.0\lib\netstandard2.0\Azure.Core.Amqp.dll + + + ..\packages\Azure.Messaging.EventHubs.5.6.2\lib\netstandard2.0\Azure.Messaging.EventHubs.dll + + + ..\packages\Microsoft.Azure.Amqp.2.5.6\lib\net45\Microsoft.Azure.Amqp.dll + + + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + + + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + + + ..\packages\System.Diagnostics.DiagnosticSource.4.6.0\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\packages\System.IO.4.1.0\lib\net462\System.IO.dll + True + True + + + ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + ..\packages\System.Memory.Data.1.0.2\lib\net461\System.Memory.Data.dll + + + ..\packages\System.Net.WebSockets.4.0.0\lib\net46\System.Net.WebSockets.dll + True + True + + + ..\packages\System.Net.WebSockets.Client.4.0.2\lib\net46\System.Net.WebSockets.Client.dll + True + True + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Reflection.TypeExtensions.4.5.1\lib\net461\System.Reflection.TypeExtensions.dll + + + ..\packages\System.Runtime.4.1.0\lib\net462\System.Runtime.dll + True + True + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.6.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + + ..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll + True + True + + + ..\packages\System.Security.Cryptography.Algorithms.4.2.0\lib\net461\System.Security.Cryptography.Algorithms.dll + True + True + + + ..\packages\System.Security.Cryptography.Encoding.4.0.0\lib\net46\System.Security.Cryptography.Encoding.dll + True + True + + + ..\packages\System.Security.Cryptography.Primitives.4.0.0\lib\net46\System.Security.Cryptography.Primitives.dll + True + True + + + ..\packages\System.Security.Cryptography.X509Certificates.4.1.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + True + True + + + ..\packages\System.Text.Encodings.Web.4.7.2\lib\net461\System.Text.Encodings.Web.dll + + + ..\packages\System.Text.Json.4.6.0\lib\net461\System.Text.Json.dll + + + ..\packages\System.Threading.Channels.4.6.0\lib\netstandard2.0\System.Threading.Channels.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config index 6dfb23305..1131fe2cd 100644 --- a/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config +++ b/samples/e2e/EventHubsCaptureEventGridDemo/WindTurbineDataGenerator/packages.config @@ -1,26 +1,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From fe3a7bcc24881ce24c25ce39e7bba70a21cdd40c Mon Sep 17 00:00:00 2001 From: Sreedhar Pelluru Date: Thu, 5 May 2022 23:42:26 -0400 Subject: [PATCH 61/66] ARM template --- .../EventHubsDataMigration.json | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/EventHubsDataMigration.json diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/EventHubsDataMigration.json b/samples/e2e/EventHubsCaptureEventGridDemo/EventHubsDataMigration.json new file mode 100644 index 000000000..6cd1a68ca --- /dev/null +++ b/samples/e2e/EventHubsCaptureEventGridDemo/EventHubsDataMigration.json @@ -0,0 +1,231 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "eventHubNamespaceName": { + "type": "string", + "metadata": { + "description": "The name of the EventHub namespace" + } + }, + "eventHubName": { + "type": "string", + "metadata": { + "description": "The name of the Event Hub" + } + }, + "sqlServerName": { + "type": "string", + "metadata": { + "description": "The administrator username of the SQL Server" + } + }, + "sqlServerUserName": { + "type": "string", + "metadata": { + "description": "Name of the SQL Server" + } + }, + "sqlServerPassword": { + "type": "securestring", + "metadata": { + "description": "The administrator password of the SQL Server" + } + }, + "sqlServerDatabaseName": { + "type": "string", + "metadata": { + "description": "The name of the SQL Server database" + } + }, + "storageName": { + "type": "string", + "metadata": { + "description": "The name of the storage account" + } + }, + "functionAppName": { + "type": "string", + "metadata": { + "description": "The name of the function app" + } + } + }, + "variables": { + "blobContainerName": "windturbinecapture", + "functionAppPlanName": "[concat(parameters('functionAppName'),'Plan')]", + "storageAccountid": "[concat(resourceGroup().id,'/providers/','Microsoft.Storage/storageAccounts/', parameters('storageName'))]" + }, + "resources": [ + { + "apiVersion": "2017-04-01", + "name": "[parameters('eventHubNamespaceName')]", + "type": "Microsoft.EventHub/namespaces", + "location": "[resourceGroup().location]", + "sku": { + "name": "Standard" + }, + "properties": { + "isAutoInflateEnabled": "true", + "maximumThroughputUnits": "7" + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageName'))]" + ], + "resources": [ + { + "apiVersion": "2017-04-01", + "name": "[parameters('eventHubName')]", + "type": "EventHubs", + "dependsOn": [ + "[concat('Microsoft.EventHub/namespaces/', parameters('eventHubNamespaceName'))]" + ], + "properties": { + "messageRetentionInDays": "1", + "partitionCount": "2", + "captureDescription": { + "enabled": "true", + "encoding": "Avro", + "intervalInSeconds": "60", + "sizeLimitInBytes": "314572800", + "destination": { + "name": "EventHubArchive.AzureBlockBlob", + "properties": { + "storageAccountResourceId": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageName'))]", + "blobContainer": "[variables('blobContainerName')]", + "archiveNameFormat": "{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}" + } + } + } + } + } + ] + }, + { + "type": "Microsoft.Sql/servers", + "name": "[parameters('sqlServerName')]", + "apiVersion": "2014-04-01", + "location": "[resourceGroup().location]", + "scale": null, + "properties": { + "administratorLogin": "[parameters('sqlServerUserName')]", + "administratorLoginPassword": "[parameters('sqlServerPassword')]", + "version": "12.0" + }, + "resources": [ + { + "name": "[parameters('sqlServerDatabaseName')]", + "type": "databases", + "apiVersion": "2017-10-01-preview", + "location": "[resourceGroup().location]", + "sku": { + "name": "DW100c", + "tier": "DataWarehouse" + }, + "properties": { + "collation": "SQL_Latin1_General_CP1_CI_AS" + }, + "dependsOn": [ + "[resourceId('Microsoft.Sql/servers', parameters('sqlServerName'))]" + ] + }, + { + "type": "firewallRules", + "apiVersion": "2014-04-01", + "dependsOn": [ + "[parameters('sqlServerName')]" + ], + "location": "[resourceGroup().location]", + "name": "AllowAllAzureIps", + "properties": { + "endIpAddress": "0.0.0.0", + "startIpAddress": "0.0.0.0" + } + } + ] + }, + { + "type": "Microsoft.Storage/storageAccounts", + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + }, + "kind": "Storage", + "name": "[parameters('storageName')]", + "apiVersion": "2016-01-01", + "location": "[resourceGroup().location]", + "tags": {}, + "scale": null, + "properties": {}, + "dependsOn": [] + }, + { + "type": "Microsoft.Web/serverfarms", + "apiVersion": "2015-08-01", + "name": "[variables('functionAppPlanName')]", + "location": "[resourceGroup().location]", + "kind": "functionapp", + "sku": { + "name": "Y1", + "tier": "Dynamic", + "size": "Y1", + "family": "Y", + "capacity": 0 + }, + "properties": { + "name": "[variables('functionAppPlanName')]", + "numberOfWorkers": 0 + } + }, + { + "apiVersion": "2016-08-01", + "type": "Microsoft.Web/sites", + "name": "[parameters('functionAppName')]", + "location": "[resourceGroup().location]", + "kind": "functionapp", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms', variables('functionAppPlanName'))]", + "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageName'))]" + ], + "properties": { + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('functionAppPlanName'))]", + "siteConfig": { + "appSettings": [ + { + "name": "AzureWebJobsDashboard", + "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('storageName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]" + }, + { + "name": "AzureWebJobsStorage", + "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('storageName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]" + }, + { + "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING", + "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('storageName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]" + }, + { + "name": "WEBSITE_CONTENTSHARE", + "value": "[toLower(parameters('functionAppName'))]" + }, + { + "name": "StorageAccountName", + "value": "[parameters('storageName')]" + }, + { + "name": "StorageAccessKey", + "value": "[listKeys(variables('storageAccountId'), '2015-05-01-preview').key1]" + }, + { + "name": "SqlDwConnection", + "value": "[concat('Server=tcp:',parameters('sqlServerName'),'.database.windows.net,1433;Database=', parameters('sqlServerDatabaseName'), ';Trusted_Connection=False;User ID=',parameters('sqlServerUserName'),'@',parameters('sqlServerName'),';Password=',parameters('sqlServerPassword'),';Connection Timeout=30;Encrypt=True')]" + }, + { + "name": "FUNCTIONS_EXTENSION_VERSION", + "value": "~3" + } + ] + } + } + } + ] +} \ No newline at end of file From 6c396fc094cbf0a09e7a56d636b5a1dc6b4db153 Mon Sep 17 00:00:00 2001 From: Sreedhar Pelluru Date: Thu, 5 May 2022 23:44:12 -0400 Subject: [PATCH 62/66] Delete samples/e2e/EventHubsCaptureEventGridDemo/DWDumper directory --- .../DWDumper/App.config | 14 --- .../DWDumper/DWDumper.csproj | 80 ------------- .../DWDumper/Program.cs | 112 ------------------ .../DWDumper/Properties/AssemblyInfo.cs | 36 ------ .../DWDumper/WindTurbineMeasure.cs | 14 --- .../DWDumper/packages.config | 16 --- 6 files changed, 272 deletions(-) delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/App.config delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Program.cs delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Properties/AssemblyInfo.cs delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/packages.config diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/App.config b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/App.config deleted file mode 100644 index 390b41521..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/App.config +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj deleted file mode 100644 index 2d18effc2..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/DWDumper.csproj +++ /dev/null @@ -1,80 +0,0 @@ - - - - - Debug - AnyCPU - {C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3} - Exe - DWDumper - DWDumper - v4.6.1 - 512 - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Apache.Avro.1.7.7.2\lib\Avro.dll - - - False - ..\packages\Azure.Storage.Blobs.12.8.1\lib\netstandard2.0\Azure.Storage.Blobs.dll - - - ..\packages\log4net.1.2.10\lib\2.0\log4net.dll - - - ..\packages\Microsoft.Data.Edm.5.8.2\lib\net40\Microsoft.Data.Edm.dll - - - ..\packages\Microsoft.Data.OData.5.8.2\lib\net40\Microsoft.Data.OData.dll - - - ..\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll - - - ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll - True - - - - - ..\packages\System.Spatial.5.8.2\lib\net40\System.Spatial.dll - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Program.cs b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Program.cs deleted file mode 100644 index 055680845..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Program.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.SqlClient; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Avro.File; -using Avro.Generic; -using Newtonsoft.Json; -using Azure.Storage.Blobs; - -namespace DWDumper -{ - /// - /// A simple test program to dump a single Avro blob file created by EventHubs Capture into a SQL data warehouse (DW). - /// This is useful for testing connections with your SQL DW before integrating this DW dumping code with Azure Functions - /// - class Program - { - private const string StorageConnectionString = "[provide your storage connection string]"; - private const string EventHubsCaptureAvroBlobUri = "[provide the blob path to a single blob file just to test if it can be parsed and dumped to the DW]"; - private const string SqlDwConnection = "[provide the SQL DW connection string]"; - - private static int Main(string[] args) - { - var p = new Program(); - p.Dump(); - - return 0; - } - - public void Dump() - { - // Get the blob reference - - BlobClient blob = new BlobClient(new Uri(EventHubsCaptureAvroBlobUri)); - - using (var dataTable = GetWindTurbineMetricsTable()) - { - // Parse the Avro File - using (var avroReader = DataFileReader.OpenReader(blob.OpenRead())) - { - while (avroReader.HasNext()) - { - GenericRecord r = avroReader.Next(); - - byte[] body = (byte[]) r["Body"]; - var windTurbineMeasure = DeserializeToWindTurbineMeasure(body); - - // Add the row to in memory table - AddWindTurbineMetricToTable(dataTable, windTurbineMeasure); - } - } - - if (dataTable.Rows.Count > 0) - { - BatchInsert(dataTable); - } - } - } - - private void BatchInsert(DataTable table) - { - // Write the data to SQL DW using SqlBulkCopy - using (var sqlDwConnection = new SqlConnection(SqlDwConnection)) - { - sqlDwConnection.Open(); - - using (var bulkCopy = new SqlBulkCopy(sqlDwConnection)) - { - bulkCopy.BulkCopyTimeout = 30; - bulkCopy.DestinationTableName = "dbo.Fact_WindTurbineMetrics"; - bulkCopy.WriteToServer(table); - } - } - } - - private WindTurbineMeasure DeserializeToWindTurbineMeasure(byte[] body) - { - string payload = Encoding.ASCII.GetString(body); - return JsonConvert.DeserializeObject(payload); - } - - private DataTable GetWindTurbineMetricsTable() - { - var dt = new DataTable(); - dt.Columns.AddRange - ( - new DataColumn[5] - { - new DataColumn("DeviceId", typeof(string)), - new DataColumn("MeasureTime", typeof(DateTime)), - new DataColumn("GeneratedPower", typeof(float)), - new DataColumn("WindSpeed", typeof(float)), - new DataColumn("TurbineSpeed", typeof(float)) - } - ); - - return dt; - } - - private void AddWindTurbineMetricToTable(DataTable table, WindTurbineMeasure wtm) - { - table.Rows.Add(wtm.DeviceId, wtm.MeasureTime, wtm.GeneratedPower, wtm.WindSpeed, wtm.TurbineSpeed); - Console.WriteLine( - "DeviceId: {0}, MeasureTime: {1}, GeneratedPower: {2}, WindSpeed: {3}, TurbineSpeed: {4}", - wtm.DeviceId, wtm.MeasureTime, wtm.GeneratedPower, wtm.WindSpeed, wtm.TurbineSpeed); - } - } - -} diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Properties/AssemblyInfo.cs b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Properties/AssemblyInfo.cs deleted file mode 100644 index d12e26ed9..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("DWDumper")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("DWDumper")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("c9e1d3c8-0c0d-45eb-a3b5-15f95efc01e3")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs deleted file mode 100644 index 0ab7b9217..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/WindTurbineMeasure.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace DWDumper -{ - // TODO, move this class to a Contracts assembly that is shared across different projects - class WindTurbineMeasure - { - public string DeviceId { get; set; } - public DateTime MeasureTime { get; set; } - public float GeneratedPower { get; set; } - public float WindSpeed { get; set; } - public float TurbineSpeed { get; set; } - } -} \ No newline at end of file diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/packages.config b/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/packages.config deleted file mode 100644 index 5f6abdf49..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/DWDumper/packages.config +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file From 257000316b8b5f6397744162c6b522f4722ad726 Mon Sep 17 00:00:00 2001 From: Sreedhar Pelluru Date: Thu, 5 May 2022 23:44:24 -0400 Subject: [PATCH 63/66] Delete samples/e2e/EventHubsCaptureEventGridDemo/media directory --- .../media/EventCaptureGridDemo1.png | Bin 103287 -> 0 bytes .../media/EventCaptureGridDemo2.png | Bin 42024 -> 0 bytes .../media/EventCaptureGridDemo3.png | Bin 20827 -> 0 bytes .../media/EventCaptureGridDemo4.png | Bin 9687 -> 0 bytes .../media/EventCaptureGridDemo5.png | Bin 12125 -> 0 bytes .../media/EventGridIntegrationOverview.PNG | Bin 83917 -> 0 bytes .../media/add-event-grid-subscription.png | Bin 16764 -> 0 bytes .../media/add-event-subscription.png | Bin 5420 -> 0 bytes .../media/copy-key.png | Bin 15944 -> 0 bytes .../media/copy-url.png | Bin 8811 -> 0 bytes .../media/event-hub-connection.png | Bin 9125 -> 0 bytes .../media/get-function-url.png | Bin 7841 -> 0 bytes .../media/overview.png | Bin 15389 -> 0 bytes .../media/pick-target.png | Bin 7427 -> 0 bytes .../media/provide-values.png | Bin 11037 -> 0 bytes .../media/publish-function-app.png | Bin 12646 -> 0 bytes .../media/select-event-grid.png | Bin 10725 -> 0 bytes .../media/select-function-app.png | Bin 11381 -> 0 bytes .../media/select-function.png | Bin 8279 -> 0 bytes .../media/select-publish.png | Bin 8980 -> 0 bytes .../media/set-subscription-values.png | Bin 18783 -> 0 bytes .../media/show-root-key.png | Bin 5477 -> 0 bytes .../media/view-function-app.png | Bin 36601 -> 0 bytes 23 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/EventCaptureGridDemo1.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/EventCaptureGridDemo2.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/EventCaptureGridDemo3.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/EventCaptureGridDemo4.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/EventCaptureGridDemo5.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/EventGridIntegrationOverview.PNG delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/add-event-grid-subscription.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/add-event-subscription.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/copy-key.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/copy-url.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/event-hub-connection.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/get-function-url.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/overview.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/pick-target.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/provide-values.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/publish-function-app.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/select-event-grid.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/select-function-app.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/select-function.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/select-publish.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/set-subscription-values.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/show-root-key.png delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/media/view-function-app.png diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/EventCaptureGridDemo1.png b/samples/e2e/EventHubsCaptureEventGridDemo/media/EventCaptureGridDemo1.png deleted file mode 100644 index 67412d5400526bf3a1b0a1d188763cc133d6b999..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103287 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ƛTA)>;- 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%0Dw<0%g+^;T{8XB^pC zn2l1fxyBv4PE`Z8ci<(9urEasU8|fcT-nUx_r^At>?zJ$>JUpA@R(pb%+nvc%rfag z?+-VxCzc!2O5eFCAD6*w7`Cpko{-@X9`?zzUgMf6amMrP#w~eEVHP?$7u)g^V_Y-s zci80ov=?8;5y8qG5%l|=wR_PUU#yb(!9G zGAboCaqvwX=3B`$pMEei@l2XtB!avQ=V_@A=XgZWGr6C$p(_6X9EDoIeMh{I?B9I|vRr=r&&oe97N* zanoP(a`roOJxa82t0MmVD|Taf=^R&~aEHZf()QMgxHm(E3f)Gy*~xPpE$fn|kZiux zwPVB2v2hf=&!6ipw|;rowi128p%GE$CpPRKRU(-jEi(00pf*_QDkejPuxi8zcG?}| z2^nRlwQY$gzaSf@3f)z&^~=!fu8;UU5^4{5F``*SjpSTs1{@RjMBgJVn!6dCt2-m2 zI26VYI;Zz9AEOht3*T06vsc(Y@iU%(HP{gKCdZrFv{d6z;>uU$o!gq;7!iA)QZlIb z&&g#1IHI0wk1{A7meN>JM;zwK(=phUGNFGLxQCn=ZwW0!6rY*e-^?vcUNc9RF-aT| zm+H#dI)Rjy^p5wOaydA-`IbD?K#PO9+xs_xc|79JU(!M>8t0P`qT&BNX_*+${g>pS z1Ywi=Rp|`%rkCTRo-*BO($pzq@U8e)I)tn;Wf7kg;pjj&O=9ze`{1)2mJ5J#X(- z0doQ&-L{@1g&$GL#3t15e&Ayb7U8e%0zkZ7yWQZm5H0}Kzj>RxWNSx9BXEg;r%_Sq z7Y^;EYFI!38vJcQAp|q@dFXNqH!)^mE(=!UyGY{#gkk(6q_9;tfwhg7uvwes+-9 zygV*!094zTj3lW~QO4Q6S_ zx$TXMrH%`->M>UsrhzyD#G+bYoA46UY=B(RVR4Vc??eF@LWqtJh+ccZ2m?+FO&sqy zoX|cd#sZCpgkR*lEOC%!r|fOhz`Po=dzctPNlYx04@&|*5S#>2`@U1l!{Wp8$cQ}7 z@Hx~0j0Uz2K0trZp(k?-fSmjQX*k0tAd_Rs3XuT%On2Dm;A@1w38ZuA4m;LXr|U(y zlqhKf?jXj-D%jpjK#3>gwTPtDM_~w%G2n~EZ z{s44LAMgnXnuQNXvZOFHAI6)>bruWr6Fln2Y=0dNQlu_kCex-GR2^(uX++QL{=`5- zaS<+8Y2`K|xcj{dw;Pzf-XPCKmAu&tn7qE{8l#y{85tbo#KR!4~U9 zc(nWMT3nymN1)Tq)^iaS!V88s%yR7v$dSP8WkE;I(HrA=(A9baiJ_G%L6SLHZalKuutxH(_CQVh!7ml`g@zciiG=I7Vq)yl(^F)@At} zd~iou6!XWJw20ulRXrDxp4GZm0HYV~9z;ISufg|6eI}I)8=jF14l4z&d%r|T^FZdq z59FpUp;d$%$d%EZ#iaej#)ft7=)8sg@CEOz9*{q;eKwwcFTj7x-Qcx%CLgG9lSDoC zV4Yu7F|gi^j63PLlu`=|S#5f~Q83{aWbgPJ6~81>s{mXDVS#$%fV0m0(T(NK``N`1rf6xOmZwsUeYRMh@S(- zm`iya5^g}@1vzKyRF8aKfwhMSM6i5m?7j_L)H`?yPv&kfAo{6r5 z$s>>0E--nKOSWTsx9$Tt{~w*_e!owKODSlehh6Kj&qPP){ulA9vjVy&(=r@GF!DbK z+8zZ3gw&Mla*psBh>mkh0ks-U(ZOp{<*5Jt9USWWn8OO{KzvGfCNViYhSclNE`}vAP=#5VTutZg{j@Nj#9hIs|Jyh}LX?`}geN3@sg%_SVlLeYu}dIS?Nw zvXb8Ds+&f0$6KSpDnzz7wI2f0hO4Hj_7W1@S44?TWMr&dun!VK%(_z9In_J+%i@`W zi5RjkuVryCMeW7Gj~Kki%p$$|6M~XC5cUVvZPp&x+yIH|Zji*;)nT5Z{UK>>Ex2-; zqq%zJH^`Dm1|2HE1i%68Sg%251m15^U%?kl#t(pII+T3`1Qjks_Im?mWo1w{jI|Do zD$2_PenWd32MNI>8nZ}7gWv}jv5hj4C!Cb4>BIXD{!X$$B5qKUTgS|jw-Fby%9{_d5JbxbpHYtQfRWfD+ z#B>}>P(--{^&0@-KRx;v-$4n$O}7MVB~IWN6NP<;Mc7@B?nq?BMMuIh1U@ys5Cy30 zO99l+0l3{r2w4d6vJ|#s#I$6?LQbjKjEmm|F9+I#VF)4cC}I+ceA=Oo4IrW|O;1m^ z%SN;w3OwML+tyaU*L_bK*6z$Cl~zZC+3<3>q{wPOrA(#HC1e#IpyRkB(Gue`-t|`^s3k6bHeMV6 z1;Gqx(f<}{nECl#p#&tw?Jv!9wt`0|0Jtk-7%oU z%jWHZQS;~$U+Bq~!}ftv{fpQ=8yzniH9K+*U=X&zMXc#K>! z2GzxAF+$r<4Gvaat<$?|Uq3N+@YrtY-uwOYVfRj{HbtW;czqR3J{J*zk*3}17!pxlp!+L71z*`pwlWQ>o!-p~ED$W1$1*kxeK zO}4|PA2bVB4dH5M`=OUo*nJZ8M9Wc^je=*!AbXZ5N=Wr|Lt$3Q!u^}xeUCt?@3 zk{#`K0UqDHw*mNVuzcZ8iMN12$q?51fMmg#Q$JH}d|IcjkFfR98mo%(^rD!X2)oL& z1wUVB(djW;7ptHpmh}NM5it*a#fIIj#L?Z_?_j4U!ah-3s7O_@seD-9HL%q8mB;Rc z`2d^cGtP>4jDX9`lxvS#uXBR2K&r^+V_&9=aa#ee%`M%QpJ{#b?_P|-6IyW1uh5VG zvSs7yt0#`GP_+_u5VMdJw;90}^fFDsl}$XJpypnUMxccjV zZk#F5>{jV@E<2dbfBvYpLfJj)+jV#`ku3uhun4zfqX z0wh#DO{v14AEr4Un|nNRTlD6p-71q8fcIuwZy}PgLAP^1Y{4Owp07t_JGe;W$I*8s zeZk?4vWsOEYkPv4>5bMZSy8P6RWf%Yrya`c-6T<4ryV1M8>IX)U2Xb>6P4*5FxPk2Ztt^3x#~G`-#mHh z%w)ZAvY~_F<3&O}uu)D&{Lj)Ev$=a$+|B3Rej_NYGY2&0&6Dn!<_S(U7UysB4#OT87_w{HeZ|o>{tCw$a5_)!az_{@6bSllOIsxo*5#dgbUS zC_RMUHC)inlfvETDR}|cF}kp%a-u) zl~U$orNDZ{Uo-uR(w~Zh?9G`JC8F$fSvfc^JB9@sGZM;Y?*z5dS{;}(%j%cYvR~Hj zw+)4`FE6z3$8wfkZn(V-^VN>}VHJ}17C&Lx!(5T|WInX_XfvT;RyJTjFmc*UzPor; z#N^AG(UsE^?z>sb%p5ENGkv&xUGJh zgH=%wR@cVLR-pdxqgD#iTess+O)0-f9f;q#`$l+w_8H~#wl3BmL7vh7r?+eWXR`mp zl}esM#VQd|EIH0;!w?S@8EGO)lVc8Tk%*W`F^ZlDJFpyGOVH*Y&#I*W1UVetp(_*uU>$X3)vTnH6c9C&KCLDoG8Z&Ot@jKa&W?%F?XcPvN$w_}6GvQ>6T}spv16T9Qpe{?;qqcfx*HWLzoJ zOk>d~ntwHLmClEVxpLTraUEScB?ufj{A3j4zOkC+DlX7Vj)+MH;HXASJ<{E1Z({&| zXxuk7%Zz3}t$z1pKRFFeRhs>EdS!2~O@o64fv}OAO+G()uI9}`!{(f+GkC!|Pn;SS z{cNTqW>_h#-~{fT(=n+__^!o|x^G=}>s|@_}UwJ#`jn6w843m32V(qCbFS$J& zvf0U*b5|OIhMf&8<8jfJye!B#R~?@25Z)@z#Ju@VeYjX|m`Wcp%emRa@?lEANuH)c zAD>v4c!NvG1llK38w)5@FO7A1%+=A!3Hba~Pyg1QQc_$<-=?Q$5Ai&WCt^U~@S|(U z#rAOLz&S@t-Q8MJVk63$t{st&h-e4w$GCwo#SS-5!quoiqFhmH{LFN(a>H$tRqenvMLRrKdiOac zL?y(L_XK1&0iFR$?y7O=#i?gA83BD8*&!aene`ZN*Vgp?L#Q@dFf-RBE2H4$AtD*^ zG3Z-8SJ8>5EW7Z?Hd?nW1N-#UT#_|(iSNyNZ2nn9IBMvx>p=yohAdsUT7H(Y!2^q_LaMcx~GyP zW~$ouIj$>MyR*fycG`=Xx!~7U!@r3w)>T`M-$SLn4(RjA+P86o%A$H_qigjjITTP*Wb+Ah%eYtt~ zK@~=!%OLHtr^Gh6X(NP*tPUygO8rqviCH0=)2F9O|ms)1De&nTQwPvO{(|1;G?uff^xJ2 zhw%8f^ONzf=K9E7VB}RzKBWM_y8sym2J3Q1LGHadyy8?0fGNaIL2lkx?6`^z;d~l! zA$4gLbdYWC4v~&TcQJaA>jKk1c?!Pfm0!)BU^AI|Y7fiDD!sOQBaiP^#WbjQNaI$U zzHaZ-bFH48?u#bM4YHesK7y}6oCsYA(@9RXI;lELN`HjGd)*6OEw-<#+$1!1zT=PA z$Yp@JbVy|v`kLg4j4WD2_>z8vv_q7_w4n+>gDn zz;;MW9J1@-FCkz@Z}3LGoc%13TEiTM{Y*^Z?;`HcL` za^_Tq!KK#u*#?mKTYj`q*r&H;wF`@I_4&xe5)VrbZ!4@~GPv1L$%nOk;6PCesh!`D z9b`Ok5XNv;A24}XG5R=KZl}J0yU?r4s!F~Vf{K#r@`r(gS{L;swgacdU*2gvy(dYD zL9IZx~_G(WLL-GDlVb% zlNSR?QiIaTmYsJRywr4mZIqX+>EbjK-~G6zl6Za~C*r}#6s$|OtvnC$pm;l65;pl$Xvd0(27)M__Td9CizCddt&Zc5oYs2tfwbOaUq44U5$&-jM=*gBULQ5Yq&#!E zZ#wj*Z&Q|g0ST8C;eg0N%683oyu`SEkua91lJAGZ#<~+ZE+;0g8E;B!66^}PV}<33BKM?l7zz4U0hIYS$Vd_Vm3 zCV1D8UI9h?VMW8Mms1p7+wrgrc?*=%aZ2vo2)&MP;$*V{>gvo|V~B;gy&7{zAD(St zHI&<0%|1UNF&a63jc_m*_AfPHhJig4%c@ ztV>(|vHf44K4&U_^+-F|0ZD(Ff5q;2_$ZF1l{X!LNJ53^iQocj^`5-sPx2TG0g$S4 z6AdA|a5pCgA%SaVBM+*#eB6&2X$Zpro-#mk3|(ZZigvprGyG~)k3_9y8ER`7ERe4mq97!84X0*iz1Y|gUI4d@u8$ebK#1} zVXB{!>V_B*XtA8tXnw*O;`)YYU_Bxd<+u%gmF1LgK)^52Kjup<+u2?CtV|Uz=*TN( zNid3Js%Gtec7Krgj8q+b;)n`m#+-Q?cWIEEey-weT`*OeiqxM^~=LJw6g^ruZ- zkE(Xtq2e0QW8bZ~PI((^vahaAF!>rq(y{SfVlqXu#bkCdX5X3hV^U^k|MGDVt<0TbS^yccH6f#)dM;Q{7Q0LR!jBGS`rUfod&IxU=$mb zcPx6Bf#kbhT=E2UYvjW%5*UB{ws#%p?E)pOHb2z@d{FS;%XQ@m@ek6KfYYzzzzKN& p@0Obb%EbR+h5CQ(FA4&|wwVK;!bcB!T;Bma)>d|wxs5*73_Sv=N+u!a;6(wl^G9fY)6cj*KMp6w53Yr=U3dRT#=5Jq`l@!zP zFg)ozNTeR}EEy3o9qgKmZ%$13UA|yvj7=I_2(b85?anyB2b@ng;ekgs|Z?6-H<=H?q*L2l( zweD*22tm zi3gIxi3A?(Z*TxHTVo|fM_R9&>rYeDFR#k^zZ9T+pDGFyFD^)aUEbegE+9O&{Rcsr zn>7D7mc>!P+d@6+W$EX<3k<1gf8UE^1-4ZckJNuXJ7tC_Ad5oy$zRWilmOrK@3)hB zKXK3O-LKn+gV;$z-!?$|K=i|U(dGQlOV^#7z{4;%R(Y)S5%$HsRpI;@qmkndEv4qm zv{s=9yT&3K9_s|HmbXx7*`1uvU*|6;dR{wTHhe$rYgyY}SV2j8|KKXpw9bRUn{d!;rx zu8?X^q%Qw4Z#JE)IGD5T+4}SYouQ>Zv+i)mi$-UW05DhkkXs}8zI0+>;azK% z@upgf51(Eu*3T(h?Tc?=?;6GYUD+EkKb%T_Uyk3>GPbs()FE};gBSADcBV;Nb)?gx zY#p~UVKnU6m$e%kTEI#kEjvusaT16#$U)T_f=N!dvJ=*g)odEgTwq-00cY|c+b&=y z%YUs)jx@GgRR2S(jc4ZS?1;KvqX%p5%g9Lf&iAAyCXq&r)^4icH8YW8G7JG`Hzmv5YyX1(FT{0>@lM`ck8cz4w?A!9~i3Wx1C%zg}kKoY_uR?^2^Nsej^< zWGO$9fs!_BiLG`q)%AraR|tC0V-rtn7>Ts+PUxa@M@xO04$-wXOe^4cU#aS5!t!DF zZOHjV^?K6WmiODm0+7CwU z@*wr~Wu)%VOOlMKcpOApFY4ADO+n<`*hVBMHL&v9#imDWRm+-(x0)D?l*yy%I5f)| zE;OH8cym6J-K2(hd>ZE72H#IJe#Pvsz@l_)^0Q!R6WsoQ+ICg2hP5K0kcqlLC((Fe z%$1~_?eX!5#Y3n2aMYe$E&6`6Z*42LosG;$SFa0q%uX@%=wiCa<6>G8YFrC*|9-b# ztiP^^8J~y+xTjUEBwhYa#fv>0YnXeV`Lw1cfTN9yU zE)Pohl0m4Nqnu*>j2Zo*0^ne@N3)zj>%<0GODES+-f(xl&wBY&7KYrMH8D}tj+aUu zHAbx^QS=>q$^w=j)of!<1H_&F)2ig#CNY1TKs_lFknTwPN}nfzap7JNZa8ds_tyz| z8tUH){BD!9aKZaF#!l$lFJ_Euf9^v=X<&H}!={WIoUM6PPBX@T80m^lv z4P;S=#rI?|c7{&!V;d2n%t_VN2&^~9A(_v29L$x;a2Y}Z;j#0UB5F9dSy0<9;~(7$ zYu|Ym7r4So^w;$sYAV}|=Rks#)bEm1+1b`(mBT}eD3sX^+am4}?dNN+u-qgGuaoa_ zL0z*9<`Pe#Y0g+wBTi&Y%w=hji>EAq+P-yGgF-m0;8WwoFo@7Z>+e6qk22&FV2P7) zO28FD8~F~uN;OZk)-@sDM5CDBX)YlcXzhqZ;ziLJSR4E^^aHW5>5!QX3&N3c5MzDd zU#$DBfRf2G=6wAE9y8vBvkzh4Q`u~TjNcuawMWd>rx__!ixR;S@C*hP$=ggus5I5S zXEy4k2zxC0`tgJOWdct#HiKc%CkC(ucX58>Lh)8NF&cTxcz-HY+GR2;MVCo$ScpQQ z3ub*+Yk!-F`vD9;WgF90fDxc!@;xP;(z~mlTf5OK_t8bkNBEaCV7%W0Rpy>_ajR*l z+66Y|9_@1a^+6DKEQ$S#9wyTzY|TleNDKdp(zfjOu%@b zm$Fgk)RP%&owyBip(xGMFJt;j_98MSCmjpJn8eldKoUoLh`hH3Z}E|)#{^H{nT{l zT-)-IR5L@7<|x7%(MiRLNdthxsx+X*V!RRowZn3ExlA7@?ua@cDxWGf86<5ThB#jz z_mxh2s!A1eo-*$r-3hv!&!W!bl^=qrhQcmyII(XWJGe0M9!0*66(jan^R`-S< z+-0ENY~a%><@KU*2AGZ9C(nX4xfZV=@pjxzgkXo*aGTP|;gm{)9<8x`a-uI5DL_}$ z8{;LJ7Saj>Kq~9Vd(6IJ$Q^QVyn_NA=Ivl_oDV{<{;bB86e9&Z+8r1>KG}HlQp3j} zeYfWJVN-t~a~aL_zBw&3X6~E*!U|;EPrJ)f_}zM#??9cXXTLVFBQtZqjqVRM3=qx( zp62Xjf2u*9g-%HPnn&)pw3PDC&L#6c>DR!gLvbHCcEB9Q4EZAPH7PIZM%Cmy!%C0Y zm!Z(H%QrbPYqjhvJN%ijU`x;d{bfuWHNhL^#?wDl?K=pHLea22rdrnidICidiFL_9I%7Xl{M=fKe!X8~~ZdM*A{zfnrQYh9ERjtHTSYp4TJ7 z7ZbuZqz;2nF$v{FrPUfD_MstgyJvb}8+m{F*n)yTV57h85GD)V5(^BL=i8SMw;mq)+@8rN!UHR9<@cwAK^st8qzA-42U zxb8u%RbuF0sw&cVDj+)*i|mF=fjdTr7er zTHiHgiihi+Z3lPOsopRE-ewQ)vO7KE<%=Mih~+e*eH1Xfpwk@t`$lH+>>Yr`pq7&; zGFQ12v4BBGLIB9$-4cSTAqnUDX-yk#mlgg}0N*kHy9BkzTz%Tv?R$2UKI)Sdg*IF6 zU~yC`IF*`QcrWz54`zV#i$=Rr&kU zpFA3AGNm>JhbXrU{5y__GouXf`G`%#7m%+4IjneG=fFwRS6g)1LZX4zId|e=7?vS z@O~yd-}b`e@SRURP;r^82|J3j`Dr8}ek@LU0YD-^~Su97XOSL!YF0?q(^d&s=!i-lu z2tgz4lXf8RCCQ9a0g$!D0pu&ixyRZuDj((bPyf&c;ZsH;!Z%jVIp02FVZn=FK!FtV z3g|SU`Vo9;+9M9gd`Khb?I5&fys)NAI-d^~8smhT<3gQzp`#eW`xpRu2-1h=*n99Z z7+Y*xZMpZ=-&`$C8m|W=YAON}Re$Sfpp~@}6x;mn0lR1nG^cyG?lVI$*1upyIA|iN zpCjZUg)(e~G9Trq7_Y&=2hvL$rhlQ)7&K&{nAhDz8@+HO2p3f#s)v=zM2vl^rqLkn z@9NqjIut%b|*x#_`}H)MN$ZIANfh$;=*HX{tUC0*h_^teHOBdpz*7 zzVQpo@pivvlTfIi{1p1xO@{mG3|ZIoxI7ZSW8+U7mxT#M7>oT0!%`3sNaf?n`IOhz zhvM9Zyf!vy>RdI1Y$cO6kXKLy(-dYx|MIJKDlr^0Q zL;XTa6;Bw1A2Vn1NmXIfctN8)hBIEp?2`{HefuN6Q?j2BuD`F;05WRB#5nV{x11wU z7*#=+3Az@0l!ow6O2(G5nyRV1V4LY8O8o}-f;fUp+y^INdz=*&=sJ7O(!;(Vkt!Db z+Jx7sb9Wg2xafL}sJ|0?8HfSonzfSq!9N|bs5ChvBsM0k6hkC^U4;fwAk&Dtlc@4P z*i!IiDS6GPqf}|On!Ey^k-0m$lY3pNhYY%EOM~=tNuvm`o+sG`!iX_j?*RiyuuqlWeuD**z z!&BoiH^q_H5eke;tN!(6w%LD?`ZhH$*w8W6pNr7j6?s+Lz?fGcb0GakmeL3lrmDM+ z;<6k=dCS*x=q80vvki6}8f4A(T!YTY&}^@jcXIeS`zA}2hy2H>CCS<-)GzKRBlijo zEVl~zU2WZ%WSoez^C#M7cd$t1)R|J}&6mklm+sV^uWZ0!#-|3>A33Zp<2%15m?)^$ zb$`2Vo_*YwUeq=!%gP+@T}EaV&or8Jbd^IWb2Rt+=%by+ zD#qvFZxJ8yaGguv&8Wmokzi#EBq^`92Ax*Gsv{XvfHrk%ZJEAB$)$LgJEE$xtA$4+ z4g?2sgy~D_6fFGRfn+py7kJS z{@@BRY=1t2VID_*xVXubAGUqc7gK-hFbrqEaJH8X^@^Xy5Jy@&NS6+t&q=N{wl++Y zz%kp1iL&duyrzULYV79sj?TL!G08NHT>~zz2enk>ijVAL^RxJBBVlgm33y*sWTMf7 z51-ALUWtVR8DDk)WY%Ed2}M2;JcdkZ_+p9%DicUHiBa~|2Z+>-N+OzIgq|x7uoN-M zRTe6GGipj#vR0bB&)4lPK`xusUWCS(+{n}k9}W}uxVzVY2T|Npm{21@Hf;XoNDZk# z`~=;Xxgw@4QWCvl$NfevW3iGNiaXKT(@zR)DU#ecG2)uXi$Xb{np13_hIQ(>xY&cg z*su`j`so%EVQ2^7!Q*CWAQ`de*SA>F$Sj{LJm6>E!(Dj66yg3wKgjgA4tRMrqm^K%#CQ`5( zK)JqzWD~RzKth_!<|hVuX>SH|<~^arDh|>R#(Z4dfg$~dI%+#lhi_KuKUv|K7p`5U z=kMcWeh~ZZyfbclFGdrE($k;fsmKd^YPNY>DgM^0nYvfz+~n_~#95maMopk1Vb^o> z$BHqaFhTb#aA{!_`BCT;nXc=RVC8{1xX94g5>1^LplOLUn)f*G;sVJSz`=x&qxZh= z&sMCK0>9Q07CwFw3=NN9k3ZK3lHJYp;#;Vy1ec7rL7Lh&LK=&5%x8C3%h*$zArYZ> zV4ntDu-)H!B3{@SQf9lNBZ2gLrM4#Qu_{((2ZXC5Y!g@ZzO2vRnd}t8%LD%``2am> zHBc;6K%}fd8ae&CX)o$#?vV6N(}^q{faN?LMq>xfD*^js_2+vu@hw*hc!n|!wRsBG z13RR34t3Kq!k}_x8cFZg7ko0}L;q7fcWYfUnH)KrOI$VgPhcPbsc-n|3cq?m3Z~=e z#gSNn`zc5G?9!i9Q~Lu3q>>Rk1-RcninYVW*f)zJ+WgTq5MpF83FX>%V`(=-NXa>(V|G0kklv z_kNFN|5=hW=Tloj#^o;l?OF(t6f#_j+T~&Q?3-kdgCG_zu#=;HnWtFR$la1>QicWB znzC!&T4)#iz5XzE+fj5r{e`K!F-@ljB@(Y$Fmh)^<&$}zg7RQagr1HmPH`Tr*tDJ| zm70cx#ZkF}FASNe*fjy{IGbj$0|u(UpdPp0$6}66|lCp>@*xvbN6>+sHCrO9Smd8 zUqx-_@x;#na~?dk3KrP#ttOsE4!kNf54k5&E?+|Q6yJ1Lm)q8cgz@OXIhs2gwr&f9 zbje`XDE#n8IDh+(S`cvM@y|FE6oTu40A&N=9)j#lc?su!QLd$iXVxHr#xBHyt;RYP z1Gvp$WWvu1H7w>fn_E(B&4G2Mg|(rmgK_HdguU^s^|-%kVjqx$ze9|@>~OKg9b_q& z3u%_kF>vR6TJOb837j0*y99}JV^W*)tazI@<(MtYm+SMuY2AXMW#olwFRE3g-AF3f zd_Mhmv-|H&Fbd>|U4&JQWXc_;HWQ?%WIt@6S6 zW(e%rm8O*6*gLR(X&)H&BbdUecm1otyukri$jrsLb75^(rEz}?!7xkg z{r8BRyrOGKr;nuE=S- zVeJ4~-j4yv_nG@sgCTPRi_VlT9W3zUWT<%(2?rSiIFH*jQYCWM#hnSd@pFK?dHqfHGMWA zQP^rVkSLB1`5_@X>R`4ViT>qJVQ4?{u3zFNSfkX(9xY31BrJfB#3)j$>5KYk0jBGC zU$S17eAO6j>J$nBCWLadx@f$|*p8_U)ge5nG0$;4OCSAx^Pt&vo+#4AE0{vw;n{f6 zcwbP%6ttGxjX!MPKPoVCh$c)}oIe_YAODy_S1(Ld)%rUb(*f;*E>8D?*7o;vuOzt$ z0sY1{6(m{GkEFOq^eEr-Lz-?M>|CmWyk-;oQKIg=M{XOw5fZbVS0dxrO>kOsgblu@ z)K`71_9Tb-IhpH|A0<#jv;JFJ-CX(AWq&3tS;mSth-^%$58|rAI59QXIZb!DgWi=f z%3{<2eN~YlYQs9+WO=9OgX`yl;`hKdZ^NhBX`Mp;3D!n*S?`f~uGCi>CRTX5nczJJ zSH_l)`W`;8pwe1mS0I`qlJxmSA=S@pns!TXYZ&$X{i^?(O_5_v_Ti3pu^3Tgul*I~ zJ}KFPEDioH_L>7Z)jq`r0u$3tB#%(acIp-{fo{w?5YpHh1)2pRdHue-VRWshzl!em z606ZTKM{QLeq|+&CjXvVvXWW73B1GT^I_@^^dy&xEWpQruh@Jn=Bba7O+_*Js7iE= z`zV_n2vqOcaw(09McPlTu(xDfKD|Sx{FTeNr^sX`9M}w(1$E9#0 z^)6Y~72yM|*+5^PO#;o+n0%qAGvf~7AWpqHA{*!L41 zWHQl&p&tsoc+}!-CIH(_UzE7t!e&3qDe-9t5Q~;kLo?_bP>JWaUQZ zDZkpk;~6W}@_$=P(Xiyo^P?5@Jx9MozAMxQQJj5<3LCXims|xpnNaxq*_U}!ES#~R z{srH?7tK|_pv&JP?alSQVEasho+Q;dfaw4&25%-fOwJQJY|&RH1Hd(rhOI!len4ah zGGUY}F5rstj%OSGQD-C0EknO<+sBVeg$XI9I;{9Q944qB1=mnXMI=lWHd~c2a2h%W zNtaysj65$!k@m%RSxcgK=-XW}avxZz!;QM4LlAc>b?J@l$<*r33B{x`SK(2n;E%LU zA)R~eC-8hph#O)kGmcD8%aAX1XiiN6iqYsV_-Gxgk?M^KUsH(}QTRBU9pY#RK4Xn`jp;>$h%H+}vrv7k_|Y(9HUOppPAxMfWaSmZRJcD(|BJMN3yC#)BQ9 zu+zTXcRQL~n>iSKJ%slxtmX^(z7?SSG?W9a?1XPJbiZ!lY|-21E@>c7tl4Z2G4iJf z*5M>lpJ8YTiE7hfUC%R#D(Nb3>S9osH?S@OeDQiMI)N)oLRLFd&Mn9_x%A*o9Mpa& zEE;DqtZ|09Dyo?9xlXe*x9qIQzGl*e1e}J7Nd;yJe3JLnCM&$g7Q|-qICK9?S1kA) z)_Bq<7FW%8T|Jyp_vcRDZnW1+=EN6@a$&Q+k)P7SRN&h&hSp{~jKzWAf`T{onoCx87_!vMB4&3O=+{4c{*4t}#LEY}cg??cSSpq{ z^Ck1SO#q!3PZ;RlD|6L|0Fm^9u?}~ zT#u+A@w+s*sI8ScAQlOAcJ8I-=ytmuZ(0TesX#J>RhFs;c`yav?^D*%lqz16z&?SYcMDJK1lqvrv8Xo=;h0A?K@P&qMcvt8eZ7uFiOZ-u3uV< za+B;~m8@Yr;L{|Ws(P!bYedlL`r=nRZ@C(k|J?n#cKUaPTkGf^?srSPOPRgTT6#KO zW-QlB3a0cLgBTjZmpk=j6iQFz$irsUN=8=vCrXKn9KD~Eb z^Z=E%^sy)B4c)S{H){Uxf65`kp6PnyZ&bKxi+vMc`z$ITh_3kXY6u9^6cH>HK|xPM z5ta)K!4LYcCL(A@=apqD>K;rVrhFjB#1vHl|6Zm~)%y8#0MAI!@9{3R>rYXQ?}_cq z%*+kE_$ey*22GF@9rn9a0jRCB^Qjkw^@p&po)%IoHvRIlD05m^QRg%6dGtl}3SZKR z9X#_f4#Mc@=*#1;7huiGHzFSU5b?b3r{!+n^B#nkE!JmKYwM9UM@t1o#iwmLkvi=g z%49j;+xGQjW#k{{=zizH%6^xLyy2EPzHYZe;l+AY!cTu@GBY!8?w`q*UXCqA9RLG-~6L~yd44tf0A;QA!cQxt(=HY_Hc#R!eK2A;x_NR6~?hFhJ*e+BXv^rZ@Sy{Qd;?x}Nq#6x=ko5&joEN1UE*Y#r0ewze z_s;WG$gr36=jps(&w_u=D_?3l5`PcHF1PAmJe~QkpSUeED#GL)5Ut-y)#)@WtRuBO zv-(|phd^|<8I!>x&%Z^!xhi4AV-TI-Akc?L-++a4pH5HhtwpkwsD_O?JXE>kCB$C0 zCVTNVM1j=!C}W5|KcBsjzT@*=J*?a>%lSKI$yVyUn{H{0CO0|CKIXj zq-xse&hfQ=;6(H@G9xW5?c{^%^umJs&9QD$A3f*JwO0}C&+}tjqX$ASHm|?f%7V}} zwWIg<{K#~4bgm`RD&kfHf6fl)Dy*O}b--|yV0j7KTC`xP4-2_Ys2msK)HUc0-o0U} zrpn5(ou+}EhDm z;UGwaHC7MC%48ASG!ZdzQh*~-$KBTV{T--0QT{e4f?QZr6iOXl;uO)mJ*Buk{q_5l zD-g1hsPf_uPw0Hpq=@3Ua3G!1kGKx(y^wJ}*{{3MFlVv;k7ky}W9A$pkDKVO#1in9 z-_cQYX~IK6AAS_Caz~)obU*W_sGta4Rv0}o+zaIo8NFN^rH)#(CltX3(UqGRA}AX- zDlAg-Q}|zQ%Qh6W^UmH+xOY)qfYb4QOrbJ}H?2SJ^049V1?;!Av_uFJ_FLzQ_XXMu zn@D7;pkRyZ!g)Dc)g-=pQid6!=vhDFi852y!|EBB3+n)ct}A#wtImjP^tgprcV9sE zgqSTl8rG`Lof(>gKRUADf+)vP`fj3QBMFcsM{{?x5sYpc@U4eVA<;1;VQNZsFVIbS zk+8*aGw9=K9tp9RiAj$kUHG11YL#wrBXVm7OyJ2iZ6Nv0t0R$3{WA2wQdD@KB_Zcb zv~mQ>DP{?rot_bDh5Ghhqa*U$GA-a zhBV-|vo?__rbJ_a$daNlB>uMr|IG=>L<=IrR&f99lKJhxO)!YvRS)zUNW~y&{LB#F zx~E*ALRQLg*P@>acd?SZn-Nfio=Clf=1ria=(3rFRlH?%@ZhZV$m#bJ1PimnhW~mS zHiqTq6-NIXuN(3*6KUGwV7j**q%0n07CxTw3%kb6)>2{5^d!D+7mGW5)0!!z7jjqBK#Kk=ysQ(?}g(69?5Yjix7{qxKeqT*Ky+b;a~@5_q*O43~SW4OQg zw0`<2$;B?51h8iG2O%RYm6z6=qHh-M z?OLQqDKn!ePKI&s$&poqTsYpFfE0b&dQ`+>WQwa+fBpN~}Bt>+m-p zVp%54cRlvTszPVTl0^C`oW%V@?Ne-*wMYiUax$z#Sf0%ANx>dV(0Ak?Ss>pET@y54 z8M2e|wQqAGk9TD9c}ml~<`SgLW^52+4t3kNbI}VxLVTa^oA14wrn}bb^WJV6sdI&N zv-8TE+v%6?Rwa@Ip?M-QJtkk4zA9wxq)I~OH+^cxqg3_kKa8^gG(tk1b2j3?+zB$e zw_6kIb+P=1R#40ZWNa4WBM&y-hT*D^t{uZb2LxGw00%pX;G4-=jl*Hl7PqJV_s##` zUc{-}1ShT+{buI0qf&?v^#6!%{*8aEP#~t)Rdn7|{*RZGDFe~+ZXYPJJ{?&E8<0Iu zt-Rc9B~jBid$#&Itk7;ZS$6_ObabYRWe>k;o!EuAU{s}^=qDb)L;MaHmzM1ZCMG5> zeh>Zn!Dm+Ej!dVV{Ua-@QF{%B#-omrk?}Q_%TQyv9b`Ie?GzCEBkLx2Bk9Fy0^|aK ztE;^1qDL0`OqD#tZs*oS_rzY=E@JJa24d189(d~p1PKvl`~{<`kb_tatGmqHXR261 z=fl|#BLy(!BebSbO)a89Dzq8CchdFYgc4g4Bw5EQPc51&c|bNv4eK~X@J=i_jT$uX zJK@U`<(##8I8)Ra5QR-vtk!LmLEU{ymH_@M3^loXbaUeh(DdxZ7G70FAg7|44tCIm zHc;2f8b_v&SDa3svWO)SprrxT%pRPc`t9e1tI#v=cRJ>p)*>>CrYTu zx|~@>PZ#S<%HUo(eXx3n*@ z_T^iHY+8l>ITu5J>iwl@#y0e!jG^}YK2{0PN-pQ{6uAv{G%WRC4BHGp84xt$h>4`m zC8UpitJ1^gpJ-qobgD2R=#~6Oy9Yu72TW$8G?xA&4@=OQiU>u`Wc8!-bDR>eh8L}K zFY+MjDydeoRTzUX)o~jrHc2xvBZ>sBI&s)@h5KNwV^^x6V9E~~X&my$kD)r#K*&+0QLvO;;YN)A(5rJD$K01QgXbxu!0_$VK|PGxP9z1=Rk#UP6?W7R3lYLL6#jJ7 zMHLobCGgbdWPO$#r-mb_eH^~Mc1{;MeAxj%vbd7rRm4FEu;@9yS#MkHDm6>hSr zRw|Utwvae!l4DAJB0ZG{jNr5sfNU(znPii9G%aC})MOIAjKVYw#3dgXE)KImA{Vqe zg_r?ah!lG(P}mrVC~i6ab3Rr~8TTt^r>N?COPN&vugd1%zW=YN?y{M{fQE@J|O{ahJ-u?>3D4lk>7cmUBPb?Q;;@rMND$H)RTG%O-gkLNJ^L zWj&7KsoWJQ|B&=aL=JI5tx5tE3tf%m@LD`nyxgt(-OU;KZc4nI9AtuNMUEJ|V_AoT z;ZDXw8fcgk6%}mb00-Y+HjQc@r`Een7TQ0wld*`&EKd_c8m!wb5+xz8hrvL86ra## zwzHZpbbSDT4lKnE=xPt3=?2qZT{;E4C||z%_bUS;A8)aREt{P(1kH+YkrmX#@99U_ zBnMZA=4pQC!ZD2%1#VjAEQE)k*%MmDRc-bJ0SphoI){_e5$sXmU6Ls7w6N`@6P04< z5@4LPh?O>2HOQ*C$fgu^oi~b_mR%@nuZr1tf>$RsK#Qjb2#naM)1EIhuv9BwGF zpN+Xibb2Fm*p29I2PjXWuq5Y5WBMsPnSTB`{ z;sI9c9l`AF`}RQ?C6+EB4IwEb@Egmk+<-gS3YUx4pF+t1sI2C1fBemC`J-s=z9e)rbiPg&;mx;eirYcQriG%$gB zn%%n}R@;3a{{HfRUc2qW>w+AGxFAbe=S&y>oD{7scpl~g&tJT{ z6hEJD-`L4!I2rB?8vaZOJS4!&W>D479^T@}L(ee~*2cshKHKL~b~x-}+eGnQyTyz{ zYZID0f%#!>cooN;i?AutTwJO%Q_;+RhA6t6Yj7JZ!H0M%8@DqS7FTz7`Mi0FX3y88 zqw!`p5#HH29994>*T`pe@?h<6;PyV@!z1mg=6sBjKuv4palLRgf0n=M@}rBY;2q8V zK0bG`QF^B?8%}-t_uCO5S9jke7dGZN#rlQ@>Wh=tT7kY_;0_;aBf7N+NN5lwOudRY zcYZ2InpyZ!mSW9sWS9l&RXV@l#~}LDwWbGiPA_aX7dO)b{b62#wh0t~^vYEwb+Fry zWL303WUw@)gwvZa*%QvLHIl{J3IT~wEe7U@702R7^tWmK5|?tjUv#korM{={F=OWB^8kK z{m{>{h#9(1DGIKWG$h2E%$>!nwQ;EB9y!%9O`Q0xW>~g;otG6ly#Mvxbc^tQcIe`Oa9Ze(u!bmbX(ZNOOoH`Y#DTFM6%l-N zK7pvAf&}SrSyYY_IUYENsu|*dW<~yQhpZ`V2tNHyv#H`E1!&v{EIY?0!@qy)HgW$5 zz~-zL;9)SE^K{8dRh%dF9;V%=l6zXUEFy~6rk3xtnOlA5S(LC4?uJWQ@CzU_Iw3M} zD!z9bboGhvm$X}wU{f!T#>}`I19RNC^^&ykC1w(NZs(rRS$x8~`!JqC$il_$fxG;g zGmw9Ss;NkrgP&F3HE&IRl0=59P1!-p7eXzBL?VAi6Ph5+$8q0q`w*3SKVXVEx@s93 zc^as@ zInYmK>F4yFD$yp_Ns`P;N1nP(2ok2^x*3s+b!|pWVDT{qM4h(qdU8@CLnp~wkk`lu zYyNR~B&n4>%Qx&OAiMdN=~dZ;u>qUGXQO=sCogUUaOfZ+*b`7Fh~@)wEsC;{Wr4Rza!;;j-~(C6%p-> z%LCu>UWt;>+wPaA+jajJ_pU3Fq#uHwSe}l@i**Zz-invKuVC27@2`dT08Fx_rKM_D zeSPrbknm02D_)d(^$4K&^HQU&)m|UjGuz>B(Y;?e-A=y;7Z(?$MebFTd@d7nKI`kN zmx#+$w6=o)=;$IB{n&5JUK`EwYsfstL8(gYeBRA04X{aY2jAqO`|hV(W(OMRaeKg} zzZ}*)m#dY@_^Pm^zHwXO;uPLlaW@;M;HH+AyE0{8hGe-O(_MyXF3e>a`l6;fq|49M4ou;=_LSn5L;Ilg@;A`#b%iA14JWi@(+ zyk?o?8Xq_Ur@=L2Cwhqa%H12=NP(6)eefse36f*7LZ6%^kY7By)9V4EIK`Z1P#A{a z-QDdv4`qEN?^g4G^gZ+!@zSJ!v)2ET0DDC*UiqHGh3@C;=;-L9g&GO#PAVNk!{;$e zVQf_R6IXFP@M`kOmAfq@FN!KhlQcfZMA(mwJ`)8c;vhG6`E)KwrLN=O6Y8y^w%f1{ZHYfIE)TE6bZ ztMPofzTO^M?-;Zkk3%a-1{oOLkJ<*Vch#-=3OyYh)%h#0%UI5EK$5H@tQ}GRUh*6Z z`ch@d+nQsyAHQ!g+8gM6#~~nK`}FPaGI~Fs8HIi(Ooou(V+-fn?!G!)tnj@RWqd6U z?@zL!zf7>EY4gKjQ@h92Dn%%#+VElQkp-e1gREm#x(|(1Xe# zOHT{fWbU*$TQJ>EyE`=P(~4p`%TE-F5PE%qnS8$G#>S(%mt67mk8m%0L;?uDZWLZP zQn3IVlj}bRGy7lh^-Vu04~m)eSz)K-FV&e1nY&lY!L4Sj?Yt3~Lil!a52DMbOi7kU z`xMnb2ALU$M|&71zo(197b-cc@i0ol~PpSTa4#oW1Mf~rcXJj=r7u<4YHjVf)JRgLzD zCa>eAsir{z;zIp!6B+dVdEW=}SuiWrz1!iUdC9e?SQFXLU&A%{v`s~Ca5~*Otz$&> z^~4mAYg-!gW}v&`5xV!3Yk1Abcu5KASd)0}bA zS5*rR*l4SN?Y=M-j{AcSYWp|T-o~uX((KS2CnpPYK}NmrhgmLH__^(C8<+9bz4~>e zINE77NbYj4zrXKgcQ9~abiMXFTI{Ljbb6u6<-X4SjDhx7@H~b|z#6j4P_kx#;w$ko zEU$PRBULEr*aYRqLzxSkW!MZ~Yt~0!ZDQo9YDFyn0a~rp_An}GIhmueE+1$PZv}m*tLrQ{N6zKbC(y6={jXt%r3KXuzLO4;BiMw|yl-H^eiltE* zrLoRsP%8T?w(f8M?o}VbvRKN$5&){KIaupQ+P!y$F`eQWa?6rUy_-rBUQwtaaXk#k zStOtKHp4XP8*GxsAu-&rIECi7a9G=_iVS9n^P9QSeAQMTN)IX z(FPK>GcSbQ|0>G$&r8p^|E?1*vF0hvyX8kGnj!OgNV3u5r~behV&_@wI^aSdnFfgD zS#4Vg#^Q)tk16vWhWx@Q_ zQpzhW86)SWY$yLpOG?wUmo(8dvt}Ad%2e<%tR{fsseY**q$EWXd&bB$1OJJ)*(2)p zP3Qhud+}WoC)>+HhU522UF5-1F@n-X`fA+H+yCdwg~09MuNrMM7F5#N1=GwQi2kcr zo1%e$Uy$=>+x8!E`c8Q57V6d|!#7In$KvAl1FI(~;|1g9-=Dm}QfQ-ZqrOsL_3_0k zA$j<|ro-3)${{^$gZ5&aWj!a14Ad;|fb4(OK-Jo3Z;e_25~~e7e_>DcQ&97}uI%hF zA-v?sZs0kQFs-q)S;qp;$FG<)bB0+%Hqtutt=Ueh#0Bcn5p6GJGG2Qy{0RcbDTA-N z^v-aDB1e^qy@aBsySG+e-1Z?(N;^mbT%4!<_MDkt+m>+-U!BHhPCju{#BPwk4B&w3 zxj}U={qT!;7DQ1)hUeuime7FizQ`Os#Sb|h;{=R}Sp~5z(R&Anc16I%Er9q&p^;BW zhB3F%+KbrrXo-kz*_gY%xK({sFT=&f6LCja8o{cRnLyixi887sZ5z)wCg7%D-_KK4aCc>hK#SOo%az|Sh& z)A6s5B!6KgbY3bcAyn)o-n_H2S5y4`sOz6g2AcXz7z28Uhe8^f3FG1=*t-%!#MJW% z+>TtB&Y!pR!lv81ayx(yfN#$kbX)!zz1jx;%ICtT<^Kv@WS)0bxIuJpL_q76enPjO z1atjpwJXP_EnKvcf5oWG!ErB6p$+osKTFLsk0?mIMT)aq>Yh?vpr0}PdrNY!As+L%i zB0LD~;Iq_A+v1NkVQM$K!Fkc3 z1(G_%&k3ROasnaYu&jv9lCKn56o1S`g0nPbKMZdSPUZ`^n?`+Ea=;O7!jV zw{&R7@dncxkdct+*L_o}8S)NNXS4Kc20~Tw<+MkS`GGbat;CQA)WA}1W*Xf1*BTBJ zhLF%0;5s4mT44sc?-D6_*EJyRy$v?hr5oVLdDstRg3Vy8$u#$qCcO$eogg2>?oh%C zGKtooV$&fie$!tH>Tsu z{>1-(HJ3uHA-FR|+8qRijM~-4nwK?yIbMlVt=04d&D6M70%J&pN2vW_b_ETMX;EER!vsKm0eji>KJ=0|^?Twvjcw3L(fb?<|m?3d?- z9ADLy|53|zN5h@%@o3S@A|ZyvD6?z^*(}2lZFEA^AtMrH)QE_h(M1p&-5|O#I#GrY zW!MPWL81$zC4}fnlqe&3zuCN(^UgbOH+$YW@6X>k-*fN%o%_4@e%kMP0+l6sKn6eW zaK->RomC46JZFRxfPsX(O}P|ec$TLquWTKF?IR=o-p{Qz0JI}P^~AH|tP&m)b`e67 z>D-HEcz`H_H62h5k)1>Pp0n99-WzjTm5PoU-JmwMhUR2y%d=Q^4ibK}^UMYd=1@Yz zCF~Alb1vd?vkzF!jQeR#wR@MTYSpW&>b+4cUc$kU03L9leGq>}1&7lZg=bWG(VfWr zMD9^F%J=rk=BI6H1!(fb zqUfi$e_+J1x#2S_r3YW3c0sOv{=m(Mdr0 z@>Xa7VJGF7mKA`(iHryDPBT8Cid>hDzihpG_s&Wrfg4->_%Zo2(=rsO7$J0wx8O2t zw%=!|M7r%jgjVU z@u}2+mp5IL9+x;JU@r`QwNTolO-jNWI=(aPF5Ci4*@=nFDTtT1@$WO?i5wlJz@+#7 ze52yFC-y85h@9Y@dnV-O=Dzk3Ik9C%BxN?Tu3a#2rD#i;Ksl_! z@%3{A9a!3wgl?Msu|whsIjf4tR+evPt4e>twc_TJ2|1fobEVHf@u~X~25`!rE(|*tW^QH3`NxN-=^PA1 zm1t(yn>M_ph$}>SL6gQ70M@-hKfRik6H7?)%TFaJ4}qc`B!1`KZ|voSWL-LD{@E}n zrDGcN$Zu`@=S2;iu|<mn8N<991pvK;VS?lah9X}<7Ot4x+WFes)6>&^ zh#x62$d-i29xwY7iz)g=HO%aa{m61Vokhv3>?sZSE^n9uEYsRQvzUbw0#eNIF2M*Sc-A!6M#FtJqw1LJvI?$&CpSad{+)W2hGuFNF}VEt(urNfeSObJ4{x{+^=3 z6*xPM_2&%M(&g+U97FaaL0!uCNKOP^7<$?+hF6lm#hl(`eA|r{tSS5 z^|%j_-`|PRFJyNua_2KWkE6tk&HL`Fqc!q|udtmO7&VTcft+zZ;&9YZnqZv9`D!nQ zuSw`CQMe@Tyw7>d^}yVv@R`V4=wOSy`6P94_Na!?51D(E^AX3NDsr<*tb3xaN47au zTM3y&-TDn)nXK41Q^rbz9=A~!Q$JZD(Fw6(f7S76TG@KDv}y6eW*UKpYz{qLi^a3{ z@eH>pao!h?PSRn(6T0kcyR^oprdkVYH#RJ;TzawIN%+NlS zbQ0>$TJl=VeuJ2>*lh>rJY+f14Cdn)Q($G!2bWH3W)SSUDxn(#D+J3drR99i5vO*8 z=Q^VhrN|Ux^+X`>0E3h00O2Y$$iacm+Vbm? zOz-_Xpuwpp6h?Vw%Qfoc>`e8u(^2^hy!Jd3>Mx{;$06n|cQ@u(Wm-QS?Y5t*c(dQ< zKfiRp{*=EBY>B=MZGk=*h*sHNy>U!=5eE_ht=OjgA~Tww@?<#6lQ~mwMluUs7u3&cbs5KdXCs8-n|iPl@y)fZfTyMHe=)(CM@L-Bhok&)g zQ|L}z9?lWHCW4rV0(71rSk@t4m4a8@i%@kbaJTjF_`rH&ujBRWG@_C2q^$=(v%D>K zxB!qa*NxCAPBaajlI4*hr%NA(m2RRy zVU>95AuT}OtZ?QT<+DQ-A9>$b5aaDo=DkiVKHC^<0OUwaicV|$2OrjeFgtOVv`fAc znae3uB9lK5$Ap5dEd-Uv&zo!kkntiR7zh^31ADDbGt)31Xfr7_&a+k$; z!>AmESIv{<{mWIGY}vIC!0tZVW@mwrXi9g*+s)&~&0v)UT*Mmzu*)t?PzNI|{IkLgG2 z@)$VI*Xef~5(`9O6q%wp5n(zH4zW%vk+S+@R&gGT<{U-j@ mC-~OMe^zMU-FkI=&L}tX%XVBkW;6M9-knpFtfd;b7klgk4D diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/EventCaptureGridDemo4.png b/samples/e2e/EventHubsCaptureEventGridDemo/media/EventCaptureGridDemo4.png deleted file mode 100644 index 9079b343fd6044f5f2d810e26dec147b7b8d6fb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9687 zcmeHtWmHsexUT|Ai$M4mpG<2qLM{EsY@E3?S02ph$PBDBYldARP`!BOnsz z;eXb-=d62Ato!YLxO**ySu^ZC`+cA1SI>?>YN-(7QQ=*>bcqn5s;GPE5{47}j>f@& z|2e}l4dBORS6vnPOQi!eXn2A3SWZ*!(xr+x{1dY)@EX@i)zJ0QCEBoyf0yHycdRa5 zVzxsl%ISMP+?e*VBVTPf-%&k%qkFg5CaGH2#V7qWqO8=YST~uCguyb9iz%Lk{(4#g zZXn6+g7}ck@~ywETaP@V+go|9JMUNv@<&bbUnRIYHSy@ho=@jsM1aHhYQ#-f%w|)n z+|-y_cjY{y9>pP0pGOu>b9a@g@gH>&n7Ehs%pz6H`@G0kw6G z8j9>P=3P_)&dnkelhOy-WF~fut8bYQ#C%9*MC9{84umci2M3bqmgGd8<7}=%*a3R< z@l>sSg#iNPphr$#go}$Sb37ck+4^_0X|pj(Bc?_T<(B@oNY zw7y>So6*4U^>K7!Qj*)o_nP~o&vbNkKVg1ubYDMPo?G7d(e!L{y1~%Uu)-cOvXPgE z;r@H=>*2I3QQ+}j_POu=&*6%1j!p-^COtO3Cp1-A_Z!vP89F#P*mXWjN=d2n+*z>b zjQvupUikX;wVQm8*2aoQ-)Lv^TXaN_vYJcu(5tNWr3(5S{Mw=@nrI6+pKlMtU77F@ z3keBXA1~8JAk0qTeM^o#f+i+JUCa{u5-gfqT zR9lAD)^9blZq~oa;YTAHjjmu+CoXz%m5{;Cd}{Wdme#e!`1=(bx;r~NjLOkC>y{7v z{r&Ir#?hRX=-Wx?W+aHRqAjLS1yedgfohY7rsuy+pUwIm^0vC1pB~DbY`0@^oS&`T zYm2NoTc9|c@!8T2I3Dd!7wL@UQp(X)w6?Si?#INw7ELE}wvQeyd2DUXV_YAfS5;qM z|7>gK>)X4wU*CQm&R0=aQ?nk(XmCT1TqUGxK3;p*0EhMXw;kxW_n`VhK+Wz#sAd*&1yIRs|6tG9#^Ud^ZH|0T{Lkz89q!WYEMGwJO zezrCiF`XvrY|e(hV>cnIaZB9o$xO4C>q;LzeuUI6DrY(VqK1+ZSv1#1-wYP2r;Ln@ z7}YuS&+KNelVp6p-yTXxEo?(30M#-XJiXkTVn`?9@vG9R7e~M2jW-Lv*p)yvM%In- zGP+S!P0d0q8UK@`alWf!%|gAN4y(`&$5i8oFg{f=&lGbF)nK^Yy~t?vtpRmkd*%I^SD;+CuhHSpGfSVx>Yz??$(L zX1%+(yWDF??}_t>AxxGqK_SUwYbLY3_=Jt&aAS(%DsE4}AX@>gm`ctKa`IvMa9tJw zx&_~lL0598N==%)4>vU>vt*G~7+Q{2FwlVVhF7KbMd{RMuit|FUOmzK6A<=m;oRZ;#&dAMT%$}f}rdQ+k! zYWy)767k$&`BC6x=eU{nGG~1G)t^PJ0Jqa6Qw^Hwo7OPf8pLni_*?!}?#;S;>>|j;&3dLz#U-rf(x@DK6Ho{$yhw)qD)C`-WHs6|Slu>5dX^K3td6Pxkks<`Roj&Re{=X(EM zQ`DbKL3IruY)suNHU87En#IUo_OL}wccjgz#%8PauLD4b2=rx+?i<~eZ|@(Zv?Ht< zbr7U=P+^{ zyL{>O(xf*+BuWKZf6gaUv$M6ahf)=~n#)B>_ITGn-(n1&jeChpH}kOGi9VX(*j3zH zK)*}!+LBxKPz<@zlfnM}Wm)se{T$x&GfYEOd_l9!;ZGGf>-5NCHFP`D%ExeC*7}R# zPs-O+E7y5g-8iY^ua%^V8?m~cu!m2dKK-{(0pm+V{zL8r`Un)mqyJh5 z)Z1n=AsWq|(W00TB7Jeb|4SA8Pk$KBf>c*)t=C8T@*GA+T^zlc4T_{itd;owU)|8> z{`Ct1GKT1X6(ra^fYq&u4McYyc%jn1ev z+J5>u%2sK0Ff+nl73H=b&V>w^HDCU^uwJp@=mg9kRR|EOudh#L%grh*{5$#H!+-r? zy;opbVq%r!Y%6ym3WXXO9d&hewfNf#zw72J$4rC*d&j1e6|D|tvvS2j8H31RIS0nP z{?4>_j8?(}2rMA>pKI1r1{xU~XS{srvG6%!;^5vjTJh?D^E2D=(l52={K)P(U`EI9 z)x}()j*2=u!|2gB=M5}pw+6DLdh=zity%USqf&THrQO%Y+D@?k%9s~1s>B+%cnjBZ zBO0xKM9cOM3`l!!-~LECb%rNb2^_Gyfwk7l+t!CSF9Ku)R8VL0)utnw^4#~=Gj|X; zK;Hng69+OJY;4f&mVcg{v#bterc3*I$K8?wR;dM^zG`U&w4^BfBEDqSI$i+!#Hhmj z3y_$oBq!&(1T81xSgwIG(0iqia;-eTu>HMB(;Z%3-dY{1q8gj8J%fYUB91dX$)^7H zN5{X{3&^;0+Yf8K_Ev&}v6Q3i&+|ctk=j+n1VkBfo3={U>ev7nS#od^R07Wr9hvBa z3%0`|qi?tgV*FnC5(U`IOP6t(Se?x8z5IK!Kz{?NOUf|8Qb=WvsdzJKmPtzE8%hK7b^Vp0Cmk9ucDE9NgxZjvf;g@KM~ zF>Ujok0$FR=#7Bg?UBJM*HVYuy-IM?Y2h>ORkN%<%aH;EG(=xBXnG4Kr7};3a*(om8oc+*AMGrBkwlbx&3_63 zJv9`@^+sCS|3uUWF}uw`cH@RiYG3V17pfqA%NmPAM}-Ml&{5mwaj}$ zd2w;E9ScV(3s>~z!N(Waf*5faNdwVUAPb?UTq;WTw`Q}ASsM^YwFg>q>VFcL5hAnw zIQq!k(uXZ+)%9*@5`Nh)$}6DS*KONqn33%%sGn7Kla(Mm66wei$SmpnkLEuFVzPe$ z6{V>>5{8kmmUyF)xO9osOWC6`N}uthr!`1%F5$JCbtV==X=PPaJ5Pp`&&vTOp?S@3 zB>uUX;>rExw~!2@U3i(3UzBu2{SPJ|8(*nme36ut6yH=J8YuF3fM&N$J%wkg-13i_#_-o~eIIZrztD@%sBU&P_ z;Z_y@NB~D)TQWtV-e8p;p8VN!dr)ITPWmW>f=Pd#MxJq%VN8JzF>;=aN2I?HV-(2| z?~d05mo6V@Gus;fHQi7JBs+f?dt2wVcJ=^H0scG{m0Wx@jhKKUnU0X-j3mc^VU;zp zbv2E&ujhy7mzQPCSSrFb48r+?%1@9Q>^wZNp4OS3)RLatH6vx;1<3xG+#y9uqk87= zn@8)faHu*6#3|fl%E%N)+0^fc-(1LkciYcms<3EG>?JmSq)}-sIaMmFltS3^h~b#0 ztINyW_sgGezfPED&UJNhk*C9(29zC2bV+sJl{m3Z<8My_Mw0t-)#i`T=^dQsK>37} z0tJBX;G1rLP-R>Q=6X6=$(+nq_&`}%+28*xNA88V`}xdlD=l$TRRX&n;)xpcv?lrN zEGShn(bEUM>g(?>bifzpU&kWKRH%D?V?c@S8#{u6_hGXeS~p1W7k4|(FT!l{Fd6g* zL(x0cL)mh%bTV2sJsO|x`5yk7Y-gD~7&Pr#;P^?y(pM84RVbLySJ7t%KoYGH}0*EYnJbe7glkdrDC=M;9D;!>l85t)VwxiFV z?`spOp&XPTJOI~rev+Ag9!}uD*|2I(jbi#C&T*oSm_>j)KWfK;*G72+W47at``Q!g zD7UCc7UZbb%Gsa_=WZDpg-O%qe~=HuRVe{8kLI^zjCR6aa+(-l9Gf4Q(_~vbT9$q` z^#0XaX#|?Aub)m;7Xs}wLObxE#vT8Yu=x+k$iIIyFrBz)ywpTpRrRLOlOf0rCM3ZE z7U|^c>gl!5WJ)~q*qrtPcWvehO9$d$YrM?Va1{`Bl%A1su`7YG#rwC-M7i1N@o$j6 zhPt{W*M_-Qfn_-jN{)W!$5Fvq-#-xXuS^$l+ytKW_7?Zq+uLK+&T0mAFg-mD_hsFm zc6wp-juzuY9HzTwTvrETXv8X=7dx5>LkTERnVFi4$(;A@m)$FaT%e`Sx}VAjV48}K zt_`#|AfcG+3RK@JKu0y5ly?&UvtJYZ(D%oJVJkp0_TSxpG`j!#0%8W;Y}I??8`O~K z(-9`|Dgoz(&qUHk&vC&%qXEo+Et~Y;Zf;SJOLTkF1WHL?e+(QHTr%Yq7Z1-$?7>15 zFAzYA2_z`lzPsIn{s)4aFQ$*47}nZNo*vGg&%GcT$d<|O|NQwg*oZvcLNy3lX3NbK z`qP9dBb&GzY;$HBadH61ys8Z@?e?1|J9uL}ok};WBh!zSVhKgq-GNXT)f<7D0T35mFxvNNjPLwr1ei z4d-2P6jT1Y-A=UCv?cA~yaxL=8px%AK;)iR4N5X*zBXfhw$@qQcp&tjI66NCWHri=b6)2I?MHZsm!(IM^_*}{SKkwSI5 zzfruZ1~Zt#He(=2E(^1HiCJ_I>_!izfyJXOk^{vu3-%7mPxpPO!2VXixx_~eZgpIB zzLeN~C9qbaYjD%e>o__XHIE0gzP`H`@OPsQY&&$m0?+RB4e`-L)obe?&rbhld#|xG zymWtiSDD4n3va1lzUY>e_jW8ZGBp5PE1^E(WB)s3)3YsUx1UId@OK99^Azt_KOt_a zf9m3>rmoJ&&Q4K3$YWR;ycX<3^Gxbf@&kGiP4MmdHu!1}96Y8ep}xqjj=vA56RKIX zh?D9dO1j_E)3eYW;gm;WKUOpxNzMs(CGNVSfl+h!odGz1LKU4*$OzNv{Ge;-0#2Oq zj14^ZAc_mybw1qukxOmZB@v7vgthi(Zxux2kM|Gih#8fUNCD9;wi%;+06-E)8I1aq zH?)!yQh$~bP4UN&;F*k5MOLA4!8PmLzuzSo7|2oF2RpVYfweYS^|+W7TJeK@k_1&9 zQ`Rw^-@eXfG$d@Exs{=A8 z9x2(2UEUB6I6GPFj3e!6W~Gd5?;b~53a&ywg<&%Pn0L_4sde~~#z6ftP=*7gu?vy$h z77#~Fyw;>PkjIz#`I7s=Zid_bPn{WDBFH2GRM@XSsD2{%Z6qdJ!Z8{w1Fg8*PsroK z?!eiC&={E7Q*@ELvnfipP_j_9kaa8X!tsKy#Wf9LL`EP4 zDt&WSR#ye3wOtw-8lcR}^xg~r#;6*4yXd}FOi-(|e*BoUXh}*NGh=-Ar+OnIP|fNC zZ6w2s2ik4^r}g^Y6nO{TW((lH_-B~3)3*o-;g zqVJ7rAPjb5#9v&0**^6=`*(hvG%W93a}?`aTv8U~hLx37#k23#Pa&Vg8N6Sx*hv>a z22#jUfEGO&mCA}fG>nXkQzM1HW4K9tyWo91t*8}U3nc0Yc8Jojs|O2}nv zvDWkV+FgSu^wNf_tsZk90{8dbj82L+UMjz$6?3sXKRX4xbuzTKyL*HV6Ty`E+1ICG zbVR&&Yc3%wTQt*)wLE22kV>q;?bUgl$k)~EfPtwOn3Dus;sc*YY0F312dn<%wS=dTB9rY-ee|p?c@JCjQCHf z_dlOsK>PraLmZ8m%YDc??g|BZLpPO_l#GI=C_d@B_ur2^{+-zWkF%3g7kPPkfdji& z_K+~0nVA{Z8Fwpji zr)f?-OS~uZfTQ-b-^JBcJ5&7b!SQtX!h-q3chS)V2IiU~&*i}DFs8m@`a#ce2RUA1 zs0Vm$)%!9;(_s`+Jxxtb!t~iCAOUcPMaB)gP$0AQ&WoT8Iz4<B;520q2-iQI@j2H`&8m?ooYJ&-6AI=;{xu0xUpg*;ByJkGDQ}NCp(LFmhVbm zYWcd4MHb9u-hxrBbNJEf(K1VH~$4yM=~rV!@^Aak310e=DdwP-u6aV~O_;Fj6o zW_oKNbCRjER<`nm#YKQs$|)YDUigM=god+C&v;kyHcSD?GnQ6epdY|ps8AHXk&$6Yqu<{Hm?+o*-qO$X zfGNBK)1nf-!nxkAE}TLpMj8nZu98Fqjh1y7kywQC8V417xORr996n?9li@s2M@)p+ zBSElEdaqu}FfM}R5%O*B?us6K9uX1IC&|ri57EDs_9e+1e4>S`5OPlx@BpAQV!F^1 z$P4#*!Gfe^W%)ysW@OM*Cfd%kDL<&RL_oZwQdm#`j;R?q6}0)>b??wW*^*u;X(0KN zlfA*oW{(Z3&dL=0rPSM;oSZ_tYy8Yqy`~s@cHc@SK|eKIze7YP-6tAF!D}7T4?{9n zoxXT?6bd15?ad1LqOmdLNIsv|+oQ@sG{!DBUM0HK*Q=G!gq|vzkTrp*1^^egK-%v( zI4xTCM~y87qRRYBBnW}lv*UHZ?ZR9AgM&n2a{vyeKIv3(yNPlbK_o@Azz7OUj9bvU&vUK#&0B-_Y5}FO zwr>&)`NKf!t@n$}T4JH1#o~WLo7>K|o?e7y`10R(!atOVT7WXgog2YF78r--d;ram zCTzCyhnJ;~sD`9()_GHv;h z%;>3i+p?LU^}Z5)9RbI1Oam6Je1BXrrMLK;50h#duzIu-$Mm^lFB1X4Lu5!O3 zNmZ0Cue5Yl--VP1QLo}Y(e%twH!K17E%0MJ4f7O^JVSgRelB?^w;qU&av;H5UnozD z*SgY?7`oCVfo?etuQ5YtW85ruGm@%bx41>~ibm=){%U7Y73PWTop08#h9)FS_{?;# z^I->5_ow;K_AV|0oMb`96r{HR0qSM>=3&mNBNxi|I;47iwoT^o(sx{S6z@KlW8W+O zvEmG{kq=)EbuA0-f-MnqFM7+KgYLfTx^_4lAfxeubO+D%h89KScMy}INvAGkh><$v zd|(e@W;CwzCzEul@FK=A;Qbq|o9eM7f>`!N6mmhK@^|cl+?fl%3D04QWi%A>3KRW`|+5$drzO?1(D9hV!C={JFoj(;14|186 z$e-<1n!2LwA*o(+m{63HyNnh9V-XZNcR9r9DA^KeY^=c%EXhcq%C6O^6I})3Ziw|Z zMZ2%;MEpmM(BV&Yi4f5%aCZe(>lueSXFzX`*{o$mR0w(a|}_zB%=hB+jA z`&^th?1X4p^O##w;wKO9U~!B~I84`9IxI0<5x>`Y+iX|y*XIaQ1>p$LokH-=iF=4F zGgm4TFH3uIk2-ad^=ycn=&Bfb5L++ zV<;E16Gf@03IeUjZL**RbWn5$z5a)>puWH=B)jf`jsr;x)=1D5d^V?4YL$wVDyI>U zk_j5H0P5W8ZVAf9{$M;jy^lb=Dx|7n-x5d@dRhsVY&$`8JRK7MJSF_lwV4(P(%X7s zFRxos^`++HSYsro1QiPeT;=-fKoR~2gxD^@M+IC8ts4S3KO1}w9S(LM4d=*V#sV9N zQ4CzUz>P|Y6FTZ1Q5g7Pb8ZlH>mex7)hZ^cECX!IUM{e`4l9G~H zBDIkF{UR|<0AS4fVP7k!f~Ru zJw}-#2L){w*A`X6@6_ z(2i{x6~t`;Q~^^j;E)D4b zpAD;&Fgx$om-r5+?Fd4n3))~U6x8XV5k2S)Z2k0gCkJV;<4R7S9x*W_AETboQ(<`y zY9W=LF|5Rjw>>l^cCO&Y<7>_41YKTUlU`oE0nJ>9;}p;?TTY6%zsv@l1k}M}3(o_M z0xK&kVRS*-8UT}}7Rn;>qVjS+Mn*>8fcq#nAHjcr@Z`TyVgEcx^3RA#trUhp*f0-{ zij0I|`~f_E@+R^ZbrA(>8+fxq2qB$ S8$67438AE=SStT0=wASeBZ1}s diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/EventCaptureGridDemo5.png b/samples/e2e/EventHubsCaptureEventGridDemo/media/EventCaptureGridDemo5.png deleted file mode 100644 index 13f7328d1a7b40672444ff4a49254cd682df55d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12125 zcmdsdXH-+$zOTI?9q9??Xn`Tv;obYtH}twVCiI+NvZ(3`CbMT_ORiDeGOj zbouk8OIL2)x&oXD{&9gxV`}RvUWA{s! z?uGt-U5;MbvAJ|f01sAvXy9$JIpY(P@f4orTEO?T@brg4dY;~r6fZYvS-if$RAJ40 zglN@IKE`NyDn<>4e&XaFP05}==$;_nT+V;^lSJ*lJqt;7j7TC7z-Kw1w*Jw>}%0s{LY4;3p3 zGn?B1zgU;f-bBL>b|VAbM;f|5$?Kh;{@Rk1a9T>7pXJ%8esQu~Qq0%tsq-VKZY4ac z@#LJ;8FmsyHeNFIEA(b>8M07tfdQex;%_?>;?;z|ST;QNGH%)nr|I^NpS#$iR}5HR z3M3e*K0W63a0|PfaBi9S+^=WJ&-~8pbj5xXw`D56bvI|l=mOv2lI5|#&Ghm)gXn?V zG-tI!m92T6JI6Z+N5J_`yd&S)f^J7xfdw2^<9K#Ztqq^YX2o$~(3W<4LYe)1By?p+ zN6?n+Zc9*~nZX*5UDOQlpCi++;M`?bBZqY-&dt= zJjLaU($4Cyx%d)>20zKd&^wh;O&?d@jZ1v8D%soqtQn(K;pfw>EYLP5THas`#>Iy- z6}8#u7Hy&vOj#@%PbVtbjqynI&+F(8Q^-tprZ_AwFbNB(fIQaY>y#SO%r%&T@dSDg zywLmpO~bi#Z{?kx!vuS=py@$}?399<<$AA$hv5F9!qKmpLod1W7DvL?Njl?JAZ&Q- z=peGwIP&xG=|sOITh z>XFr+lj2@R$Gk~`rmovXSxfRhH&g9$1+yH~1|f%;JY74=|D&5mUqAG#XSInMn3tW%Ww=kVj*`-oww@ zX^oC|TUuLtXHEyctg*7ve)GE66i(9PzL}(O)B|%I!}{({ahnHR#0hQ#(@!_ixOkcQ zNXo$HR^ZBOeFuS>lW-~DubsQ#2$(<tMg*sdMi6pCfQYm^$MyNypN)#4A?k7!xQKwcz=VbJNqFxE6c2 ztVLdFy58hOMQ&&&{fwlrl=Cdq!593Ga*?~py`*E6rzj{V=i&rUY76HgBQE%5m3w*b z*CiHTPp8eeB+P2f>zjhmYP{y>e7~dGChs0SGRMXd&39A9r(CHka-{rqcB4W4r+CwE zBQNBn2Yp%tbn=xzDQnWlIn3+zNEM>&en!@1h(%ssY#a2L_`}QMX(8&Cvk`*VQYa4- zu-Kt3JP9nSd%1U9$$AnoJ4ahmaG3;_htKg;W;502zuX;*M|cR~nx+IfW5@CGeE!7z zyKX{b;qO1+gvJK&{CK+7e}|0BE0Ov3d=PozY3bdnV)wFo!S#|60kdOrGHyon`JsZ< z2L@h!AFhq82e!*PA;&IT49e7NUmpoVB`xJ7GSjEN+u}bI+Hs)i-rb)%-8x|04&+lv ziG7hXoXwLojTbUjddJC{WoS~UTcfijfvVF>=DToJ)=5qG`>s8d&BGL#rM)Df=iZUU z`|di-AGtqF>cfh#`N?U+7JbPkw-e$NolVa3f}1SO5BBF^SC@M$xGdkPHkc<6n$tHd z%`xv1`bM(Mv_*ANxp*DV`8;-}sjETn+LBsctJnh2NI%EKc8$q$*Ga%dFAZeRt<4%81DOtI;mLW|s{J^)#r1MTUZkI+eCUrO( z0|fv#1c_BO#Hb78+6E0t74<;|80TKhR^s1vsH!h?){;2ec4X>e*_O_^Eu%cX?+xPS zN4?|{n;H;9J`6;UiKvCX$=883lgrV`A-?Q!JzLI8SG3@(W&n}u{jwYuPwrOfjw-lS&#Ax{I zv)e3J`b34*)p0Y2a@=rw6X6dls&Z_Zm2x?)aZt zpbFmco6051*~$^h8_>LZA>ZGpoG)qme+V4xCBs@-^qY7Hinb3n{1hp=bzh=`Q0~Z} zGkc%r;@A6$;*&A5!_aFkZ?2oCy7#?0%xnAcWnKp{f!NYwKbf8E=@&`WoV}R6dCky2 z*S`TE#*lj+Z9JXSS#sswS>}w67Uwl47#q`L#{(vHjD!OdBCX0<2ZLEwZPkgeWhy-d zfReC=0pRsia=$vw_h#1d+uJn@SgCN-&!M=y*m7`>r3t+&nEz`4 zXVsPHHMina@Uiy}8bZ(#mR$z`O;d3N|E#a^$N60u%|7kKS2m}`?g|!F{k)mJiHeL_a%ZQP zsVKnD+~yU^usMD^I$2SL4DIu8>$9wOyMuRVB?w?_bch~+kKB4gb1IRT>W-Owsz{Y? zWx>%Z?B_4ZhKXPkK<3!k3DfY$RTxasboW6)CR`4MRs4w=0L^L+={cE#Xu3ImUk^oV z;{Va~EKUeK8)ebu%b-DE@k<&2qu}inr537Wx9jW%YK=&DEN`5+Ed`#=#jVT@3{OpU zS0J40_7%_0TnU5j0+{pMJ7rp0Z1|!Lm-A)e%8QuIm+z(!Ck;QAr_L9@5ASB$cul_= z0Pmi68o@g_27}@RYYvX{x|?3T*umGf4oR~OKcg;=$=X%VhTch@ty}gW!N7A|;~zbsBSNdaI7@O+EZmE3V48ikmfl^~ z?RUQFS0K>1f1sq(xR`Z8KsE%{h~OcoI}=8zfH_6Nyao-3wJ0Z4>ExbI-z$xzvz5Yj z;oJIod8^?omZFCd8`AHNcUF1}&Rx!rKg!Vzt6Z#j>D2yMwrM#3q9{AxLO^UcY&b73 zDr<*p0OIntdC{hDygDc!OF{9)YKOn%Q$9<;7RuDwP8v7AF?W##3!@zK1?4-}p7kjz zE)stZ!g8^?osUYMPc~Hs@_6E~clv9rb%S;Jg70(-w`>G&5n@#@*302-1|>Y5>|>7X zNEN>6-4@Pjx6r~B*>=m0#fvRRRU>HZ$w~y~EK-|P*lJSOU7x`aDx7-rbkYBYrO!<7 zjM0quPidpGV=fTOaDzycbC4O!B2KVr@~Wh!Az{RN0JRE5f?Jp%b^PF(Wf zv{^B8kL7%e?#ldjpjgt+=g?8i?6(2I7AtOSMxffb?nU5R?e{3!9@D~^w^ zyfupY%xCS?k)Q1L)pbQRUq~eHSpbMKNm+9wC56CFWBe8!tl6wg#%PMm&6IkFZygp~ zas%z1*PK<1(6e@|qsWnh=WIM+r^l3l6b4(H$sjI+%xj-a>(v>asieF~>2I*6a7hF)p!HM%I5qCXP7q2sd4WmGeU?z)&C(N9@B>J;hx~@4U;m{|r!``l~ zLo%ryps3ksVE(DWd*K<|9}N*o2NhY~gOvyuLL^2$1e`1vjlCH4jHVDE& zMDGLZcbaxO-T5k$lrnq?cxcz(5B=y`u9n9&B3Z4WH=}G|)n`9Er|x;7tvFgBNqIbA z;Y045S$z>GI;}Z=y(S45sl&G^zkYMC!_SPIo*S^(KN_r?wMxzfOe^A>eIAh*Gqgc_ ze0rpf0ydJjyamI$&k&g8&eLG7Bn@_b5U%6fGSxd;^Do}bC{y^^hNA6atetuDiFzQ% z--`R+GgAMX>rzPKutBPT`REWR10fpDLMxEEUNa;<_br+Sd>y8XBEscxQ2(_T44guy z(Jyc3jm6{|4);J#7i(#~XW%%W_>mqGVqyf*||BLxN{Rz)Io(UZa%Tx z-)X_+ym@)}m%~Qg#O-%|pp9%^>Gw&j-0vosQ`_7Zg zTl2_oZf1$eo98EncuMDHrX4e~w1WVbsLj_@h;Pp=&qS(I$)H zBowXtOsA%!~e4 z6Prqpz~Fn+K)^cENid;|G>(Iz4dZfWy8rqL;Bp3;0F;o)SINQf#TKZl&Fg<%S=rly zNdGLIt@`1jr^U~2rsftD6iDoA?~O!(_2PiJudk~+K0bcFiC){#-<~So=v_J6q83C0`jCnHrfD z5mP@uzok7fyXhMXu%5lO;WX+c)WMa7{TZk=30j2?o2}L}5_GF8tYEbV7L^&+5dm;i z#mI0^gUB=D_sp!xwi*R(qieCb(?`xZ`oV)fgr%fmB}x_N8$*22wGEkXOW0U~;+-A* z;cVkeiB--sUA&bVq|i$_lz&M2VK)Bz`E7Dt3J^%gd1XMrFMNSRCj# z8=GT}X#c(SN{S%AZ*t3cnNYevMDb#s?ZN6JkFVfPd5L!Y5Y1~6>w>HfB96A8E#5Y0 zgyItxw-jD5`yd`o*Zo!QW~2%jHaLk^J4N3q^B1)TsWTuNpHcCHwXFXWsJsK#vOKC{ zWdvp4lgfmsOy$_L_*WQ{%?WeeoUGK(*PO7+3b5@f>HPu)s{4QZggfvedpJ2;i zIFYbYj6L3o%@$U`3o9B8DL(<@%x&2YsvyWp*78AXYyWF+KtL&U1o!Q4j2qc@!(2Od zD58X=Fv4IeRdpP_sI79|L#~{CsIcL4-F~B&(l^?;>J*Cb5Y64-;|V_WH*f#5N)9b@ zUiv{PszG10T2ADm&{!V`sO%!t;=70Qv60j&zL*jPqu zw(`n@UnYVy4=GjFjS^k%C(o0=q28z&xvH&+?#LD+V;f|f$>GKeXh+`}jppVY7JPP^ zfDmhrf%8|wj%8eji)G@=!SeOhd|Df_Xpu@Qs8jF}eH z*Qdo+;#P&-0ra)BWJ&1j>$^ew{PmZb&YG!#qfAaM%3h?3TSP^Kb#{|&Z|Z8fBo3m9 zqeOuF-b>M=uv}?BP4qlq?ObEM>cZD??Nnu2_$14>v=z zB=-f%HJ*f3@S&i?_Q2vcjecU@k(zGuc;Vt3l}jpLRdmA6O<;CI*fj^C3&Gk5?+gsfmZP80=(R^81XSulMoMod@(UuQU5SuT@rcLVU zgQPIZ7=~D_!bjdq8Xc=hUuNN04@QX>-^I6C1ZalSM~1oTN=qZhn|GhrsMl2!mFd+E ze4lwG`b=#2MMJ)p$1&v}Ll*fdXf@kdLv(pAiVb-!JJd*K7lMp6z&}$HPC6t9x0cex zhPd7}$hk@3W5#)}^kW;e0Ws40$^jLkiB*@tQxJy{gr|E@CWGEiIi|E|we$R=?ghw@ zwH3$^y$AD2b^{onixIYy1U)e$4E?R~Pf`Y8j9GTDpEiFuuA~zUDFzR1+59Jz`iJxZ z7KmMcW~19u*T?N|XxMU3N@1<%=46+mk~R%lk@)&cqTNOAzBI|`iRY2A4*s{nrNC;9 zCFh|3pzWrWBEtDj7ydEF)s`NCLX9C*hMtd=7?)5LQYnq-i(0A~iuHj2h%zv#t?9fAtE?|Sh>~cphy+m~Hz=?yWrquyyQR*o@SXyDjxy}#>zKN-(e z7=JK0*zcVaNAhYtJoZ@)Bp0QVkRvoNA~XCVsPIU|9);X%A9^~}CXCWlE(W+JlImXx zTOn8A>_Pl*6(sum=*quhrGH-unzSZt?Syzvlok`e?nu#(Iq#lsl`t=Tn={v1Poxs>v2dvu)~`*A_) zNF7l%1|#5!`e$dVHU~a<=fxl!#z?L8-sXnNsXVhNK;5L#eVX-T(9-dzW}TEg$&Fnh z5t)TMs>;NJokvn#4+@m+C<|2iuxD*g=j$5s-9J!n3#=2=)^|29CuwXyc$I%b?}qn? zugjfz-&u^Mh^PVIrb}qZ^m;7tVx}&k4cv((9$~k9#LTj0U(`nT`9=>Dm=@Z18UbGN zSTq7l;%Xg;;|4TU_0zGZuKTMGJ@RAs@>wEO{i9{&0+(KY2Z)uI>>fl@@~ zLtpYo_8h(zp6&hxb}aqSKLcv8z9&6mWcZ$*o&U5CoZ3RQCcG?5Zacn$@#h!>Inq&G z=7GAyab3P)D5V{WM8<<#W1s@toeM!q6n44~8F0E!!kLwGToXLRe(ZVNHYh`_JJ3Ct zI5iS5OZtw0rv~Z6ciO*xw{AV}$`g^EKi_cC8S?%HOIvNU$aF=SgrTJ@kSc{L^oRv4 zB;F+cpV?hZlx90NSH9pk|1UyHMmZb~MgA-A@qexU--Rk8c2(qEZ%ljS7{mq@4zJHK0=0!+K+(7A}A!63a&Vf!-2*JEgP} zn>hV^J&KEhMi!d7F;{-oPG@H9rdQquRd4;6dmD!6b!sEM#{`8e!Eda@Sb$-w6s^`+T3RadUICjUGR@_?i0)9KXUYJ>6;TE*)i}0}lF3ZZ73Nw>1Rw;| zjB(jrf{!0lBAAv+zKN*H3$%w%hoE^1(f?=D_doUpPXPbZNLaKXHt79sbV8WP*mOlnxRH1O$v*_-z(s!Mjp-O1|`UU3AxLwLgU< zqJCCZjl4Axr!m$+)BCSvcs<|jSDdSIn&K@;7jYslrcUGs5(>rbhTTMd(<%g}cQ1M`zC?r8X8=mWRc)O|j)!`wLS zh|2&E)os;nz;_Uqa>uJ5(ktiSC-?k+HTNr=fI@3hq}`XzUX4B#we7KrWi%rEY9;GD ztlw@r`4Fv;6DlTswl^$&ht}MK!X^8hnFa*;8mh$YvcA*KVkfJ)^gf6*qMU-RzrBT9 z$bDJU8JS6@aP%FeA@Cz}^*dKT88)wk3rn#}lp)n4%rZJ)y#uYSb~e;kYV_cuBU z1Z&L}J~*&AM)GJzi_mKCKd~%2_#gcUePG%`Yv~_rmyCqCVrQjFKqc^lpyyZpLSiwi44=i)Q_IwY0;F$*r#~>Fda2KY5t*0d7>n829Pe@BKv^ zm5y~E(97TrR7k@;wgml}%Tbx`ebR*Sl619?@_1lH`=l9J_$&n+&Zx@Io+y#YE3e>} zy1}idfsH~fWHC?e0Mbud;Pb#+c&GV?6l8cZxa3MC{WDf#@#_b0kts!d;gHRk%rc!_cAqj0JBE$+<4%*^;(@kd?J1J5)| zCa*A>k_Id=&b^0^=&A~{-cbUysdb=lH-B}Ex*1}hmep-J#SW)V($-eHlBr>ln|4|M zp4YVNG-Wq>gvwI+S6IhH`HLI}(Skg_ zK&?T1o#409x3Ivld9%i2ZD=xs1ZocEW;gyNaj0?0LDF#(a*a$#x1}Y5lZ;;3y3Nbo z05YPyHP9cY>Hmbgd!F_RvBumMIt)=0uKg&IQ)glOyBZY@RC30HDo&L9f#5uns+K;{ z+ghC%#{bxVQSxe8OC9RnH=y|Sbfz_@$@Ifr6 zuc=v#`$Lsp2D&bP_p?@EnwmOoR1K(Lx&KhnYiqj8r7lcmE227mwrL~+ko(5bdwYAo zy1ukiu8rvHa8h_1{stG{Z@p-vCE;ZsTM}wNCFT=gLK2AjolYOU=1ym_=2UrCNsYz> z_3&in$BG%3;=wlTz(pnYG=tUtyxl+2%j6F{=$lPB)M1{^bWG|Shl1O zqNA9$n;oT}HTztmS*~T}T7rs3D=k3y_n$AHF5ic8N+A2?c6;93WImeNh9}(=9}6I~ zM5yT7Jj23c8krw{4cQq`B8$W{JmOXbGd(`vD^Rp~bP!U~ker@Ll#~781N#`%TK(8J z>bq6t)7nN4Q8lCH+uZ3d=K>D%GH+!7pbMd`eu$u>}hu;IH$TgX=X=i^JS;<+oK$W05rvT17$L1 zjl}M~Gb!Z+b}9%iFtihW23wdC*BpXaywb6%s?38;38p- z8&nE3*s58G0_+*OHj0|_3_YGHVnZ~T@)-E9kSmW?au##Oek-7QsP4$F9t+;o=k8Sb zsA8)d-6sbw96)|Td>AyAzE=X?rM5STbL#+p?9C#568UrV4de(yn+)Nn{ zQuPjwfHTgel9;Rmoq$i@s})aHRh{}Fl<9I5=ZRzO6D(_$?QE=NQUO6&o|_F2Hg>Ug zj1TDV0??N~_XGI*|Ks2tSNl8=vmV?tAZ%n%U%h%2uqwnbe@n|bAPc3x*c;aI^6(Hl z=l4rx>G>)*GcyBt2d12sK{_t5rHLpk_O(Xsp~ z0ZA8%W)`kSyI)-~^c_0Y{UOeUFAM+lbfpj@1>Edcf}>niRa?eIT7=O^i&4>Du7U#rMf!SFICN z`@hFncIo`SlBm4$+P%9Qs!$5cbY8F$eG){utNgB>kNmw}*Xa>kl*oHoI=u=DR^f3_93hS7fPE|Mz(+HS-8y&55nyQl0MTHClcS5ldj%Br6e4#9GZy>1CJzD(` zjk~B_>XY40mvosu*qj37%7TVK?P9}j-w9AY3(8;yZAV~h{ra6u-}SPR5vhXO0yr0O&tnOJCGs5TPUMFT_kJ=- z;t(GJehSE#fbos#6*;j_U1P*aF-SO1d$&=j{;USX8348kMizwglkIU*wV|?##pk*x zT=d_~7?mWj=c7}|IhZUCZ2UL~{?nG89u>%+40Q zb9t)8_4Ts0%Y3kOK0s86**tPa7Cw*62>BT=R>lPdp#nIpN;AOdZ&sRDuQ>uikUG7# z_+0h@s5UE9m4QAwIyrXw|=< z489z!CI;p{Xfjxl&ZQPF>g27~BY%_IB78$n{~% zi!xY4E_#X)DojR8OpmxP%g6q3H8;0=H!QY|L<=e8al<9ou49MLqh!Ik&EodbKu@$x zTuNCluF@YwNwxN%LC6dwl6l=kor&+hSqDQZ(k|2EEQ!xwr z=}*_gil2bblt^tK&5CHv%4*3x*f!DoQeh1m0$rIE$IpGf|_Pk&u(^8Z>NM6v?UFD~==@OdqN%})jX5`PJ-qODx^$m;F? E0{R%YcmMzZ diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/EventGridIntegrationOverview.PNG b/samples/e2e/EventHubsCaptureEventGridDemo/media/EventGridIntegrationOverview.PNG deleted file mode 100644 index 1b12e73edfe766bd072a129886c108bc118a1c6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83917 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 diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/add-event-grid-subscription.png b/samples/e2e/EventHubsCaptureEventGridDemo/media/add-event-grid-subscription.png deleted file mode 100644 index 468d29a6f417e51288b34f46b55a457e68ab5ce3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16764 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 diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/copy-url.png b/samples/e2e/EventHubsCaptureEventGridDemo/media/copy-url.png deleted file mode 100644 index b807de3169b3878265061bb14ffeeebd317bd1e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8811 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 diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/event-hub-connection.png b/samples/e2e/EventHubsCaptureEventGridDemo/media/event-hub-connection.png deleted file mode 100644 index 08360628c26f8d9cec1c38d7d0d81574a8f41696..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9125 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 diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/get-function-url.png b/samples/e2e/EventHubsCaptureEventGridDemo/media/get-function-url.png deleted file mode 100644 index a37cee2bd499173328907691f8ae9c7689ca9500..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7841 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 RMf6($SRJBPscQ4)UjSpX8R-B3 diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/overview.png b/samples/e2e/EventHubsCaptureEventGridDemo/media/overview.png deleted file mode 100644 index 3bf88ddabd98d019d3fb7f9b45de6f123eadf391..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15389 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

XVT~W?Wdx;-q5sHKv6+uzroa} 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 diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/pick-target.png b/samples/e2e/EventHubsCaptureEventGridDemo/media/pick-target.png deleted file mode 100644 index 058aff7f80e018fbdb87087217bf510d32048083..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7427 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 z 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

6v$vzLeA-BZZt+dZGM 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 diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/select-function-app.png b/samples/e2e/EventHubsCaptureEventGridDemo/media/select-function-app.png deleted file mode 100644 index 0116e466d404b9bd91bc95ae592d1a76bf2d4e59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11381 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 OU~Fh^P;lw)Z~p-b(<-k3 diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/select-function.png b/samples/e2e/EventHubsCaptureEventGridDemo/media/select-function.png deleted file mode 100644 index 7eaa5a3ae5c761b996c6eed165730ca38d4a9885..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8279 zcmb_?cT`i~wk`@%rKpKW7wJ{$NH0q7y#=I$^xlIgf%Dr>uZiHA26QGYA~zHRbW}YCe)(S>M9hB%Ug!K6rQ(-G4qe z`aDYP@bH-SRG-Nk1X}KAxedA5r!Sqmt5|Im#yBTw6~{6`g~2;wvJ+oa$(S;RI(-vq z_MneN{F28Vl%Bpz(Tx|pcU#Bx*`t|(+nf*hl*x|2uYS{A^bgVUKxXbHc$Ckq3RFXr#&hiWr;weG$^~lsk7fL$mlqF@;vp= zfm@kIN6I-Dy2N4Cg~({iMe46b_YjJk&yL2P>Pq=)0VuQnX7cD?#awoH9U+(`Q32Ns zZK$wA>;<2g@Ga&&(sJD^$pG*<1NK@v0KESmcC`-nAIDJ2Uae?@yuB((tc^_~kWLs$ z>;_0%)>k>H?|9DrIy6a`GHkbee(y|z9;qy!G*4lCbyVmfdpXY@)V*2tsK4gjQ+g3U z->3X-o}<6^hq}Mtlh2uaDO*$OwI*pL>3=O5RN0?DZQ;FFOZL)%oku4ViV`ulTx4BY zj*whJU7tV;OyS7b9{OpBM|69m1^i1^6slZ1zkgH_1+o3@;&FavmFYzYYq*+u%k&VR zpenPU6afF7!BgF)O4`vbOjGB8Xx5y{mf%lcuPAf1@{*{Qy5Bsnop=D;yyk2-8aj~!Bho!;$6)Q}9#5l; zM}tH3m#S|f4%;ysWc+BAq{zbszg^|WZPlvow;V?}(vphP3ba|htJRn526<}e3p;jH za&HJ{l9R3>5}8;7J+Ye%gU)ERxnR3WQ9D@H{M)nFvXcp;D9~ zr9m+IRj_cgIJrQ96NbYY*%Y@i_fJeZ_z>kwbJ2B!&iEtkh4K_^^4WKsoQja07L&&P zd-qi@XF0Xx?hUi87U2I1CZ4xawsV(`U!sT*^fM4>iph=H@gw&8We!c>%eGAg>C}VI z+^}eJcv#2!H1r~B9cWd#bgzfHv+7lkCZPj+YcY4#;gSd161)L@c@)nEJY4iRfL*KB z@;p0&bd*diJ=QkEeMOv^*`El3W3MRvw;SPWdo3EeZ7bj0_OaC;Jyv$nenOEkf2-iX z6!Zr!Mg^uJBdN%dcgQ@SKidE&qXY*edc+y%0p=jL_W7xIWMwzlaBdD5ojSjdsPpT1 ze&m|vp(|y+`A>%CY#`V^N^sBU3#yMY*985N2a5r}h;nQY)(PMCcF?gdT>1V%ds2cCy+K6)l!&Cn~JA;Pw{uVwTY7dLdQZ!fN zb6{~A7e|0m&9Fgc{zEFoSSB=s-7@hr$ zrV|zX9U@^42;Z-twhY_`W`-i8M=|J>Bn9|sQVwQ$`Gl3`vt0j511+L|i=*|#|GDge zp9?{Xfc-PCpBfc54hg!qlXX{hH4_NbYRd(IC5zF7VVE(%O%E31J3+%|fXb;Lj{0&L zz}A+C!#8_+T^GU>5jQR;BTMS-=3EUSP``V_X84t$*^Xt^rC2MgHibt`rIJ@ppp20g ziF`gfrfb@Egz5$?uD!WZ=_i{*Rgz3S>q3%l)LKMQ^_>u-RROyEwh@E2j>jIXS({B} zgnh^6FAR2d9X;0CS^KV=CgfEEO59=$O;ZQr?=PoRH`i(fjAo0P%M>rUmg`#NILDs% zRH9=N#KZ@T9G!jU%(k1@Nt|576JlX9oKV}05Ykp5Ac}cs1NB++$8Pj;+IBsMYE(uV zZTnFR9?tVm-z~H4=Pe&a4X3s>%iTpy|2TFr3@taEo&VG}ViW7)E#9csx$&l!tEkSy z*_>;nH~tey3{LHqQJGKsnP5H0x6sp6)Q z_QVOQX`!BthBd$YE*9E87@Eq;xZ3kvSID+T_)W_c=OU+kpRDq;UppxE2;>E`FcUE} zqsfGZuaij^^hz=?$o0%kVw6Lv;F5kuqtO zfy7yN{&^eyOA-EEljY5AV$^2I$fIH(YyiO0@60ntp8Y9ZSM?*RqS2d>=<1lg*T@k5 zjv-m{chK>|pu@xPK_~2m_WSX{*Ai4C-Zq^FjEpHw|f=ain zM%ed8Rin^)on=<#BVLIQtnFzQ%=)$g091TIg-9Gp0ofA$DKH(m(OTP10GZSz<&JsH z{qUECgpVqx=m+j?88uOdQ4PTax%4L@4TWfLgXm{&TY+ixTJ+qDGrjA~3_)k9d$eS! zA_A460%MtqA6TV%G$6MCRzMdc3(`0qE%N9R6=bgigNwu6t^Q{W{2I}!oN>b5aZ;Z+ zw>t&$4Xx}elIQeRuV*R(ExaW8oa~`)Ped|Agt#)ucr_waIY;=b@D$s)w{v@&3f0mh z^=8>h+)@Zy#XpPJeG8<1U>I&$UoiVJ?Nl(=pF;n|4Mf=eJenP#YgGU$!7hz=POr^D z$ul~Z1ri_!V8R_c8vvBn7reQF#88#L;G%yF=!gYmsR6q}Rit6-$`0FV3J<)>4#$hO8hQ?#>M;YzhHlNEMrE#-VI3`p9v#7#R+7KR4jXXr z>%p$h)vu3OYA_T0(Actl6~=^}GN*)l8tYdB%fr~m7w=IjyEB%bkHv7fUu@Th7#(fd zNx%J~I)Xz~-NcgR=;DL(E^4N$l>|qbixy<~wfg+mkJrnI%Gn|3phl@HEI7D?i?Q|| zM2s?TGT$AeGFP~w_cUPcBWUBMZP1*RM#)|>QdZh`?c+i4O#~%F@X^dFb`6aWAK<&1 z!N9$?zU?|3hV2FM%A&uI?j$qw7}G~&aNMmm&zWr#=F!chFtbadoU`UfjLK|Exz0ht zP~gVWzC+4=%=>8!7-K$=1zY-x!U{J2S`EN3U|NFKnxWNKjqYvXPR(GGHwQ4a9YWsZ z@dYg!B}}JB>}w&d0mj)2)fL~|A&BHyBXtQiUc{%Ka!T?qe$r3OMC?CBCy&c>m8fo# z>^xW5vu$<^JDh`8wK(!4c4^$kOr5KjJWoq0+pEwxNQ-U^C$Vfl@t_Y`&Qy$UCbfj8 zihWYIM;yoGE0PZS{Z9>6IJjScKCk5VhySbwD zaT40GQ~B&dz?|mW8DnZReSX2QBF}5yyO=ZaxFXsh_)Im@_&LSQ^Iw}2=DfwPzF)6W zVi$}LgH940tGtdcE_2RDm#)Bk-G^m&lvnB{tV1)(sf5_@fHQ=*40cR3<+{0tt8Y7% zTpyUGuCT(m?{VjnR3>{3(ZO=~oF3_yAzQ9p%x?ye37N`yE$dH_h_Cm}nt<1oQ%^wa zTM?)xJUGU_cWmkNR>eKfIFit!x7t2_<+LpQ$p#wjNg7AIMLPQUbVZ6{`7cgXT8fRx zWX6Wd0E%QrN&JrjR|izQeHH zyc~E%UOJdei*fUAg}A2 zL9Sn3e{^A|kl8ky1?pJH@^iPg7R1^*0;!e3=ol7l%kQjWHxFuCpa=JLLoX{7kMgy% zuS(mwmg74JJIAX1?jjmT<9NX6&ByfD{ghBUVi#M6fFmmZg#UzMG5;Nz{d*=ze;zw3 z;1s1`!hG*PHZZCUW*n|dk4G}^5wsQs67O2C0%5Y`MrXcvF2>y6YU?~j^&}BZP6>;g z)D=qwSLrcf1+R5oCnG|`wc~f?kJ#&kg>nY#!cLbJZhq-jV1sdLpIRiRzpf3GJ&g|# za6dPKbW?;8w|=YQI=CDbWmwoa9iYep$+neok3<-ih(Qvaur8xrnNs?9R!~t)Z+aO6S)Hm( zB<0TA$w>(zKyol&zJdVkf@)qzai{ZU8{^m(y1pg`=a^gm&26YEAKjmAdxh8EPf29W zL}G_x_?!jSnMksy8w=bFEw4;``B~1#nT3$fSeQ;^mG-o8ZYgIzEBPO8X;FDHr7lT`np#K zNN(nANZhegO35|)uJeP(&b8XDC?+YxDcOTRD)?D-Zj@F<1xZQqfR1|UP5=o>m`Pb%Crbtto49Z2_KuB&B-dnslHWiP|2ki ztH@^reok7vC4mN!F}Z9IAt`n&F2xQ@@QsSZf0b7L^l(Zp1AESXNi0jSRmuX`rD-ky z7^=EVGO%EKK)S--%TSSpTw#`46O3AW6fygfM$Jg&V!uS`Y^tT#h+f=ip;GzqjUhMg zXZc*GCmVJ(y9#D9Cw8X)psAnI{9spR5M^vrWb75BTz2EwZl`25ScjY@%Ff)DvLb@{zX?Lb&Z(wGuSAuOsuPAhYyp&X z{r^j2HHzzc4I6fLO=P)T-yi)W_S|ir6@d!B{E7XY2eZUPn8Q8$LBl%Y3u#NevAS0^ z#gw26m<;xpRoiJ#oifvTmo`*am&w9w)$KB4d|$3{wvFcP($xYg^!UfLNPj>FmPLcr zYV&J&`^uD=(v2T34ws%zPKnrU+tgjTfJGF+pvk_nUB>83bWKGhZte#Nxc368DO{|d zP-YBQqVF!8SMP`md*mgg4XI6aay)s&PgH44txRv}8dYA^yu4`# zrV~>-Dqlpcd(2;{B)QIzAR6;G4!Gl_mv6J5^LJ?8*P|DA@~KH@1YoJ*Pk%e=bp)gE zabib)_<0@Hdy$&|%F!4ag1u7KjLoxNsLbIlezpmfi~jBWa6{inkEzk-#lW}i0(i@I z!H&rV1)g1|LB~#EgGA(-el}OeNQtqyQ0eya2hzZG6V|7~HBoXoQPa!JDBb1pS+!dk zyTP$#CR@YDJ8UE&8bpR=ui7?i=jfd>ajW)1xQ$ZfOzR)lKbAssV1M_rKP?b-Y%J?8 z?maJ|(MpjCfZ6fj8xYE{Nu&Z=p~;Vaal+!POPVNG3=_W46F?l<8-rPT)bx7uO2^}o zErbl9_Xb7$r451yz46LtT@o89*_PEMX9|NXo}&XpcHLK^2TjOM@AGf8fpnTbi9^+! z&&xufYgDr%Lukd#TuVGB^0GT|3?DMHgZ)!nN2+*mbIl!}JF(R-Rywe2pDPIu61n-y zBZgajqGus7dk`fr+F+IVqetX}KYCu?wD%*9BBHeh(@p1zPoM}T*nEyLZ=xSxY);R& z9==FoQrKkA*N&fFA$qyP+eeXRGD#pQrhjxXWkF*2xWwK0Ex|-9^F6kKp*60hca)lP zg%qIaT$?GK%Mb7{rZ3!IoI{uS1NYPgw_O?f3Id^Udkn25JarBJI?uTXnvN-3@HWrSX@>!26)QdW6)JSTbWe1X-O>7y5X>$75qttjc+ukdk8=F2|RXJ zpWXzeEbHf&B*m7~`fJzcx{*6|WLnwtpoke0pr5A@v_i zG(w~<ocSqpA!CVOH+_Q03Q3pP%84yMxy{EIu=)D`GGSk|H|;9K`5qC#1<-QaW7u& zze^XcR7|^xGd~B;xYDXe{~KK64|5RmLyW?&^Mpp4Nfs}N8pRZuhq@<#eXd;KaZMr| zpWLwCfed;Co-Pj#j}hbe<6e|3Mlb1hF-MZo)dptt+hHTfS4_alY^254N?$0+3ju4o zFmpqgfN zX=IUmdH5d_$2rkuoyPW@?Cftk2y)qJZ&4WRim26)&5*Ya764^W+RPV^LqftYe_XCh zz%;vz3=l^e+$=U{mMN@Zs523{@A(k>{a-S}0I_M#)*XC1U-C$h-FFBb7kFPR$Mx8J zd>)bFYmwBkKw41o-KCN6^>+4m&JizZf+^{}`_Me`#*??#pipK6@PS=Q{S$q!jf+L8 zw)Z~s^UWLxLe8pi<8bD{UCn$j^U%`&|KH>p7yrHMn=B}@hj-VEg#_Jyr?Mu<*_V|Dt zER&uQMWZ!Fm>4=p$l2j=ERrwu7kTa919ATv0LJRhkJ57BAl?I9TxElQtv6nG?NcxK zcH%}~q^>E1i#^J0&;WU1D|47xD39lTj_kp~&}L-MsvXpBE4!2jd_K+SF(i6h1VM<1 zrmX#*MC!txNugnO9u_KeA( zsb`9YipdYRHoYF6|B9J0kqeOK`PtgDd?-W!o`B|@6w%3|U+UhopGYdmF(i|*Nh6l# zi7QP6?yqr@wkVY(;z12rtUwQ4g%nBGT9UX=BEI_K^6Nq|QZH!yG51~LW0BT}@^67C z@)-d|ep^z5H|t?;Y!*~Sodv+?1S>IRMhW*~po!!ym6)D^iPpe;@gOocXsK}#dpXMb zr3UDz5Ie4eL^7FOw$=k1lkJoMsbf9K0_qV16Y0h_MAolye@;hw?(t{rb{_;^bPi-; z@T#Zhi8nQe4tZ;fbyA**s-TuyfUd`hH7V{^p)TwzD;VU7DGolAcBL`_JQA&6KRZIm zxrB2#M|~Ck{}I!_L|jzvsFgx0e5&wrMC$MpuBc;-Z3HzniOmK45RY57U#(Te(*)&O z6Q|$`als4>-~Zg|x4DsG^6BIJAgW@EGH*-OJ!oxGNyr&-mT8~qeq5V5&hDW@FM=^q z%qzZ{7*bgKDMvR@0G#Fv4Qyo3rwd9Fvz@p{UBLXGgM0hV;wE5#WVlK?D=uW<3* zwG}x7n7XKCo1n*sCN8_`u21e>d|kDXsM{4B>vlG59xmtHBUo5O)KF=I8ZC^20V!J_2_lbFw_&c4Me4|OtcwA z{kf&td{-&%M@#AnH{5zne%0SBVt-!Ei>vhuQuqTh$^JW}dnlZm+T*;v-5irg%v1Fk zC|cVx5^pnMAXU|*JgKiL2ywAb1LzymH~E}oJ^Os3HiV&rEAuuYJIT#oD&!Y=t~Vi1 z3(|~jFm_ZKdOY0)Gk6Hc*FPKDXh`#FOCfJ~KO(I&$#KGX(BBE;|4&i=!^SB6|1}%4 zhlFpmV6RWR9HDEp;;5b_Fcny1d9|K?FtRA+n3Xa*PR!9s5ivBKZF&ZlpBOH z4;nts$a`Cj?92+>rVH9i0rF7zm>mQ^z)>HfaZard>jb&Vh^gXlJ2#hIVi=#0sZA+I zT|z%*o2V=9zb5_aP!o)>W*l_EJP~>=Nz4OA42eI;o={!(>Oy@l`@9i(m>98kv9|Nc7gl3$#4?>y;=hem_QW5+gaO&hcq+^cH zVn+yk4zNen@gC}h@Ka~hwMZufsb~ti5|kTbNV^?2T`#X0 zUZV zDhB2GgcXCy7|GS^aDmPWC%$zWY6lp1KU0i&>C0v?=ivV)FCi`^bxBPvfV%oahHg6D z2=CORpY>z@S@xGvx`uZInGuH?u7%eN@KR!^&U0FlJrXIqDUary-kqrtdPLDS#+*1u&VFu);K~ zr^y}f*J<%-W48BLMk*-DaG5y0Eyg{AHx#e*>8@WH55zt@G0J{=!Aw!Ck3g`MTkDDI zw;C0R(W)uYI+N%zx^Z66gHCf#`cJk9$l(B!!gyX~9FT}SBG&hAq14WWS^g{cTtTMK z+!Skuc%q3jZk6J<-_x*7Ikgi$sFZ#8)w@FPDEpcU0!s?+sz~2ZARVj`L`YsLa?Z;? zy$@?GYyy81?yn}`(GS(FsL;0ilVQ8o)Q3oGHVqY=IP)5W6Zp@l{<*f#0UZ5QIk%r3 caxLo#a#ugcSGUEz41lNlT5JY-!(wh*fk=}dnB}$c!(jgG(f)weUfCvbo_t25v zLQ`5GO#IEss$x@803BRON1yJR|`C;I@MNOAP?HssjL5 z$w8Jo%TP!D_xGC z%>dwWp~6c^O)rC;S%oNlw0@T}XNBc;Ny)g^GIo!(_ap4y%ET#}BoaY$Kl+TJ-AZ&B z9x1Uu3nWxm$YXeamF2Mw*eJ3}F{%Vmd82YI?5V2O@a&|S3#hih1MLvPjku)3P;bsc ze;ZsN=|!j3GB+}@p@)b592&_6M1TZadZ0MIpw}P;K2dG|Ni@Zw+!8013|jUCc5gu*-KE3T-4_{Jdo3X>04dD?rm%YX<{>kC41iDw*GY za#bmlG_)M%GvOO3@Yn=_x|fD+EUL`$Eg1PneF(g{npmk!!V!$`34BTbEFeDf7~k$! zFE&zF<~nvf(h6QOb3)Dqa9^ zQ;7={+$^3A`l-!H^Mmg3)#!J@l^x3PCVf;BUOg$C6+cCFr2owP|AWi)U&XdY!Cqe* z6YX|s!=~s)DtAcPVvlRE?TtAc53x@%biqNABh2xjIzBGGp1n#|)qC#{>$JK#;6_o42rftvhD5`Uj@Q zAqiS}yRF&ua{g7d_kR`aRB2o6A#iPHL5kRiO+pn1{N*NTSJ0WKzTf)^3wf)%E1so5 zziu|lL#TsoCXkKWxS|6>%9WPb6WTCP<3=j*%e!NOtU&F+0stiG!w=sPiRWF;M7X&MZwn$}=h zRaEzYCUUNpR*aGNB06N5WYH$|-QoS^EJE)6k5M(2MfRXssq&PsCCbCPh7J=?QhHt` zD}A8a3ezS#tH=->kGMnJxWZlo-M!Jx%@+Y#X5`6p`No5wPGq*?cvL)ClgBkQIJp{? z&!OqPT9;Zpp8x5ypa?7E8E>jo1Q+zqhL=^vR}$6S!W9^@v9ut>ckYptQ2d9w^dv&iwNEn51ijW~TV!AWK`!huM!=<$YAM!6ts5 zH4#53)n-!Baxwgd@fxhr4_SQ=eWpfM7I^qGIPS>|V0-|0_&p3!$ee+;W`1Cwk8GEEhTQ%qv9v( zXfdCX4tsNd$J$FYcH?J^x&Lfe#l`Yn-Kol8$XeyCl7iG{W9WN@(Cy@c4Q(bDi|I-| zwWq?b3&X7AL_2=?t)8)WD5u)nJYeXOE$sK$%6zQVpXubJS>$e3YvyF<+S#gEr#kyC z(ZM0{vdPkc@IohzFV1hxAal&z(LoIoH~;>u^@~r^))go1P8CU{vtVPR3Fo2s?Zu*Y z)uhlasfPlVzJ1%*>$#?)hsiQVs#bi`&_5U8#Whe*w2JwI{#ELRE$1on6BV&r$HS~m zS-;mRd2Vj9e-f=6LLT+U&5?%?O+f}|$M6#p6V02?bzO&=^_nH0U1#ntwe;j9&&PR* zG^m75i%S*vS@Wk4YW&aDn(@1L8Semay_q`p*qlv=LTM~JVD!Y^jwG!y*!u82i12Ns zBN=26ro!j`5Dy4W`}W(-3;@9PafA4y%ek~cEGTc49u0{;PYl|*={tEj)JtuU% zJwS!MB)R$!9D8LY`EEFfkVk`#pof!wcmuK*i(4KM@!Fdll%pm-FV7dc<^ztl^{fb-Lgm|z4zkA4c?&@Z8qtd>VgwSWw2MP=ieT67&Rj0) zND;iPlp(1}zFXbTLeytJe^GmcfUQsoXTPlRs%rjS)iU^GZ+~fG z{sh+^cAV+A|fk62&=xiOaHX zI7Nz|f8nGR_p7oajcHMux)JT7icBmE$mY_v{ppI$OWq`p`Of}aMqd@@#N*V1reK85 zj?}#gh~1AWJVp-$@Fir5!*;4Cq!cKHiKG>0>&~X3^cUZw8>D@DmD{p4#N;KFZNGv1 z_SW|en>>Dv)duYS+8808Z$3LmAx|*Kij_a#p{sU4dxFLsX;hhKsPILqZFi*pJ!_I8M4ap&U5i$s2yQO~YOgXcl?ycg~a zJLmsxCL7#Zo7LOd2E=!L0t>`m0U)9vB<_h`^ngY`?sehqPNkkII5P~fxw?p zGp%Sevvy46=}uq3H1DNKdiBP#?YTfXr)QEeROS8IX|Lofx{h`qx*Xlm)Uoi3Tga62 zf+e9Yw&=0hp8DaY79*y8HbtWPsZpM#m!-TD=r-f*kkxzbt}t;4WpmB7cV8Y}+y+x$e&dV6&drg}64HxK^TpBT8$Xa#o_hO{}@$m z8SI$bP$;0w|EgMM(_#M-HkN)CdAW)Z75AH8YM=K%U$>v%>F(~H_x~L&D9&laCyC^G z?VMaCoMYtqz3N?rLj|1AjM*V4d+b7Qf}a+iKgKO5InBD7S|0U^qUQi^0^gp=c%&uk z@l{6?+G0zyFpx5kPApV2&`XwBa!T?bgIRkD=WQ~y$tE3V@?&V|LwKw2F(zbbcoLkF z`(6>vgsM20LvcnxMbS0{8gqy41%F!+FBg}CkTT?Ne*TuFpuuqw@3kR**e==@dA8s% z+2ThSus`j2zWAw$k@`Y^I9x?~r7e2w*sZ{uF@tR^axqImb2Shy?oM9flBtJ^GlzUW zc~{|@Rtl{LYIR*_vyg&Smm-t}o4q{Pmlax7oI+~F?AY|zFry-s%F8m_Hfv=!PJvgc zJr%;u zk!o}0mu2@>_s%Bfc<$A$U%pS9y%@t$sk%CWm#n(DwQE=aV8Q*xzFaENti{)|G#<}zolYQd?DPP!=JY?F#oS)3$ zy*>Tx*+tm#w*eF!4xg#_9pE`_?;~4Uhrj>)qakr?JK-i@`}H>R=(ND}{XdIv0QyBY z=evYEzI;MsC*~{ck{O;OK-4!c&bP%naUVQsAT}x#3GzGIMz`1Q!r^WKCcZhN^XnP( z8Q^sU?1dBIUud`$g&{g+RBSzC_;*N52n5E7|Ei2n58eO5qzB;ZpQZo8u>T*vmLvrJ z4WgNtIcl6TRPk85^$UF6$o0QN`hDGD~{p52QKB-4sS&7|q zliQy0HZ8(ng0BKb z1W{>$e7797X+od4dhsSEe+5gLjDtD&7>KSI#Yd$C9&vnC2!Tv~0@+O{kX&tLqT(dl ziC!4`?ZkjKnnWYLyK5V;GRKM5>wf;?0YMG03HPM14BQ7)x-CYyo5JBu%Mpua@nA^l4pZ||hRg4cq8kv_g77qIJ9?;hna27g~vkKy=2 z@znLKE4S)WY%M;2!!gYSfzoj}qjJ!{8S+DAg~Bn1?U^)(aK80WmcAv_O6LxsOJV88 zNqN99PggJ3|J-n7S*{kw(2(acJwICK)!4F&IkGz)8e_Bm#9W|Q8$0&mAkSTB`Cv~G z0JbcfKs4u`ZEXVOE-EAisTY+7*WJ&s*1MSCbKwSuv(e*Xmm)XvAe62EQJD6hmY(Dr z)qO!pQU=IYDc;<7^a`aKK4o>OgK4`fnQq~Zuxk7I>-_=Pi(JaYkuPcD1`|eMRd3r8 z0bsoEGuUb}?!6&FD3l}hfjKc&G^_d8B_r13Cq?4on)!L{d-uy+YN=*ijciRs2cbtD zR+3VfHUDI=!k4*kC6(<8P@Gy0ae9*Yju?0q1meMG$FCy(R{U$^#ovdf|2h@&FKT-& zN`%kCYjby+mjiwojV zN^5;zo=DEil@qbFv(q4#=7q*tSevLnIyrck(oJ9R1f`-i3IH70#Mk!)o@AaHrvXBmykV)w7vpRjMafzT&+~? z{`%kLBE7~NoWgcP5*RdH236g=&z*aN8eL~r^lTdG;M&Cvc|J;)5@SydESS7zBvNqz zJz6&9u#`{tu}lhFsh@3Y0{zO7;RjknYE4MAH-YdrlN~xxIWKqnRlQ0(7;GWcynC5i zzU_G+DIp+=pT)@hXf2?%LzaXom;t~$xNBw%0Lx2~e3-=3t5@)O#Q&Kv6Y?j)5di>o zjPE}|tNlZJN%z}QsuZ)`9em%CjIuGc*Wv=x|735BC!nU|_}VYT;JPflwdj6(oxd=f zfp<<3u^H{J8WrxuZvQNsX>tEg*Vrp_`mL%{zAb3B#OSz{hHls1(SDZ}TO*UQUjY;9 zJ$&e3gO1?kZxf#MQ$5-Ztx%_ZZTYLb`+(Vl*R-$F`+-;Y_(C_=K3}^}u907a9h^qr zv!l;=d_MG;${((yDw*!hl@)V*B-IUlUT%?VRLtMulti@ly?(1D$b6;3abHfS><4Zv z%Tty<{e#`O4Rgh4{PPWNK3f+uN2cY5aSkH>1OGAoLn{3rJzxR0#0Sd7MNpxH-?NIv zmGzEWjPpNNLnY=;wZht{{Ox2b^uA>L&`|r9J1|+??N4%66(8%aEa}SWg{Me#+-iq# zwi+wki3 z?&Q%5+v!1>v)6l*vlX*d+I)0-S1!xWo@}30TNr|3Ps-rv;jGve`6}X?vx_|`JQrC- zX1#dhD5}NF>fD}gSw=IbY%mp!$FE%kzmABA3k9a(^iBq+Dg-vs2RpN?J;_~pw9^|- zX^U7CG2XU7EfTQ`eZS#a|Evl>rcJO_u%9h%LzPMUp0#<5RvS~8oFM;~eqHEMGl!Ub zUswSLKLY-kNQL+`JTc6p`0`aft>3!o6IHI0HcWs3#mt?9Jr^pI>D$Y3bwB1re!obX zYHCQ1V}n}XAE42uU_p8Gd+BEf!HW7wmNYmG>o*!x*S?dd^*a>#cw2``Wb)rZIM1aC z%Uo>pwnui`rpE<3>>mk6Io^fF3{hrY@s94`CT%=Td*{%hSCmSI7QaZ8*X$wp5MDlb zjPE@Qc)gCr&6?4aok_dpo?Ap?8|!4+;sJtg3qJtv`EeO@tt5Uj^~r+A-d19d0`6A- z6p4i4A|Krh5HQ!f<(RB~OV6%M&xWd!X**^|ymsYj()ze)^=CW8=85K;c~5@t8k);{ zwL3HVnOjT-`ym66)b61UwKdQwpkCPG-bBj0QvV=iu`v&3yXzjm(%&1t?YP^& z#cwR=u`2BMVI{2jfu?&^ApBh1VS^r~edJczge z5{|voCQ1A*|dKkoJ5mW2W4d^7jmj$MTv z$t==|G8-)3J@#~;=;3x;{|mPU2Lw;Mi?(W8P;-g`U&|Yb-x`BS#7jywXqWdW8!utz z@l-#E$9$ny{ps?LyOwha>C*h;u+J6&6n@-ta~7?3jIp;=k58tU^tOWt&B70T4rTLtJQxe1 z_8ugP#;tm64;<&;oto1&%&VAV?@!;+iSe*FzbIy%;AXCg#qyg@gXRP~p1N#rSN00% zPs{axg^%qL+1nAR_=NBoIznC)Io_0k_SZe$GwF;Nx!uJ&{?-q&T2WsgzH6#iL%XS_ zI`e6V@1dBIw!0O27JY~2WFv(Naaqx{9tKI0F}I|0k#C$B9gtYBUw?6yuJhMWHWj{o zJa6C4-EWu~;8`K74}^%1wJ>?ande|;paw#whsnSxuCU-C4WkZQPhUl3w-VDF-uJB& zDv3>}8~+9oYV$9}FClf6irTBqYA1eXt`@r?I{T&*$4S9;&oxK|qHk71rlAps;Wiph ztYSos@@@D)8Qw`WS-7MVdF0H&A9xKcKu+e)9jrR3{14&9|LahvHNUZu43|8!lY>Qt zu(++g(hw(Bg+Cv;#Ff_?_=Y(48Oq1kxEpp zg+BzG!zZ!&ZT(RTsXX!9MVs@nqB~R+ys{(>guT-<`*U*(NfYL^s6~Aj8M}%#8Ii+E z17iaQBX@In@0sYpT1w!~GR0FO`)j31#_^b-KO$m>+y+E{M6}?O^Bz2qZj(z{EUlwplmS~M^zg?2X^8y7uz)O7w(EH0*A_PQZnH8ScVhq&jd>VYD13P;;Eky zVZ)6*pOJGnN08 zFI7A;*}Riff;^QgR6){{1=GFVKDXSF$(?QQ?O24K9cN7K)#;m<&r_lMN+| ze4(R$@O<)7iLn)zrR8ss8#d)U((8mu9ZJo5=)gF_m>9;|PFcHks#v~*KCu)Zy|SE zwd)Qsu=N%s;(B!LEj2fwdoy=|YVivP(7MdGU_c7I4UhY0Pfh>BTp=V#7b;+UbQ7$5 zAvLv08j)uhG3_lEg%fjTwhh3($BsS4ysY8rq|!<0;`lHhd$pKKgOrSGH+Yu7lhe!3 zX|U;uEDSOEhi-+S?=CV%m%k=MY$UG|=u+o0ggw+bHX zTnnNk97nl1Jp4hE1c%EAGM9EEfGFtRy;^}uRu0}TsWU61A&k~xOSwpELz=@IRDYFR3 zc;lB#QQ^})^Lca`WF_G)DEmSTc#wSl^B#XsZb$hwb^)EP)fSe}ci!&9Ynpj#GUPmvN_%u==V>`t5*&n)cp6+sCdMY zf#4Xrq&0c(md@EBduR|Ls>EVn)l4h78ai=5AQhHF+7pV z^JKMY|3KuzJh!5_Qo~VL+6ru8^+$g&=okIC1O|{ir;IcxRmI$%b)kua{c^;_9kB~= zo+iqd#rtPTsT>!WKJYVjTT2pEarN1OG_M;)7(4BcaGBIO_KUkdl+{F~S4O=`(#oWz zC~y(~Xxc&U`A2&Ki16Ai989q|j8bkbw@)qydc%k{m*Llocdn)3(j-^cVnM-tr@p<1 zxXuqC!hZUH@qU4}nk07GI@|Sf{@WTX7FI&DyVIj%s&eNF12rR&^xovWu4_NlOOn!? z$5`8A<@1yI)fT2OV`qRgIyKOiR4R8th^s90{C0q?%XQ$JCV1V0j@eH9h;t=7TYx8H ziHXsITi?$f19h983UK7Jpdk zvzRFV!y9(yB3c-u>2z`ccy5*eQhr&nVnd;%B~cxQX~i{Pv?iM-?xYs*RyGhETGG%8 z3uV&*Z@oL4D0*Go$f?Y~$Y@4L&#U-(Cw8J$@s7ag{z$G-Q6-gj)q_;VJNA-(6b+4A zSBGA>c2HJTo@R?!47+fFIxum~mCRLLN^#J2vMB%-9~f{;Nn2+_MB#Doxx-b;*5w1i-kAW?$x)uK$qD5HxOEu%z2 zBFg9^B0?}~lp%(hxm(_I?tAWg%02h~?)jZREPD@o@3q!m>sim|`8;c$-#56!#K6r! zMMcE~(Y=qe)dgco`3zoPufG)1acNOF4J!cp5lA z>!)iOKt;vebMiy|(YMTnib{76a$5uX*luIiJIQ4_eD2Y^fpZwyR~&Q*4nBH6r{PjJ zx!}o@gX8^)8}Yt}i9N(^e#$mW_=?uXEks}srvm~dz;qcXa|fu>K}>k@W)Orsm0B3W zjriXbO_LF;r4g%_kiTy$r-Fil&pX_?bEifuY%>6Pv}%qa<_v|E8XvG z=IOL)NB0J7mGxH0&=V`qJK25<8~*jMRxT%WV`j+V&#dW#nXW2pdV2b*Mr*gU_rTTsB%0+`UH`>9NXHMTs)d*-v+(X?olR&rP2Tcr;SkL8$vLA)tZRd`<4h2e! zR`&)E)qBt{*NNB*`0R?N%E$ya$u?3iZ|{v7!q=Vooy90&lp=Lv(e<5_K7P{5o$KT! zU-D84X)2}o?bs6az9?o#G^@VZE{5vrl6>1~T7B%e6U^F#$IpQ9CgY&C-*GK4?h9=a zuQ%a9cRH+JF?3=-t4h)?6kkkk`?%Ww`O{|!OrFW!{I8iga&@N85XWn7R4rd`jEPlw?GYe1 z_uXh6$>?!Y(GN-ZEEBvb7a zjnXf^_}LXUM-CH1&CsEgC?8q)P?=~`pYPfeTo z`dE|>dH6n=nX!93A3L!7-k15anXf}t5M5JKzmM!Ret3EM_80YO)oG?_!I>_ajEKao zZ81*kavo&@i0#dCbwM7Nhs29d7yYUxlxQD)TGYp4V)q=+lSqR|fo#y{S2M@>n=>lH zH<9HSndJWD7;^aU;%5<8!i6y=V>KB*>Gn+VjK1`U{cnOMH&i;OZtiS#+=^5s?Tv1{ zzne=x73Q4pfLxWAXljYLloX-7Kz9b=wOuCP-oFWn?`Q7oe5d8xE4@)4-<-GJT_J+B zkG&i0QTf&^WtbPtFs?A;5&VC+7lBPDf_XdT`ql`UGzQi<8J+!9LMDe%pLsCpr?j7uQfu-Eefm6n?1>Dk@x>uTyBuvq!|J7g%?^)i1b6JjzFE+oQfj_s<>% z1H@w#sK_3H#aAXBZw&5+r;RN9Nr0eB#H z9n?GE;e>h>{RJ$%E-v(Px~)GM(a@a$`}8wAfiAJ~QS^BF(4=885xI8oQG0h!*zhdS z_d`G23VFqbt1fO=$}bdilru0fkKQ2Y%|qc^vcD?l@T>B*Nf|Pyf}2EqeAf0X6W}kA z6pmd(b&`zr+ z@eRD=15Jq`J$&>0ppF`sF8kN`&|gM2Zg2Y7(hqVU@8yTE!g{5fC3EVL3BjZQDkh(% zL2SAfdyZBuF4T>bM`(KAC`@rki!9t-G&o{lx&eLkDOu9-^!%dvFv|c#z*))E@d=f{ zHIB1jSu-rznZp)989wvFJCLaSM5aXEbXAV^2c&(ax$>z?qnEtW8rvQ$I4fwoey@dJ zhAQ-?UM>j`rZz7`m|W7wD&?;}+P5i|o3ps781K#s4m!7vvvh$!?=$&ispfuguH=ht z07KrVtDn#+TCRhZdntbfFWr7XXF+vo0$u4xURx2BQCL)joe{2iNUCv=VvBE#*rS#9 zRXcn|3i$wo0Y*+v#>o};-k3%< z#w52dt8V3h`0>4Y>CddbP^F`IJmsnPqgcWsC$Dm=?_5>aByIS@l@H&GvMOljqYjJh ziNz`6=b@x?U!9^a4g4BaCyj1=XYKLi6YlqlkB?_`(F7LAK66*aPg?|i1{tx@>LYwg@=tTN1U-JN>oX!;w?mg{qPsu* zT{;Syypyhem`>2iFjwLZZ`RlBJERka;JVD8o#p)TG?=6(<|HiP*q-w+d%e&o>aWxu z$d-u<=lpw>vFBRgU8)658GqY94e$m^kgYiIC>hXySfHB2cG8hyS_o9(c{{pnkh{uB zq5I!j%+O6$V1BXucBcp0kokpny$y4O-=g#{n8TN}j>9P9zTpRy(3bpE5dMcZpM(A3 zHf1q|JYfHO2XkQl?s)4s9=@jqCyT-fBDk{<#EoxD)O6ok-~BG7TvneuoP)Pzd|Tg~ zZ3Eu-#`k3T7bz)dU`QdFYE2`I~Tr{g4rRNW3=P8rwsz1RTLE!F`V>ygQ#^!l zMfRw5y8ZHxJ381hk8RLPD;RU%i!#?*nYatkuvICVBs#PfZTOYb8X2ekz>Ye&5p`|w z^NQ8DLlE%yB?L{t)cDLmqHM&wlLJ_GQxZnRq`V}IHAFO@ip*Z zQBH>no7<7w#GtKj9jxZkogj4keuw(u6U=T8<+D26SD8Z-Ww5 zUeU4{&kyD+hu`$}1M{+{Hx9}aSnI}LE>YhVQ!=>vG_*r)Si(_L?SG9{yN_JVeCiIX&hboRKxeSt3BQw#$-!;mH^6!)M&i7PtLK)Lj;dO2w#w=Pu5+qQYH zsNA;heJr@*ZKzo{%uEv|TuD{&)6@u2-LVx;X@vhaB!^0^_efA=xhZSg@Y%s2x-*g> zk!bM(Z`BQ80+c>W(o8seHgriW9xZ7obn03OEm#w`jR%z-Ct5LD&}9@;XZl!r-^FEisWrWSNmoi#GjHmaR z)>l^Cf|$LZH(m$=;y0AZpJueN)b5ARb!m*d4_BG8FcY0{kG8&jL6`rf*2$;xcsSm& zl|4Al(NGPUalaRc{gDob8xKYMMoW(ZqNG_T>;HH2V;x(nb@ z)R`vfRBI;QQZ6@g#+VJ_Cqb`_)`r-S3Z)=Cx5E&ov*!G0i560x(BU+=ueBshO~>r% z#am))QdMAr2xMAU=p266q^zKOKZ;qm4*Trx1APO>0;OH5A{Nz|F89a>3dyV?XZ22} z&m&N4jx$u&caWwt&gBU@sfHXK5fCgNw?yY=FeO&t&*}^CiLj6Mb5qpKbk;KL7TV* z1Kw2$78rKcoL4)E>UDlRdZn!^R97GItA_ri1)%@nPr{_VZxt8qdN*y-SBK6*X0``7sVADSKDmR}xi9at1#ftDCEdN5OE|%=cf6A??B9%- zyAiyFOSOax^YvV~L`bfy30$Yail!cqs}#*4X?I_jVeSe$LNbiMixn9|lnIF5S3Uy7 zkhct_!qR%!*q1PXdY)V8h$@u(vA!_9sVDV{-*n>;n(Z~wkZwA@GGlY@di3Y*oYMm^ z9osZ61e0X|IFV3LMx_U14&W#gZK^I^N#~McCtVvJM2kseV=y(}TQ~M-cu(%Gy(aCI zzt^2govF&ZULTZgQvB!MQ^K9uwTm49Mcs!Gj$+al*^R#kV?HlsAC`1LaLyD--iw*#quvN^2%1~a_dW* zV{TNeSY|mmoVH*?qb!zo4?g!j<+3xM7fT!}TOANE8R-J}=2p zJ|D!MZejKHW3CU%WhwXygd^!|=qkE&0wR%g!NKdT(UF(X-P$|Ne5I6&W!F>MYNTyOE8LT-`Ith?xkY?yz4C8R2&Vw`Yi~ww>3iN>*5rKo(42rYSzXu!*#*eQH zW^l(I4j=;E`P3u6S{X{+igdphz7D}Q!Xj9SEgy;N;#z-W_C_}2gjf-H|4yLjf( zXM-T-eJ9FK|9@@aUP0yjy$fw-wFFSDj~_p7d_U&=e7q*+Pbxs5MgZD|I^7T502oul zauZ{%NGqK3u22Xf|7D5#L)jk`JdvYtEnjFE0kMaLPsNS?TzDolmui8uzWC%rOw1=0 zIs_SaA_bIF)6u8kD4x*=@1_W_-6qy5eMmy+E<*_+r2nFgr zyr>fHEP>ey^|imZ8`PQ01Tn$nsXs76ih^jwENKQ2f}k%Ss51{I z&(_|~2U;*mr%Z{X)&Y&(x+oac1>1REDgvYhZEp~7CY?pey=HD*IP)k{ zCn3*vPie$nkZI2wg7ur4dGw3z$IookOAuc85B^D=fFSpEpalO}KLGh+7Xiw**GsGN zW^CTv%jCxovBrRwD~o(eqq5mA%#!XL)GBn>U>Z9hC|NbHR2oqkGwW2 zW)T463mz^kuxuV8y5xIh46 zmXN-0t|00ugqP|d6W6L_og;0-BaP5|xRbH`c^kmV8gdGsNEzm!W6PUfnwFk3qu1Q0 zx!ewNYrAE+U?E*gEOgfC%pgOp3)@DZD{DrBhCFd>nz4|@Tt7`q%@cyR&(e9vIdGo) zfwqqE&=faf+^i!(aX=-oZ~REEw4BF$;ANUmx;tLdG6d7dod^}~G5HH63xFpwbj^BB zX-E=0ra1EgM#o%>o0yiF_H);#@p`y}`a;%=8S=<_DF;(TeVGDJe7IM)v?x~k<}>V! z+hiH!Zd833z!}N!7<$VCX2oJWZ?b5)1<0-S55$Iwqj7|{Qd$YJTI%8(d+S-B&|~cb5Bj5cZ3hiv8>l)CtjNEI)KF0*T>D_ADO(=4TDD3`KKCGKN6j|3 zrdyM)K>z{V@LLy;1x=(*({DcQXp!XXMN0!yfLPE?@C><(Vb8I>DfLOv(Kh;NVk_uh z_^t;FEYHQfx`=A#wrysbq**vVceRP{JEy+ZAHhDRpw7(tTS%z7Xn`}X zmH8ySr04X2mgL))P1-jA^v8z%auCNrIzw^<^oyCQ5X3x@6tYXjL!%*^(oDGLWQb@G zsfI^x0jn`={J%o=KaG?z9+}T?CM9L+JG5#ncIP2&!+{A{GD^B#YfbU!?^UG8; z=|`G!UT&KB0UnPhADX=KUvSqT+TaNep_#w{8Dw@RI< zQQ!Sd{{kg@&QS3%Q^x@mjCLv1_nx3bPm)Y_`fDb5<3L-P4M*2hTeyNLadfT+<9 z%;-sg5?PiwJF$db&w_*2oR*;2{R5r za$;qqD7d`<$h-MGgg3v*ww*6oY8Hb$*(9FgZ1cmRXsp9{2Ol;yW(st!4Bv6+b`{C# z0xdIDVLvi%cx#4sQ>6#S{^4|=!$@mD=#b;d>2L+qR|o_h@2Q;Sz6Ig7e{{ru%An`` zY?1b92Ix}T!bg~+*&($fFXhM5t3xWg`pVfrK>RE(?8yhuJ9f3VIH7#{G>n1Y>y@tZ z;((0V^qZM3yug`S2>D?q!{lpQrr|z|i3y~3+_IRIBH{9crP@t<5Oy;W{{g1--enN# zaV5Vc5U2S0I#?E5U!2W6jsYVA3)POMhtvpTCcBJ9n)&q`k6lqz6~Rrj5n8b3FE{L` zhDGdYC)kI|WJ1T)nVNp%zP8ACgD;yEX`Yk8Zf1>D^yAH7^^B`B{&Ky6uhP!U*P1b} zy3yx{(%1-+6j88*yf3u+H?v;Zss@M?Q9NY>zPAxKx>b4#vh6s9JFyOW_n^0bYIx5T z#|_8Jf$3IRr)mP&!z0IIh2zJ|^bUGG-iPf(uxhJ`syL-x5xIbwG%xSD`4pq*;%U=CM#-SvnWclM&1$=0LYm&r`6uAj}+ z+{aXG9$>#q&k~(vYXkiUUAy|Ez$(#3mVV+F!IcWU&TCuU`)_4!SXUyHsb#R{$s<>rd+x0GzpUvn}=><@EN z2WK+GRgBYj7Vx;C5e>Lb>JQes9ga5Qc4lYdf@|jhSeyLtnA*(#Wno4&4P==8<`}#R zfVoyVx(M2I(5%bfmE@y~fF_-9enL9=PSk0Ee{aV9TeI;0@-tKw&56`|5`O^diC$m` zb@1cIj{^h8fcPEv;v`JM`p~SCNk>mdyJ$2r>RCEgw9fkrHkub(b-T`Te@sYdfN z0FmMyN3&ZI`_r(Qu3RJdQVtB)H9%!AuyiC}8)F{%^XGNresTc=)5U8W4DIEwgdMwY zYZLv%rD6)c*K)gE<&c0~FVTpdZ`1|3;<|o#-Dt>m?U(X5Y9;hmCdg&jRV(93wnXe@6r<<#jaCym!gt#VUXn!_=u~H8E!fIe~ENrPk z2ye5*wf}yv`yD*i!Wvd<`^No^`J0)21?^_soC&q6=r`glQn1v6A_S6DT<4J$D7Q#< z80@u*_$4v!0sYb*$knI|ZNohLV7&FwxW92JUmAw9q=JnqzPYHj_IgER%Nd=l7(VxU za5}FWnQ2L)OaWWos zH}dc1$<~9suW;?Zc+~C;h&@2dvhT@xH+{w#yN}87lGtsuh~n@3W1VpNrrNFJWp_(F zhO3Za{_Jc#P!9ucOK)2@yp%^;cy2+s+w+{|P=j;jw+LpKhFO8pO3t7n$5{f~p-QL5harUecq-_L)K_CiD&W zlGn$KdOafbmc7_>1UI0>b2mY%X?HPwfaorEu8(PgF);g4NjJ!SR3zDokMrA{fs*uP z^q5mQqW-#nQ^I8fR|9@X>!~9$+Ydgc1%p%@k;$DBkge~@2k+*?W6hbqIpDT~9D%rF z5E##!wEG8PdU3?)O(kF^GkvT%4C;b1HqZ7GQ9V2IqK>d*i8c(QEgVrA)=iqUeJ03i+0_G!VW9&5Dl<3^! zjral*hdSX$R)8BoZ-ZA})2ufF34#4NN>6h;mYmV7%%cFWyJIrig z8)2n~EuPkhB=xd{zj#Yr<0qTfgl`>PCX=(?X$2Y`X3UYSl-^^h7O*E7K?fmPFIgaW zeXl--YJo}YdC)RH8QvaGYU4kKyHT<*+r4?>dbEsQYw7t}4P`>6xyjiF(n>{ADN*SR zv&Mx1O}+*X`_N$}7PM>mDHW(_={tKY#j;~r`u247_|Pcw0TbF!E@RaM!vSgaU)Mbe&@vn;6L1QB z7`fQ~ci6WNp|I1OZ=5Hjz<|K@#LauNK@@5Hd<>v^%yw)z(}4*9XUfoTZF(K=qxGa~ zaRVxrw`$A^*7lQ)+1OLvb5iA)gomWc5pu{%fzKsh%D!IF&I?@KJIENm`$UapL+sU- zPHcVR^HM;E&2Ubc{Q`f#{TXxAh?>Mu0+5uAA$XgqvM7z%lzx5C#Kc_lQF!~@*ZPgu zbCu4<5G(zJ>6)%-shs%JW2VH$sDj4wmD0P0+=`~j-`8JHvfQt1=!?y6&sWwiChn0c zM%H|rHlx{Y@OCeTVbwVplwkQX*n5cmQ*EO@G>rU*d-CMuBjjNfeA`1gqF#i~Vxu-3 zz_FABTy&RZlevG{$wLcy01<>XC+ckaGrjTd;TooNQK_MJSoMtjYh;s4NZ8WYamg^f zVPnNeE+cGkU_c~3T>zg`QHotStR<7b3E@5Ju5O5R{%WZSYi@MS+#gc^Ui!uLCF{I2 zkEpV{_e-zJ#u+TvQ_wj;>dP?aS9#S3OVH2tkxeC|9p2r8rJY4s>8OXGO&a}~*Pz_7%!!*K zV7WJlhLJf}z7fGYCDdlKZi~=Gg9`PHucxow=*ar&<)_=+koBzwWXskxEXpitTcY;V z;I%LNI6@`?U`XvaUE4H>(>-P(cQHUA{vbtR9;Ql{k@^3Dp#8_Z4xn#IQS_x&?m2Cb zw)pt@fobh5wi_VMtv_DAoE4PmT>|h(KqIb9xr77Ei0(t)Tn-ODQzZfdGMiooDA{S3 z%9+)1nAz+E4waijBImz<|K1ftzu_+D3$4L{24)WvvZyUi?_DHl zvNw7`uxz+{kvFxP2x^Mu_dw?vuM4wam&8JD>FPVt0yy+Luk@U>q(HKn(zt}P(?tg{ zVZFN#@j?oTW(d#*{r)l&VD!V#y}^iR{~oY2yqKzlzXgI)L2rU3f3F9eWT585_O;av ziTPIQot(PMtrJ*1s1~9@eJW2LPU}1egVA%P-ld_+Tb=8CmOOU!II%TUd6Rtg#h6Cg z5NnRytj86SiN=z>dgrZWl*C}`snL??em@8{!y)k-;APReTHROGAkuXmg0q%a?R@)) zrji%%tH`|I;dMAHueHNCL_)CFe26@N6XpK@v0%Ng+PV3)W%t*7Pw=k~JV3l&-LtT; zVBPFfth#-Y!gG~MtxyTwE90$P29_LBHwcpDHAkD2dIgL%a2j`ndjR1$%19;R_-$k6 zA#oD(%}V-+&*3S%udTaC-KwAV)03(u{Oj<0`hbe|d4@Vj{-#O%I8_vDf8i-kUSoaa zH`ElpMe^%xhNWHxN$xR|zd-quF!iJ9(t=Qr0!L_BKojo}<9P=*w*Kdr_kCT%5yiTp zBZ}I%aMoT3dxs@WQo)`f|Ba{h31M%NiqrKFgAWQE4fQ2}OBPSLYjlFZ{@I4i5H!0+ zX<4c$o8qe}t5RV$SA$3b;Zt9+cJ*MH7@%$xtMvfcDBzkanrA?oiNS&(F0=SVJ9Wvk zwIT7cv|@)14Sh7(!BQz8cjx}vN9_x|YbcHnXC$R!8m_4LXD_a>Tyl-wD<2kgPYqTS z?R10g+yrkFYjfMM1_?m0nSJ6kCrLUW&q#mqObR&_bTw75=FVQJAy|(#F4Pn7twfQz z`WVp;cKVSc->t?x--7V|KyC~Hx(D}uTdZ%Yz4q?Y5~6YW6l2Y&vE48d36~+_zxpxpoP6NDxL54DG@6}aKa#b#6TAjxDEIQ!VVs(-;3Mc%{L?)h<0#E|2x#Cz<%lan%MKi zZx}cR7>6q>&-!PgK<*~ir=~n>NNbp#LEo=OofYc4h3aG$^6G&-$*cmoy6{wv=MgTz zn$7}W^EQep&iA}S#r9v!EG)pacrU;}-ApD+AQvY*YdVPam_Aqq(g`Pf;6z&q^l?K8 z@QRrJXDZF>AgIOT63?L%Q)9UFKVjdL-#=sDR+x+i_w2J7!=fH@9RnsV;?AU}M zkwTB%O6?9T5;fvr2HfcaXjJk`4MYR$(c)=3&Nmv9LJE1!&y&~j?)51{^&moU?HQhu zDuxX(f@^%~k}O-+RcSZBmR6_!)V}k?(LvK}IcL#^`@5hg{>lx~?c9A(_knoHfXsV0 z&C@_tAIKqf)a-1u>$5;r>px%OyFS5eaFa)scs>ClG%a~uilsiPUWk|Y;IBi|6%)_0 zVD+Yi#&rii*UvOo_`vU2f$@TYs}QAgGx!ImEH-eYP5TY6gX?c%mTgbv3HeVAFONu} zhm(gOX;DBJe(`U&Nq=zQt>)Qinr9=ld%v)NLCO!G>LFoU1#*9}vG6G}PF|yXErR zEbzorM#Huxe0@2N#3lq0t#!2f&ckUfH>2cXVvrYU!W!U?^O{2+Y_m7E2e<#0^S>y^ zdZ?e~K3YX5Y%91sS^R{g-F1yP_UR~i)*NXXbWT@(xG=*YQPwba0+m0w`xAl)T~E*2 zX8X}NDFV3TE^<1w0bvDJNV+q)2S7Ew6I0CJ{8|kmk*X39>|rAiJD5>VSRp`FAODSn zuzM0!ThN-Br)?6D1pI@VVr^dmpMJ{RG3>Y9HTGX8Fk5?ia}9vfjqk$q&HWwCG19~F z%V9Z~i5&oL6==^b)U*cIVwK>Hl>xoB^Aas0YR9raw{92ECQtRxam2=dU9!!l^w#ce zT>)Ftr8FeB2YH$|t9)GK`6{dRMshEA=B3mxb2!2LP-Sf^jf^)%9>0-$`@?vkiC8le zMO!K1b4ikMo$_OWLmloiGXU?mpnPGh`lduZVNK+isve;HD8yR9ocok!CmP655sgQd zM$J~F{I@-rBO>}uZz&V=rF@(Je$oCVML zsu3PfI!5NJkjNq19ACrAdCB5|Bf&e9!z=rWofb1nm@9F6Pln|t+MUGqt2@rr5|tmu z!w(21-p6`1yutafphM~=lD*<`!uesvA;*0Bo!iT;L`muo;@deo;I7%7nY+sH-he(W z{o(@QQe#Jja5vP8ceB1>4IEc-LOYY;A9TPWU(v&5ddp(v(X0V%bjJNJ1DedNvnq0q zWXG6Xo$u1`k<#j+2Cg!WN$znB_^MFa2SL&%xi<0(I|MbiALA?#50zF*ThGM;W+Dny$QXXU_O1Kc=#EcH; z1La)aof(=QJFIkS{aGmRC|_=NbvrtAmNz-DLUt@qro8VMy(lR?)+nryOF*$8(J--e z==P$)x8tl+yx0~bB`c-`ho5F4>n_iBdz;MCU$(yGy9{@hak%T`kYQ6!aNvV8vf z#CX7L<>i5#Q10umBTUArNu3_0MzfsR%%+Y7tx5{o#jWD9`jJ1IKYtku=;x)=E?{O- zL+{=$|004ZWK0zd(X$|wIq;P=&QiR`)3k$pac|%nw?&?M zi;Y>Y=}sbT@}XDbMb`?Un_&?W0FLNZ<=kB=MLduM%?{hA)#uQ&da@#AA@Fm%^q>8R zrF~v_OVQ^qqvqWs2VZH#l3Un$vr~hsnuc32GFs7tV{0$obieC<+H$SP*yRi@hX~v+ zcbv)c;*KAuX?)=%h(m)^t%Ogu!=rVdRwBEG_RCtLSyaT zP`6txBJbrZ>scxDA)4O<*Cb7sN-gAbe;U>Jw5&DYhifuTT5dC~&saJtNy6#;6fU238q9RbP7AuHxOsnXv!jL{QYa`W%?*dyvebB7p{ z#A+zv4}Q8A5r^Pc8{5g6;qfnZ-&hgc`c^3CckGim1tckcATmXCbe zq5ioof>;cu?UkJ;)yB(YIg;XSakOh$ul{|MVS(RXR+${q(zphbMHU!VoGi~6<0bTx zHAy=jIFG%dLZGKAU=qz{qc_M(9)N*?Gtil7S8f!mxK_zUoDa;-%Wr78M}%p*Rx2%i z9=zo;?Y<1f-!X0D4l~%SF7T%4>8A}6L~jvnLTy9$r6;`@(H~8To&;|tX^8O9OU3b; zC}z?$YlTQMG*l1H8zd3l#vS+>YE#kbxU=%9f5D=%oNj-kxR+dAWRE>we-C6TNV}}q z>LZk9e8XX$id(@sLy>TWykoO$l<@jTY<#f6_+l~qtL#&?!?hR_f^t!IaK5&B`{uRe z`ic9qzbpIQ7bWtG(@pvTbI_(lez1Dx=W&a{l0H*2R(DC-jXb9i!rK+3Ed9B%c~UHv zE3b+!;OJ4;RsW z?=jz}Q7uJfJYx8q!S8ZMPf{YFjX8=#m&MSoRPiBA>1x-3tmJ@}a&JE|4Te?Ec_~2a z2^q1k@QslJbnV|(S_$sRpj<84(`i>@Nu*j<5 zIdQfd8f^)Qo1YVte!iA5UQYF~)B&ft12VtFU-L$y8sM*2dK| z>SQ2o$`q(y1r7t`$pPy8MGO^-vdOyKpsI% zqF28lSQ1$0tlTGKQ)MTA9MNZ--h+vFSAT0Q7^GD~8K+cl7WY== z`+*NKf{D_S;l%08!Mr&=Rcah**U}@2%G#b{W44BrE%=S9wuvap^2Mi5Q$9BOKDIeL z+Qr(C*&cOc8uq^upR5bLZK0N9Cky;6mn$mfNoY$7l-@p2n=w*;>p?eV_qjr*`d0~~ zBtFjB-dow|;PkrMTOS}{)Ouo`{g;8&z7QamDAk-~hg5*0R?WYs@c!$Lfaqnm?GcMX zl{$n7U%bjczx(_5ThlDZ!9Zp(Aj=+X%^5BLR_GBuMBpXB2m^Tqx|dL)YT-t2*xm5F zqJ=?H&As#*q*W1c!d!8m$XT}WH2^A$7i(jb#67?4mmr8o_)`3Jv10=HCa8dK{bhdT z!tYf&S5M!dHru`Ws4Gu#ku^RHoBqRv4}x6*?y`6r`wR`%`&~KpN{e4b2Hcq%vZ7)M zaZS{hJuAumye$2jZ^XHQ#k>bz{0V?LIf@A`Pq}ahtZ!PVjco`xhn8TfJ!OhOPY$ss z9xF+A`UB<}awQ0_3>~AK&e|T5_NzY&0+1eEN@dE$Jrb`YhcMiL-?cRQ5*V_Pzjy)`}Y4s~J``cK^ z19Q8OpKN>=n3fC|qJOP@A8Dk8v@$rK;^gXlVYwj_94+QJ>PycNlYz`g6E*NI5pEye zOPD36KLxZ8PU;Wp>-O(O&y56~ZTpoVHoY+(ayvv+u;&Jm@a)bqPd2JTRwuGfcIY7V zn_OR9pEYavRGZ0sDsQF^6Ur90`x5KBhfg|ur{5e(DN4JRA7&ZfdR`i(8{@;3tG7$c zPIP_j(%qWh?zEKnk=5Ot5;*8p78}(gvy#$qeZoSgxNjPI-+Zg>0qIq?fZ}c8LM>ZO zMD=@4>bO(-$`&rBa`%I$K=eGK$zCggCHYl3I>GZwda6vWx=4>#n7fiHq=4r(S$clY zRt<$pS8TLPiU&n#O$rTLZ)TcYca`G~Qr6duaROg=ZOXexK~w-0KCG;>k#Rm8*oZU< zQ4mv@eKWS2qZq)@Nab4b8IZ&PXG3a-Y%(tTNW3utdhuf4`KBEPHXPoPN44~BF<`k7 zNJpuso1?}V%QD75ueztkisGPj!19}*U6T&Mio;A$@Xf>_vFj^2gh-u|)5)tJ&hOQa z3|hvG_PyjXHmUP6FjBOf(9B<5PD6>_G>#NF^4k9aopPzSH>Yjno#dNkK?gT|U#+L% zo%+P34ZHCarDuD_veQKlmsB3kAC&1NJYT;R8F6vRWvL`B3F@O-kB||(_PPPny zSG_!})N{f0j(Vh2kL>`)EI?ywY<`m?>_27bxm?^`qTeR>P;I#l*l_S+S*6(nQ9mr5 zFI_Gbx$lBgV@wsyKy@#^cE6AM0%IOAGWj9tA71FU zzM(;}k%BD52GSZvdx|qx%-S0|u$Y=J&*QVv3gLd6y5iwPX@Ds3xzy4Xvzbyg{xI} zlFW;P{it!9Kuo9Tnv#fyBy=bQVcp(|kxyQM5=ud35fGG%)d!frP2m=;K9TGb)DDR=A;|0G_xY zRxK}#H!HS1rdCcn@tosMX}lS1yU>*mwHE2b2JkuLl@|m}0Il?nt`+FPbqOND&d)M$ zUs#QOewR)3>8coKMsR)=uum;Z`r>DKU=?cWWBUQRD5=rlmmM0*j!$LSNGLmHtp9CD zcw^6Tsr*DMu-y`@E+(=m4onz-@M@kpOKYA4~;^z*+m(S*}{%QTKaIQ%Nam z1@;U9j(Njks~Yih>I#R3K>)j zk}bU|BC1OL1-dl%Xp(f)6=$*Ep~B1SAXdO*Li-TdqIkMLjdl7;XX>k$5;39v6_sZs zS4A`?@k4hJ)m%*^-cy{?pyX<~PLJ+C3rlYk#xe2&qikxn0NCwUPM?4+INgk%GyeKc z%gPRI;&G^EBq4n1I*_=<2KB~a4tY4Q`|p^};wif4`o;aqyIr*-i{Y(lTIq~yJ=cLQ zaIBtcHj459{=M;i0Vd`oH{JR#EIxl8`Z_ z`?l)RXx4vb0Ta`0k8+*f+pioveh(3toXqNQ7R>EpN>=}?BA*jT)%1fPlT%dGI=Aon zSG*GdmF@h{zUphccl;|}-DVr0Mb$bCl8EO+z)JUE+ul7-H&h$^o)cLGtgr6?PyF{{ z@WV!;{XYlu58DTK8~e3kH-JPs#$dT>fBYKVqz#&-y%5&2{I;I3~(8@`7##_jr1Jg9)m~ zax3KIj$fx%MPJ{g(3y=Gqvcp?`$6ONg5|ye!P_*!f`8KfXQN&6A6<N3FQV7;QDv59h_73yz(;lmRw7Gj1sf-cYjkrV*2Xfiiu8dFGua`W^yu zh<2NoBru3$1=w(GMrTpk?Z|sLe9yoiyOVO$j9bfPpf)F)T9Qu+JmTL?Ec`>?{}-P& zQXK(1W#fLFB(wh8wp9bO(fS+ZNPe|+wh82}&grm5ZkWjgQh~Hyv&i5X1d8MkS#>n( zV~uFwXRHl^2*F_2_-RdDf zA1<=14t|c-6yx1|i6k9|^QcdqiL-=AB4VJ_lxC2y=|{q>O)jr+}|t8uC4^ z_mvt#z3utiv;BIh_dm{sb{O*Rcr8#ZY$PKg599yoF<{zt3CgUxOF@X!_6==SWS-Et zt}w2>g0!w@Ur0+EVqO$&c-&P1#R@3ou}qUifCSn8dsDiTJ@J4sA-=u1nDof*SSkpc z$S;_{fRxpu(8=*5h;r&cZUD!B#N$9&8ak%l*uxvmkExS;d?&4eJ))V+{R1<{4J{y` zonYD|6B2l0EAMz`8}GGuGCaI zuXkuD$Elf%T(qZ2lFMK`X;Az$P>F?ATCczU@7_}vmG!~jUOKQ^{Xa8ZqS%3ZF)gJd dk15n$^^;cu@0c$FUy4Kp(KfhUt?3Z`KL8W;!5RPn diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/media/show-root-key.png b/samples/e2e/EventHubsCaptureEventGridDemo/media/show-root-key.png deleted file mode 100644 index a47c57ae33a742f3008a68f9262bfed91e8f89a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5477 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ℜ|F$oSDm`-$L| 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 Date: Thu, 5 May 2022 23:44:34 -0400 Subject: [PATCH 64/66] Delete samples/e2e/EventHubsCaptureEventGridDemo/scripts directory --- .../scripts/CreateDataWarehouseTable.sql | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/scripts/CreateDataWarehouseTable.sql diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/scripts/CreateDataWarehouseTable.sql b/samples/e2e/EventHubsCaptureEventGridDemo/scripts/CreateDataWarehouseTable.sql deleted file mode 100644 index 163f9eea3..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/scripts/CreateDataWarehouseTable.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE [dbo].[Fact_WindTurbineMetrics] ( - [DeviceId] nvarchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, - [MeasureTime] datetime NULL, - [GeneratedPower] float NULL, - [WindSpeed] float NULL, - [TurbineSpeed] float NULL -) -WITH (CLUSTERED COLUMNSTORE INDEX, DISTRIBUTION = ROUND_ROBIN); \ No newline at end of file From 34706f78f003e660247ec07d7ab34342823fdb99 Mon Sep 17 00:00:00 2001 From: Sreedhar Pelluru Date: Fri, 6 May 2022 15:39:26 -0400 Subject: [PATCH 65/66] Duplicate of Data.cs --- .../FunctionEGDWDumper/EventGridEvent.cs | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs diff --git a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs b/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs deleted file mode 100644 index 8b5d40302..000000000 --- a/samples/e2e/EventHubsCaptureEventGridDemo/FunctionEGDWDumper/EventGridEvent.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace FunctionEGDWDumper -{ - ///

- /// These classes were generated from the EventGrid event schema. - /// comments for understanding how the EventGrid schema was obtained. - /// - public class EventGridEHEvent - { - public string topic { get; set; } - public string subject { get; set; } - public string eventType { get; set; } - public string eventTime { get; set; } - public string id { get; set; } - public Data data { get; set; } - } - - public class Data - { - public string fileUrl { get; set; } - public string fileType { get; set; } - public string partitionId { get; set; } - public int sizeInBytes { get; set; } - public int eventCount { get; set; } - public int firstSequenceNumber { get; set; } - public int lastSequenceNumber { get; set; } - public string firstEnqueueTime { get; set; } - public string lastEnqueueTime { get; set; } - } -} \ No newline at end of file From f30fcd74a81c42027be8bace451feced7bf15033 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 May 2022 20:55:57 +0000 Subject: [PATCH 66/66] Bump gson from 2.8.5 to 2.8.9 in /samples/Java/Basic/SimpleProxy Bumps [gson](https://github.com/google/gson) from 2.8.5 to 2.8.9. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.8.5...gson-parent-2.8.9) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- samples/Java/Basic/SimpleProxy/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Java/Basic/SimpleProxy/pom.xml b/samples/Java/Basic/SimpleProxy/pom.xml index b403f18ed..eb4d6acfa 100644 --- a/samples/Java/Basic/SimpleProxy/pom.xml +++ b/samples/Java/Basic/SimpleProxy/pom.xml @@ -52,7 +52,7 @@ com.google.code.gson gson - 2.8.5 + 2.8.9