updated samples used by tutorials to use the new package

This commit is contained in:
spelluru 2019-10-29 22:32:21 -04:00 коммит произвёл Serkant Karaca
Родитель 4c4d2843d1
Коммит 237ec5dc03
44 изменённых файлов: 1965 добавлений и 0 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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<string> knownCreditCards = new List<string>
{
"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<string> knownLocations = new List<string>
{
"Seattle",
"San Francisco",
"New York",
"Kahului",
"Miami",
};
public IEnumerable<Transaction> 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);
}
}
/// <summary>
/// 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.
/// </summary>
/// <returns></returns>
private IEnumerable<Transaction> 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<Transaction>();
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;
}
}
}

Просмотреть файл

@ -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();
/// <summary>
/// Converts an object to its Json representation.
/// </summary>
public static string ToJson<T>(this T value)
{
string json = JsonConvert.SerializeObject(value, typeof(T), publicSerializationSettings);
return json;
}
/// <remarks>
/// Converts a Json string to an object.
/// </remarks>
public static T FromJson<T>(this string value)
{
T @object = JsonConvert.DeserializeObject<T>(value, publicSerializationSettings);
return @object;
}
private static JsonSerializerSettings CreatePublicSerializationSettings()
{
var settings = new JsonSerializerSettings();
settings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
return settings;
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Messaging.EventHubs" Version="5.0.0-preview.4" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
</ItemGroup>
</Project>

Просмотреть файл

@ -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 = "<EVENT HUBS NAMESPACE CONNECTION STRING>";
private const string EventHubName = "<EVENT HUB NAME>";
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<int> 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<Transaction> 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.");
}
}
}

Просмотреть файл

@ -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; }
}
}

Просмотреть файл

@ -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; }
}
}

Просмотреть файл

@ -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
{
/// <summary>
/// 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.
/// </summary>
internal enum TransactionType
{
Regular,
Suspect,
}
}

Просмотреть файл

@ -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).

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Просмотреть файл

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C9E1D3C8-0C0D-45EB-A3B5-15F95EFC01E3}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>DWDumper</RootNamespace>
<AssemblyName>DWDumper</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Avro, Version=0.9.0.0, Culture=neutral, PublicKeyToken=b1248d7eeb9d0814, processorArchitecture=MSIL">
<HintPath>..\packages\Apache.Avro.1.7.7.2\lib\Avro.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.1.2.10\lib\2.0\log4net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Data.Edm.5.8.2\lib\net40\Microsoft.Data.Edm.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Data.OData.5.8.2\lib\net40\Microsoft.Data.OData.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=8.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\WindowsAzure.Storage.8.3.0\lib\net45\Microsoft.WindowsAzure.Storage.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\System.Spatial.5.8.2\lib\net40\System.Spatial.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WindTurbineMeasure.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Просмотреть файл

@ -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
{
/// <summary>
/// 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
/// </summary>
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<GenericRecord>.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<WindTurbineMeasure>(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);
}
}
}

Просмотреть файл

@ -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")]

Просмотреть файл

@ -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; }
}
}

Просмотреть файл

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Apache.Avro" version="1.7.7.2" targetFramework="net461" />
<package id="log4net" version="1.2.10" targetFramework="net461" />
<package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net461" />
<package id="Microsoft.Data.Edm" version="5.8.2" targetFramework="net461" />
<package id="Microsoft.Data.OData" version="5.8.2" targetFramework="net461" />
<package id="Microsoft.Data.Services.Client" version="5.8.2" targetFramework="net461" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net461" />
<package id="System.ComponentModel.EventBasedAsync" version="4.0.11" targetFramework="net461" />
<package id="System.Dynamic.Runtime" version="4.0.0" targetFramework="net461" />
<package id="System.Linq.Queryable" version="4.0.0" targetFramework="net461" />
<package id="System.Net.Requests" version="4.0.11" targetFramework="net461" />
<package id="System.Spatial" version="5.8.2" targetFramework="net461" />
<package id="WindowsAzure.Storage" version="8.3.0" targetFramework="net461" />
</packages>

Просмотреть файл

@ -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

Просмотреть файл

@ -0,0 +1,29 @@
namespace FunctionEGDWDumper
{
/// <summary>
/// These classes were generated from the EventGrid event schema.
/// <see cref="DWDumperFunction1"/> comments for understanding how the EventGrid schema was obtained.
/// </summary>
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; }
}
}

Просмотреть файл

@ -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");
/// <summary>
/// Use the accompanying .sql script to create this table in the data warehouse
/// </summary>
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<EventGridEHEvent>();
// 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);
}
}
/// <summary>
/// Dumps the data from the Avro blob to the data warehouse (DW).
/// Before running this, ensure that the DW has the required <see cref="TableName"/> table created.
/// </summary>
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<GenericRecord>.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);
}
}
}
/// <summary>
/// Open connection to data warehouse. Write the parsed data to the table.
/// </summary>
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);
}
}
}
/// <summary>
/// Deserialize data and return object with expected properties.
/// </summary>
private static WindTurbineMeasure DeserializeToWindTurbineMeasure(byte[] body)
{
string payload = Encoding.ASCII.GetString(body);
return JsonConvert.DeserializeObject<WindTurbineMeasure>(payload);
}
/// <summary>
/// Define the in-memory table to store the data. The columns match the columns in the .sql script.
/// </summary>
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;
}
/// <summary>
/// For each parsed record, add a row to the in-memory table.
/// </summary>
private static void AddWindTurbineMetricToTable(DataTable table, WindTurbineMeasure wtm)
{
table.Rows.Add(wtm.DeviceId, wtm.MeasureTime, wtm.GeneratedPower, wtm.WindSpeed, wtm.TurbineSpeed);
}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Apache.Avro" Version="1.7.7.2" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.EventGrid" Version="1.0.0-beta4" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.13" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>

Просмотреть файл

@ -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; }
}
}

Просмотреть файл

@ -0,0 +1,2 @@
{
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"AzureWebJobsDashboard": ""
}
}

Просмотреть файл

@ -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.

Просмотреть файл

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.Amqp" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.4.0.0" newVersion="2.4.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Просмотреть файл

@ -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 <ENTER> 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<EventData>();
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);
}
}
}

Просмотреть файл

@ -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")]

Просмотреть файл

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{0C87A54A-AD21-46D5-8B75-4247DA32237E}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>WindTurbineDataGenerator</RootNamespace>
<AssemblyName>WindTurbineDataGenerator</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Azure.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8, processorArchitecture=MSIL">
<HintPath>..\packages\Azure.Core.1.0.0-preview.9\lib\netstandard2.0\Azure.Core.dll</HintPath>
</Reference>
<Reference Include="Azure.Messaging.EventHubs, Version=5.0.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8, processorArchitecture=MSIL">
<HintPath>..\packages\Azure.Messaging.EventHubs.5.0.0-preview.4\lib\netstandard2.0\Azure.Messaging.EventHubs.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.Amqp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Azure.Amqp.2.4.2\lib\net45\Microsoft.Azure.Amqp.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.EventHubs, Version=1.0.2.0, Culture=neutral, PublicKeyToken=7e34167dcc6d6d8c, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Azure.EventHubs.1.0.2\lib\net451\Microsoft.Azure.EventHubs.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0-rc1.19456.4\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.6.0-rc1.19456.4\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Net.WebSockets, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Net.WebSockets.4.0.0\lib\net46\System.Net.WebSockets.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.WebSockets.Client, Version=4.0.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Net.WebSockets.Client.4.0.2\lib\net46\System.Net.WebSockets.Client.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Reflection.TypeExtensions, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reflection.TypeExtensions.4.5.1\lib\net461\System.Reflection.TypeExtensions.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Runtime.Serialization.Primitives, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Algorithms.4.2.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Encoding.4.0.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Primitives.4.0.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.1.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Threading.Channels, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Channels.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Threading.Channels.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WindTurbineMeasure.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Просмотреть файл

@ -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; }
}
}

Просмотреть файл

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Azure.Core" version="1.0.0-preview.9" targetFramework="net461" />
<package id="Azure.Messaging.EventHubs" version="5.0.0-preview.4" targetFramework="net461" />
<package id="Microsoft.Azure.Amqp" version="2.4.2" targetFramework="net461" />
<package id="Microsoft.Azure.EventHubs" version="1.0.2" targetFramework="net461" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="1.0.0-rc1.19456.4" targetFramework="net461" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net461" />
<package id="System.Buffers" version="4.5.0" targetFramework="net461" />
<package id="System.Diagnostics.DiagnosticSource" version="4.6.0-rc1.19456.4" targetFramework="net461" />
<package id="System.Memory" version="4.5.3" targetFramework="net461" />
<package id="System.Net.WebSockets" version="4.0.0" targetFramework="net461" />
<package id="System.Net.WebSockets.Client" version="4.0.2" targetFramework="net461" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net461" />
<package id="System.Reflection.TypeExtensions" version="4.5.1" targetFramework="net461" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net461" />
<package id="System.Runtime.Serialization.Primitives" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.Algorithms" version="4.2.0" targetFramework="net461" />
<package id="System.Security.Cryptography.Encoding" version="4.0.0" targetFramework="net461" />
<package id="System.Security.Cryptography.Primitives" version="4.0.0" targetFramework="net461" />
<package id="System.Security.Cryptography.X509Certificates" version="4.1.0" targetFramework="net461" />
<package id="System.Threading.Channels" version="4.6.0-rc1.19456.4" targetFramework="net461" />
<package id="System.Threading.Tasks.Extensions" version="4.5.2" targetFramework="net461" />
</packages>

Просмотреть файл

@ -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);

Просмотреть файл

@ -0,0 +1 @@
<%@ Application Codebehind="Global.asax.cs" Inherits="ManagedIdentityWebApp.Global" Language="C#" %>

Просмотреть файл

@ -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)
{
}
}
}

Просмотреть файл

@ -0,0 +1,277 @@
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{476F98B4-05BF-42B6-B0B4-E50CD5B71635}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ManagedIdentityWebApp</RootNamespace>
<AssemblyName>ManagedIdentityWebApp</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<UseIISExpress>true</UseIISExpress>
<Use64BitIISExpress />
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="Azure.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8, processorArchitecture=MSIL">
<HintPath>packages\Azure.Core.1.0.0-preview.9\lib\netstandard2.0\Azure.Core.dll</HintPath>
</Reference>
<Reference Include="Azure.Identity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8, processorArchitecture=MSIL">
<HintPath>packages\Azure.Identity.1.0.0-preview.5\lib\netstandard2.0\Azure.Identity.dll</HintPath>
</Reference>
<Reference Include="Azure.Messaging.EventHubs, Version=5.0.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8, processorArchitecture=MSIL">
<HintPath>packages\Azure.Messaging.EventHubs.5.0.0-preview.4\lib\netstandard2.0\Azure.Messaging.EventHubs.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.Amqp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Azure.Amqp.2.4.3\lib\net45\Microsoft.Azure.Amqp.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.Services.AppAuthentication, Version=1.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Azure.Services.AppAuthentication.1.2.1\lib\net472\Microsoft.Azure.Services.AppAuthentication.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Bcl.AsyncInterfaces.1.0.0-rc1.19456.4\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Identity.Client, Version=4.1.0.0, Culture=neutral, PublicKeyToken=0a613f4dd989e8ae, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Identity.Client.4.1.0\lib\net45\Microsoft.Identity.Client.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.19.4.11002, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory.Platform, Version=3.19.4.11002, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.JsonWebTokens, Version=5.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.IdentityModel.JsonWebTokens.5.5.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Logging, Version=5.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.IdentityModel.Logging.5.5.0\lib\net461\Microsoft.IdentityModel.Logging.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Tokens, Version=5.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.IdentityModel.Tokens.5.5.0\lib\net461\Microsoft.IdentityModel.Tokens.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Diagnostics.DiagnosticSource.4.6.0-rc1.19456.4\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.IdentityModel" />
<Reference Include="System.IdentityModel.Tokens.Jwt, Version=5.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\System.IdentityModel.Tokens.Jwt.5.5.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll</HintPath>
</Reference>
<Reference Include="System.IO, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.IO.4.3.0\lib\net462\System.IO.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http, Version=4.1.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.WebSockets, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Net.WebSockets.4.0.0\lib\net46\System.Net.WebSockets.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.WebSockets.Client, Version=4.0.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Net.WebSockets.Client.4.0.2\lib\net46\System.Net.WebSockets.Client.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Reflection.TypeExtensions, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Reflection.TypeExtensions.4.5.1\lib\net461\System.Reflection.TypeExtensions.dll</HintPath>
</Reference>
<Reference Include="System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.CompilerServices.Unsafe.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Runtime.Serialization.Primitives, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security" />
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.ProtectedData, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.ProtectedData.4.5.0\lib\net461\System.Security.Cryptography.ProtectedData.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.ServiceModel" />
<Reference Include="System.Text.Encodings.Web, Version=4.0.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Text.Encodings.Web.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Text.Encodings.Web.dll</HintPath>
</Reference>
<Reference Include="System.Text.Json, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Text.Json.4.6.0-rc1.19456.4\lib\net461\System.Text.Json.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Channels, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Threading.Channels.4.6.0-rc1.19456.4\lib\netstandard2.0\System.Threading.Channels.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="Properties\PublishProfiles\ManagedIdentityWebApp20190718022551 - Web Deploy.pubxml" />
<None Include="Properties\PublishProfiles\ManagedIdentityWebApp20191023043107 - Web Deploy.pubxml" />
<None Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</None>
<None Include="Web.Release.config">
<DependentUpon>Web.config</DependentUpon>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="SendReceive.aspx" />
<Content Include="Global.asax" />
<Content Include="StyleSheet.css" />
<Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Compile Include="SendReceive.aspx.cs">
<DependentUpon>SendReceive.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="SendReceive.aspx.designer.cs">
<DependentUpon>SendReceive.aspx</DependentUpon>
</Compile>
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="App_Data\" />
<Folder Include="Models\" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>56779</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:56779/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -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

Просмотреть файл

@ -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")]

Просмотреть файл

@ -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.

Просмотреть файл

@ -0,0 +1,32 @@
<%@ Page Async="true" Language="C#" AutoEventWireup="true" CodeBehind="SendReceive.aspx.cs" Inherits="ManagedIdentityWebApp.SendReceive" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>EventHubs Managed Identity Demo</title>
<link rel="stylesheet" href="StyleSheet.css" />
</head>
<body>
<form id="form1" runat="server">
<div style="white-space: pre">
<div>
<label>Event Hubs Namespace</label><asp:TextBox ID="txtNamespace" runat="server" Text="" />
</div>
<div>
<label>Event Hub Name</label><asp:TextBox ID="txtEventHub" runat="server" Text=""/>
</div>
<div>
<label>Data to Send</label> <asp:TextBox ID="txtData" runat="server" TextMode="MultiLine" Width="500px"/>
</div>
<div>
<asp:Button ID="btnSend" runat="server" Text="Send" OnClick="btnSend_Click" /> <asp:Button ID="btnReceive" runat="server" Text="Receive" OnClick="btnReceive_Click" />
</div>
<div>
<asp:TextBox ID="txtOutput" runat="server" Enabled="false" TextMode="MultiLine" Width="800px" Height="200px" />
<asp:HiddenField ID="hiddenStartingOffset" runat="server" />
</div>
</div>
</form>
</body>
</html>

Просмотреть файл

@ -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;
}
}
}

Просмотреть файл

@ -0,0 +1,89 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ManagedIdentityWebApp
{
public partial class SendReceive
{
/// <summary>
/// form1 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.HtmlControls.HtmlForm form1;
/// <summary>
/// txtNamespace control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtNamespace;
/// <summary>
/// txtEventHub control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtEventHub;
/// <summary>
/// txtData control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtData;
/// <summary>
/// btnSend control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button btnSend;
/// <summary>
/// btnReceive control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button btnReceive;
/// <summary>
/// txtOutput control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtOutput;
/// <summary>
/// hiddenStartingOffset control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.HiddenField hiddenStartingOffset;
}
}

Просмотреть файл

@ -0,0 +1,13 @@
label {
width: 200px;
display: inline-block;
}
text {
width: 300px;
display: block;
}
input[type="submit"] {
width: 75px;
}

Просмотреть файл

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on using web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an attribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
</configuration>

Просмотреть файл

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on using web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an attribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
</configuration>

Просмотреть файл

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
https://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<!--
For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.
The following attributes can be set on the <httpRuntime> tag.
<system.Web>
<httpRuntime targetFramework="4.7.2" />
</system.Web>
-->
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.6.1" />
<customErrors mode="Off" />
</system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.19.4.11002" newVersion="3.19.4.11002" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.Services.AppAuthentication" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.1.0" newVersion="1.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Tokens" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
</compilers>
</system.codedom>
</configuration>

Просмотреть файл

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Azure.Core" version="1.0.0-preview.9" targetFramework="net472" />
<package id="Azure.Identity" version="1.0.0-preview.5" targetFramework="net472" />
<package id="Azure.Messaging.EventHubs" version="5.0.0-preview.4" targetFramework="net472" />
<package id="Microsoft.Azure.Amqp" version="2.4.3" targetFramework="net472" />
<package id="Microsoft.Azure.EventHubs" version="4.1.0" targetFramework="net472" />
<package id="Microsoft.Azure.Services.AppAuthentication" version="1.2.1" targetFramework="net472" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="1.0.0-rc1.19456.4" targetFramework="net472" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net472" />
<package id="Microsoft.Identity.Client" version="4.1.0" targetFramework="net472" />
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.19.4" targetFramework="net472" />
<package id="Microsoft.IdentityModel.JsonWebTokens" version="5.5.0" targetFramework="net472" />
<package id="Microsoft.IdentityModel.Logging" version="5.5.0" targetFramework="net472" />
<package id="Microsoft.IdentityModel.Tokens" version="5.5.0" targetFramework="net472" />
<package id="Newtonsoft.Json" version="10.0.1" targetFramework="net472" />
<package id="System.Buffers" version="4.5.0" targetFramework="net472" />
<package id="System.Diagnostics.DiagnosticSource" version="4.6.0-rc1.19456.4" targetFramework="net472" />
<package id="System.IdentityModel.Tokens.Jwt" version="5.5.0" targetFramework="net472" />
<package id="System.IO" version="4.3.0" targetFramework="net472" />
<package id="System.Memory" version="4.5.3" targetFramework="net472" />
<package id="System.Net.Http" version="4.3.4" targetFramework="net472" />
<package id="System.Net.WebSockets" version="4.0.0" targetFramework="net472" />
<package id="System.Net.WebSockets.Client" version="4.0.2" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
<package id="System.Reflection.TypeExtensions" version="4.5.1" targetFramework="net472" />
<package id="System.Runtime" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.6.0-rc1.19456.4" targetFramework="net472" />
<package id="System.Runtime.Serialization.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.ProtectedData" version="4.5.0" targetFramework="net472" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net472" />
<package id="System.Text.Encodings.Web" version="4.6.0-rc1.19456.4" targetFramework="net472" />
<package id="System.Text.Json" version="4.6.0-rc1.19456.4" targetFramework="net472" />
<package id="System.Threading.Channels" version="4.6.0-rc1.19456.4" targetFramework="net472" />
<package id="System.Threading.Tasks.Extensions" version="4.5.2" targetFramework="net472" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
</packages>