88 using Azure . Core ;
99 using Azure . Identity ;
1010 using Azure . Messaging . ServiceBus . Administration ;
11- using Azure . Monitor . Query ;
12- using Azure . Monitor . Query . Models ;
11+ using Azure . Monitor . Query . Metrics ;
12+ using Azure . Monitor . Query . Metrics . Models ;
1313
1414 public class AzureClient
1515 {
16- readonly string resourceId ;
16+ readonly ResourceIdentifier resourceId ;
1717 readonly AuthenticatedClientSet [ ] connections ;
1818 readonly List < string > loginExceptions = [ ] ;
1919 readonly Action < string > log ;
@@ -22,26 +22,15 @@ public class AzureClient
2222 AuthenticatedClientSet currentClients ;
2323
2424 public string FullyQualifiedNamespace { get ; }
25- public string SubscriptionId { get ; }
26- public string ResourceGroup { get ; }
27-
28- public AzureClient ( string resourceId , string serviceBusDomain , Action < string > log = null )
25+ public AzureClient ( string resourceId , string serviceBusDomain , string region , string metricsDomain , Action < string > log = null )
2926 {
30- this . resourceId = resourceId ;
27+ this . resourceId = ResourceIdentifier . Parse ( resourceId ) ;
3128
3229 this . log = log ?? new ( msg => { } ) ;
3330
34- var resourceIdentifier = ResourceIdentifier . Parse ( resourceId ) ;
35-
36- ResourceGroup = resourceIdentifier . ResourceGroupName ;
37-
38- SubscriptionId = resourceIdentifier . SubscriptionId ;
39-
40- FullyQualifiedNamespace = $ "{ resourceIdentifier . Name } .{ serviceBusDomain } ";
31+ FullyQualifiedNamespace = $ "{ this . resourceId . Name } .{ serviceBusDomain } ";
4132
42- connections = CreateCredentials ( )
43- . Select ( c => new AuthenticatedClientSet ( c , FullyQualifiedNamespace ) )
44- . ToArray ( ) ;
33+ connections = [ .. CreateCredentials ( ) . Select ( c => new AuthenticatedClientSet ( c , FullyQualifiedNamespace , region , metricsDomain ) ) ] ;
4534
4635 ResetConnectionQueue ( ) ;
4736 }
@@ -51,7 +40,6 @@ IEnumerable<TokenCredential> CreateCredentials()
5140 yield return new AzureCliCredential ( ) ;
5241 yield return new AzurePowerShellCredential ( ) ;
5342 yield return new EnvironmentCredential ( ) ;
54- yield return new SharedTokenCacheCredential ( ) ;
5543 yield return new VisualStudioCredential ( ) ;
5644
5745 // Don't really need this one to take 100s * 4 tries to finally time out
@@ -64,10 +52,7 @@ IEnumerable<TokenCredential> CreateCredentials()
6452 /// <summary>
6553 /// Doesn't change the last successful `current` method but restores all options as possibilities if it doesn't work
6654 /// </summary>
67- public void ResetConnectionQueue ( )
68- {
69- connectionQueue = new Queue < AuthenticatedClientSet > ( connections ) ;
70- }
55+ public void ResetConnectionQueue ( ) => connectionQueue = new Queue < AuthenticatedClientSet > ( connections ) ;
7156
7257 async Task < T > GetDataWithCurrentCredentials < T > ( GetDataDelegate < T > getData , CancellationToken cancellationToken )
7358 {
@@ -116,33 +101,33 @@ bool NextCredentials()
116101 }
117102 }
118103
119- public Task < IReadOnlyList < MetricValue > > GetMetrics ( string queueName , DateOnly startTime , DateOnly endTime , CancellationToken cancellationToken = default )
120- {
121- return GetDataWithCurrentCredentials ( async token =>
104+ public Task < IList < MetricValue > > GetMetrics ( string queueName , DateOnly startTime , DateOnly endTime , CancellationToken cancellationToken = default ) =>
105+ GetDataWithCurrentCredentials ( async token =>
122106 {
123107 try
124108 {
125- var response = await currentClients . Metrics . QueryResourceAsync ( resourceId ,
109+ var response = await currentClients . Metrics . QueryResourcesAsync (
110+ [ resourceId ] ,
126111 [ "CompleteMessage" ] ,
127- new MetricsQueryOptions
112+ "Microsoft.ServiceBus/Namespaces" ,
113+ new MetricsQueryResourcesOptions
128114 {
129115 Filter = $ "EntityName eq '{ queueName } '",
130- TimeRange = new QueryTimeRange ( startTime . ToDateTime ( TimeOnly . MinValue , DateTimeKind . Utc ) , endTime . ToDateTime ( TimeOnly . MaxValue , DateTimeKind . Utc ) ) ,
116+ StartTime = startTime . ToDateTime ( TimeOnly . MinValue , DateTimeKind . Utc ) ,
117+ EndTime = endTime . ToDateTime ( TimeOnly . MaxValue , DateTimeKind . Utc ) ,
131118 Granularity = TimeSpan . FromDays ( 1 )
132119 } ,
133120 token ) . ConfigureAwait ( false ) ;
134121
135122 // Yeah, it's buried deep
136- var metricValues = response . Value . Metrics . FirstOrDefault ( ) ? . TimeSeries . FirstOrDefault ( ) ? . Values ;
137- return metricValues ;
123+ return response . Value . Values . FirstOrDefault ( ) ? . Metrics . FirstOrDefault ( ) ? . TimeSeries . FirstOrDefault ( ) ? . Values ?? [ ] ;
138124 }
139125 catch ( Azure . RequestFailedException reqFailed ) when ( reqFailed . Message . Contains ( "ResourceGroupNotFound" ) )
140126 {
141127 // Azure exception message has a lot of information including exact resource group name
142128 throw new QueryException ( QueryFailureReason . InvalidEnvironment , reqFailed . Message ) ;
143129 }
144130 } , cancellationToken ) ;
145- }
146131
147132 public Task < string [ ] > GetQueueNames ( CancellationToken cancellationToken = default )
148133 {
@@ -162,31 +147,24 @@ public Task<string[]> GetQueueNames(CancellationToken cancellationToken = defaul
162147 } , cancellationToken ) ;
163148 }
164149
165- static bool IsAuthenticationException ( Exception x )
166- {
167- return x is CredentialUnavailableException or AuthenticationFailedException or UnauthorizedAccessException ;
168- }
150+ static bool IsAuthenticationException ( Exception x ) =>
151+ x is CredentialUnavailableException or AuthenticationFailedException or UnauthorizedAccessException ;
169152
170153 delegate Task < T > GetDataDelegate < T > ( CancellationToken cancellationToken ) ;
171154
172155 class AuthenticatedClientSet
173156 {
174157 public string Name { get ; }
175- public MetricsQueryClient Metrics { get ; }
158+ public MetricsClient Metrics { get ; }
176159 public ServiceBusAdministrationClient ServiceBus { get ; }
177160
178- public AuthenticatedClientSet ( TokenCredential credentials , string fullyQualifiedNamespace )
161+ public AuthenticatedClientSet ( TokenCredential credentials , string fullyQualifiedNamespace , string region , string metricsDomain )
179162 {
180- var managementUrl = "https://management.azure.com" ;
181-
182- if ( ! fullyQualifiedNamespace . EndsWith ( "servicebus.windows.net" , StringComparison . OrdinalIgnoreCase ) )
183- {
184- var reversedParts = fullyQualifiedNamespace . Split ( '.' , StringSplitOptions . RemoveEmptyEntries ) . Reverse ( ) . ToArray ( ) ;
185- managementUrl = $ "https://management.{ reversedParts [ 1 ] } .{ reversedParts [ 0 ] } ";
186- }
163+ var metricsUrl = $ "https://{ region } .{ metricsDomain } ";
164+ var audience = $ "https://{ metricsDomain } ";
187165
188166 Name = credentials . GetType ( ) . Name ;
189- Metrics = new MetricsQueryClient ( new Uri ( managementUrl ) , credentials , new MetricsQueryClientOptions { Audience = new MetricsQueryAudience ( managementUrl ) } ) ;
167+ Metrics = new MetricsClient ( new Uri ( metricsUrl ) , credentials , new MetricsClientOptions { Audience = new MetricsClientAudience ( audience ) } ) ;
190168 ServiceBus = new ServiceBusAdministrationClient ( fullyQualifiedNamespace , credentials ) ;
191169 }
192170 }
0 commit comments