Skip to content

Commit 7d405d8

Browse files
committed
Merge pull request #1981 from yantang-msft/EventHub
Add logic to support EventHub config
2 parents 380d900 + f939360 commit 7d405d8

File tree

10 files changed

+435
-35
lines changed

10 files changed

+435
-35
lines changed

src/ResourceManager/Compute/Commands.Compute/Common/DiagnosticsHelper.cs

Lines changed: 92 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
using System;
1616
using System.Collections;
17+
using System.Collections.Generic;
1718
using System.IO;
1819
using System.Linq;
1920
using System.Management.Automation;
@@ -34,7 +35,6 @@ namespace Microsoft.Azure.Commands.Compute.Common
3435
{
3536
public static class DiagnosticsHelper
3637
{
37-
private static string XmlNamespace = "http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration";
3838
private static string EncodedXmlCfg = "xmlCfg";
3939
private static string WadCfg = "WadCfg";
4040
private static string WadCfgBlob = "WadCfgBlob";
@@ -46,6 +46,7 @@ public static class DiagnosticsHelper
4646
private static string StorageAccountKeyTag = "storageAccountKey";
4747
private static string StorageAccountEndPointTag = "storageAccountEndPoint";
4848

49+
public static string XmlNamespace = "http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration";
4950
public static string DiagnosticsConfigurationElemStr = "DiagnosticsConfiguration";
5051
public static string DiagnosticMonitorConfigurationElemStr = "DiagnosticMonitorConfiguration";
5152
public static string PublicConfigElemStr = "PublicConfig";
@@ -56,6 +57,10 @@ public static class DiagnosticsHelper
5657
public static string PrivConfEndpointAttr = "endpoint";
5758
public static string MetricsElemStr = "Metrics";
5859
public static string MetricsResourceIdAttr = "resourceId";
60+
public static string EventHubElemStr = "EventHub";
61+
public static string EventHubUrlAttr = "Url";
62+
public static string EventHubSharedAccessKeyNameAttr = "SharedAccessKeyName";
63+
public static string EventHubSharedAccessKeyAttr = "SharedAccessKey";
5964

6065
public enum ConfigFileType
6166
{
@@ -246,17 +251,36 @@ private static void AutoFillMetricsConfig(JObject wadCfgObject, string resourceI
246251
}
247252
}
248253

249-
public static Hashtable GetPrivateDiagnosticsConfiguration(string storageAccountName,
250-
string storageKey, string endpoint)
254+
public static Hashtable GetPrivateDiagnosticsConfiguration(string configurationPath,
255+
string storageAccountName, string storageKey, string endpoint)
251256
{
252257
var privateConfig = new Hashtable();
253258
privateConfig.Add(StorageAccountNameTag, storageAccountName);
254259
privateConfig.Add(StorageAccountKeyTag, storageKey);
255260
privateConfig.Add(StorageAccountEndPointTag, endpoint);
256261

262+
AddEventHubPrivateConfig(privateConfig, configurationPath);
263+
257264
return privateConfig;
258265
}
259266

267+
private static void AddEventHubPrivateConfig(Hashtable privateConfig, string configurationPath)
268+
{
269+
var eventHubUrl = GetConfigValueFromPrivateConfig(configurationPath, EventHubElemStr, EventHubUrlAttr);
270+
var eventHubSharedAccessKeyName = GetConfigValueFromPrivateConfig(configurationPath, EventHubElemStr, EventHubSharedAccessKeyNameAttr);
271+
var eventHubSharedAccessKey = GetConfigValueFromPrivateConfig(configurationPath, EventHubElemStr, EventHubSharedAccessKeyAttr);
272+
273+
if (!string.IsNullOrEmpty(eventHubUrl) || !string.IsNullOrEmpty(eventHubSharedAccessKeyName) || !string.IsNullOrEmpty(eventHubSharedAccessKey))
274+
{
275+
var eventHubConfig = new Hashtable();
276+
eventHubConfig.Add(EventHubUrlAttr, eventHubUrl);
277+
eventHubConfig.Add(EventHubSharedAccessKeyNameAttr, eventHubSharedAccessKeyName);
278+
eventHubConfig.Add(EventHubSharedAccessKeyAttr, eventHubSharedAccessKey);
279+
280+
privateConfig.Add(EventHubElemStr, eventHubConfig);
281+
}
282+
}
283+
260284
private static XElement GetPublicConfigXElementFromXmlFile(string configurationPath)
261285
{
262286
XElement publicConfig = null;
@@ -292,9 +316,34 @@ private static JObject GetPublicConfigJObjectFromJsonFile(string configurationPa
292316
return publicConfig;
293317
}
294318

295-
public static string GetStorageAccountInfoFromPrivateConfig(string configurationPath, string attributeName)
319+
/// <summary>
320+
/// Get the private config value for a specific attribute.
321+
/// The private config looks like this:
322+
/// XML:
323+
/// <PrivateConfig xmlns="namespace">
324+
/// <StorageAccount name = "name" key="key" endpoint="endpoint" />
325+
/// <EventHub Url = "url" SharedAccessKeyName="sasKeyName" SharedAccessKey="sasKey"/>
326+
/// </PrivateConfig>
327+
///
328+
/// JSON:
329+
/// "PrivateConfig":{
330+
/// "storageAccountName":"name",
331+
/// "storageAccountKey":"key",
332+
/// "storageAccountEndPoint":"endpoint",
333+
/// "EventHub":{
334+
/// "Url":"url",
335+
/// "SharedAccessKeyName":"sasKeyName",
336+
/// "SharedAccessKey":"sasKey"
337+
/// }
338+
/// }
339+
/// </summary>
340+
/// <param name="configurationPath">The path to the configuration file</param>
341+
/// <param name="elementName">The element name of the private config. e.g., StorageAccount, EventHub</param>
342+
/// <param name="attributeName">The attribute name of the element</param>
343+
/// <returns></returns>
344+
public static string GetConfigValueFromPrivateConfig(string configurationPath, string elementName, string attributeName)
296345
{
297-
string value = null;
346+
string value = string.Empty;
298347
var configFileType = GetConfigFileType(configurationPath);
299348

300349
if (configFileType == ConfigFileType.Xml)
@@ -304,25 +353,54 @@ public static string GetStorageAccountInfoFromPrivateConfig(string configuration
304353
if (xmlConfig.Name.LocalName == DiagnosticsConfigurationElemStr)
305354
{
306355
var privateConfigElem = xmlConfig.Elements().FirstOrDefault(ele => ele.Name.LocalName == PrivateConfigElemStr);
307-
var storageAccountElem = privateConfigElem == null ? null : privateConfigElem.Elements().FirstOrDefault(ele => ele.Name.LocalName == StorageAccountElemStr);
308-
var attribute = storageAccountElem == null ? null : storageAccountElem.Attributes().FirstOrDefault(a => string.Equals(a.Name.LocalName, attributeName));
356+
var configElem = privateConfigElem == null ? null : privateConfigElem.Elements().FirstOrDefault(ele => ele.Name.LocalName == elementName);
357+
var attribute = configElem == null ? null : configElem.Attributes().FirstOrDefault(a => string.Equals(a.Name.LocalName, attributeName));
309358
value = attribute == null ? null : attribute.Value;
310359
}
311360
}
312361
else if (configFileType == ConfigFileType.Json)
313362
{
363+
// Find the PrivateConfig
314364
var jsonConfig = JsonConvert.DeserializeObject<JObject>(File.ReadAllText(configurationPath));
315365
var properties = jsonConfig.Properties().Select(p => p.Name);
366+
var privateConfigProperty = properties.FirstOrDefault(p => p.Equals(PrivateConfigElemStr));
316367

317-
var privateConfigProperty = properties.FirstOrDefault(p => p.Equals(PrivateConfigElemStr, StringComparison.OrdinalIgnoreCase));
318-
if (privateConfigProperty != null)
368+
if (privateConfigProperty == null)
369+
{
370+
return value;
371+
}
372+
var privateConfig = jsonConfig[privateConfigProperty] as JObject;
373+
374+
// Find the target config object corresponding to elementName
375+
JObject targetConfig = null;
376+
if (elementName == StorageAccountElemStr)
377+
{
378+
// Special handling as private storage config is flattened
379+
targetConfig = privateConfig;
380+
var attributeNameMapping = new Dictionary<string, string>()
381+
{
382+
{ PrivConfNameAttr, "storageAccountName" },
383+
{ PrivConfKeyAttr, "storageAccountKey" },
384+
{ PrivConfEndpointAttr, "storageAccountEndPoint" }
385+
};
386+
attributeName = attributeNameMapping.FirstOrDefault(m => m.Key == attributeName).Value;
387+
}
388+
else
319389
{
320-
var privateConfig = jsonConfig[privateConfigProperty] as JObject;
321390
properties = privateConfig.Properties().Select(p => p.Name);
391+
var configProperty = properties.FirstOrDefault(p => p.Equals(elementName));
392+
targetConfig = configProperty == null ? null : privateConfig[configProperty] as JObject;
393+
}
322394

323-
var attributeProperty = properties.FirstOrDefault(p => p.Equals(attributeName, StringComparison.OrdinalIgnoreCase));
324-
value = attributeProperty == null ? null : privateConfig[attributeProperty].Value<string>();
395+
if (targetConfig == null || attributeName == null)
396+
{
397+
return value;
325398
}
399+
400+
// Find the config value corresponding to attributeName
401+
properties = targetConfig.Properties().Select(p => p.Name);
402+
var attributeProperty = properties.FirstOrDefault(p => p.Equals(attributeName));
403+
value = attributeProperty == null ? null : targetConfig[attributeProperty].Value<string>();
326404
}
327405

328406
return value;
@@ -381,7 +459,7 @@ public static string InitializeStorageAccountKey(IStorageManagementClient storag
381459
else
382460
{
383461
// Use the one defined in PrivateConfig
384-
storageAccountKey = GetStorageAccountInfoFromPrivateConfig(configurationPath, PrivConfKeyAttr);
462+
storageAccountKey = GetConfigValueFromPrivateConfig(configurationPath, StorageAccountElemStr, PrivConfKeyAttr);
385463
}
386464

387465
return storageAccountKey;
@@ -414,7 +492,7 @@ public static string InitializeStorageAccountEndpoint(string storageAccountName,
414492
storageAccountEndpoint = GetEndpointFromStorageContext(context);
415493
}
416494
else if (!string.IsNullOrEmpty(
417-
storageAccountEndpoint = GetStorageAccountInfoFromPrivateConfig(configurationPath, PrivConfEndpointAttr)))
495+
storageAccountEndpoint = GetConfigValueFromPrivateConfig(configurationPath, StorageAccountElemStr, PrivConfEndpointAttr)))
418496
{
419497
// We can get the value from PrivateConfig
420498
}

src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/SetAzureRmVMDiagnosticsExtension.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,8 @@ private Hashtable PrivateConfiguration
194194
{
195195
if (this.privateConfiguration == null)
196196
{
197-
this.privateConfiguration = DiagnosticsHelper.GetPrivateDiagnosticsConfiguration(this.StorageAccountName,
198-
this.StorageAccountKey,
199-
this.StorageAccountEndpoint);
197+
this.privateConfiguration = DiagnosticsHelper.GetPrivateDiagnosticsConfiguration(this.DiagnosticsConfigurationPath,
198+
this.StorageAccountName, this.StorageAccountKey, this.StorageAccountEndpoint);
200199
}
201200

202201
return this.privateConfiguration;

src/ServiceManagement/Compute/Commands.ServiceManagement.Test/Commands.ServiceManagement.Test.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@
457457
<DesignTime>True</DesignTime>
458458
<DependentUpon>Resource.resx</DependentUpon>
459459
</Compile>
460+
<Compile Include="UnitTests\Cmdlets\IaaS\Extensions\Diagnostics\DiagnosticsHelperTest.cs" />
460461
<Compile Include="UnitTests\Cmdlets\IaaS\Extensions\DSC\DscExtensionConfigurationParsingHelperTests.cs" />
461462
<Compile Include="UnitTests\Cmdlets\IaaS\Extensions\DSC\DscExtensionSettingsSerializerTests.cs" />
462463
<Compile Include="UnitTests\Cmdlets\IaaS\Extensions\DSC\GetAzureVMDscExtensionStatusUnitTest.cs" />
@@ -577,6 +578,12 @@
577578
<None Include="Resources\wrongPara_VHD.csv">
578579
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
579580
</None>
581+
<None Include="Resources\Diagnostics\diagnostics.wadcfgx">
582+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
583+
</None>
584+
<None Include="Resources\Diagnostics\config.json">
585+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
586+
</None>
580587
</ItemGroup>
581588
<ItemGroup>
582589
<Content Include="FunctionalTests\ExtensionTests\MicrosoftAntimalware\AntimalwareConfig.xml" />

src/ServiceManagement/Compute/Commands.ServiceManagement.Test/FunctionalTests/Constants.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@ namespace Microsoft.WindowsAzure.Commands.ServiceManagement.Test
1717
public class Category
1818
{
1919
public const string Scenario = "AzureRTScenario";
20-
public const string BVT = "BVT";
2120
public const string Functional = "Functional";
2221
public const string Preview = "Preview";
2322
public const string Sequential = "Sequential";
2423
public const string Network = "Network";
2524
public const string Upload = "AzureRTUpload";
2625
public const string CleanUp = "AzureRTCleanUp";
26+
27+
// Acceptance type
28+
public const string AcceptanceType = "AcceptanceType";
29+
public const string BVT = "BVT";
30+
public const string CheckIn = "CheckIn";
2731
}
2832

2933
public class LoadBalancerDistribution
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
{
2+
"PublicConfig": {
3+
"WadCfg": {
4+
"DiagnosticMonitorConfiguration": {
5+
"DiagnosticInfrastructureLogs": {
6+
"scheduledTransferLogLevelFilter": "Error"
7+
},
8+
"Directories": {
9+
"IISLogs": {
10+
"containerName": "wad-iis-logfiles"
11+
},
12+
"FailedRequestLogs": {
13+
"containerName": "wad-failedrequestlogs"
14+
},
15+
"scheduledTransferPeriod": "PT1M"
16+
},
17+
"PerformanceCounters": {
18+
"PerformanceCounterConfiguration": [
19+
{
20+
"annotation": [
21+
22+
],
23+
"counterSpecifier": "\\Memory\\Available MBytes",
24+
"sampleRate": "PT15S",
25+
"sinks": "HotPath"
26+
},
27+
{
28+
"annotation": [
29+
30+
],
31+
"counterSpecifier": "\\Web Service(_Total)\\ISAPI Extension Requests/sec",
32+
"sampleRate": "PT3M"
33+
},
34+
{
35+
"annotation": [
36+
37+
],
38+
"counterSpecifier": "\\Web Service(_Total)\\Bytes Total/Sec",
39+
"sampleRate": "PT3M"
40+
},
41+
{
42+
"annotation": [
43+
44+
],
45+
"counterSpecifier": "\\ASP.NET Applications(__Total__)\\Requests/Sec",
46+
"sampleRate": "PT3M"
47+
},
48+
{
49+
"annotation": [
50+
51+
],
52+
"counterSpecifier": "\\ASP.NET Applications(__Total__)\\Errors Total/Sec",
53+
"sampleRate": "PT3M"
54+
},
55+
{
56+
"annotation": [
57+
58+
],
59+
"counterSpecifier": "\\ASP.NET\\Requests Queued",
60+
"sampleRate": "PT3M"
61+
},
62+
{
63+
"annotation": [
64+
65+
],
66+
"counterSpecifier": "\\ASP.NET\\Requests Rejected",
67+
"sampleRate": "PT3M"
68+
},
69+
{
70+
"annotation": [
71+
72+
],
73+
"counterSpecifier": "\\Processor(_Total)\\% Processor Time",
74+
"sampleRate": "PT3M"
75+
}
76+
],
77+
"scheduledTransferPeriod": "PT1M"
78+
},
79+
"WindowsEventLog": {
80+
"sinks": "HotPath",
81+
"DataSource": [
82+
{
83+
"name": "Application!*[System[(Level=1 or Level=2 or Level=3)]]"
84+
},
85+
{
86+
"name": "Windows Azure!*[System[(Level=1 or Level=2 or Level=3 or Level=4)]]"
87+
}
88+
],
89+
"scheduledTransferPeriod": "PT1M"
90+
},
91+
"CrashDumps": {
92+
"CrashDumpConfiguration": [
93+
{
94+
"processName": "WaIISHost.exe"
95+
},
96+
{
97+
"processName": "WaWorkerHost.exe"
98+
},
99+
{
100+
"processName": "w3wp.exe"
101+
}
102+
]
103+
},
104+
"Logs": {
105+
"scheduledTransferLogLevelFilter": "Error",
106+
"scheduledTransferPeriod": "PT1M"
107+
},
108+
"overallQuotaInMB": 4096
109+
},
110+
"SinksConfig": {
111+
"Sink": [
112+
{
113+
"name": "HotPath",
114+
"EventHub": {
115+
"Url": "Url",
116+
"SharedAccessKeyName": "sasKeyName"
117+
}
118+
}
119+
]
120+
}
121+
},
122+
"StorageAccount": "yanmingv2vm9503"
123+
},
124+
"PrivateConfig": {
125+
"storageAccountName": "storageAccountName",
126+
"storageAccountKey": "storageAccountKey",
127+
"storageAccountEndPoint": "https://core.windows.net/",
128+
"EventHub": {
129+
"Url": "Url",
130+
"SharedAccessKeyName": "sasKeyName",
131+
"SharedAccessKey": "sasKey"
132+
}
133+
}
134+
}

0 commit comments

Comments
 (0)