1414
1515using System ;
1616using System . Collections ;
17+ using System . Collections . Generic ;
1718using System . IO ;
1819using System . Linq ;
1920using 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 }
0 commit comments