Skip to content

Commit 50db228

Browse files
add generated code
1 parent c7bb0a4 commit 50db228

27 files changed

+1285
-9
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Microsoft Visual Studio Solution File, Format Version 12.00
2+
# Visual Studio Version 17
3+
VisualStudioVersion = 17.5.2.0
4+
MinimumVisualStudioVersion = 10.0.40219.1
5+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Iot.Operations.Services", "Azure.Iot.Operations.Services.csproj", "{A98A1401-F7CD-3CAC-A3A0-931D8873FEF9}"
6+
EndProject
7+
Global
8+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
9+
Debug|Any CPU = Debug|Any CPU
10+
Release|Any CPU = Release|Any CPU
11+
EndGlobalSection
12+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
13+
{A98A1401-F7CD-3CAC-A3A0-931D8873FEF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
14+
{A98A1401-F7CD-3CAC-A3A0-931D8873FEF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
15+
{A98A1401-F7CD-3CAC-A3A0-931D8873FEF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
16+
{A98A1401-F7CD-3CAC-A3A0-931D8873FEF9}.Release|Any CPU.Build.0 = Release|Any CPU
17+
EndGlobalSection
18+
GlobalSection(SolutionProperties) = preSolution
19+
HideSolutionNode = FALSE
20+
EndGlobalSection
21+
GlobalSection(ExtensibilityGlobals) = postSolution
22+
SolutionGuid = {5D7B8265-62A7-4E82-9C32-536AADFE007E}
23+
EndGlobalSection
24+
EndGlobal
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* Code generated by Azure.Iot.Operations.ProtocolCompiler v0.10.0.0; DO NOT EDIT. */
2+
3+
#nullable enable
4+
5+
namespace Azure.Iot.Operations.Services.Observability.AkriObservabilityService
6+
{
7+
using System.Runtime.Serialization;
8+
using System.Text.Json.Serialization;
9+
10+
/// <summary>
11+
/// Enumerates structured error types for failed metric operations.
12+
/// </summary>
13+
[JsonConverter(typeof(JsonStringEnumMemberConverter))]
14+
[System.CodeDom.Compiler.GeneratedCode("Azure.Iot.Operations.ProtocolCompiler", "0.10.0.0")]
15+
public enum AkriMetricErrorKind
16+
{
17+
[EnumMember(Value = @"ConflictingMetricDefinition")]
18+
ConflictingMetricDefinition = 0,
19+
[EnumMember(Value = @"DuplicateOperationId")]
20+
DuplicateOperationId = 1,
21+
[EnumMember(Value = @"InternalError")]
22+
InternalError = 2,
23+
[EnumMember(Value = @"TooManyUniqueLabelSets")]
24+
TooManyUniqueLabelSets = 3,
25+
}
26+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/* Code generated by Azure.Iot.Operations.ProtocolCompiler v0.10.0.0; DO NOT EDIT. */
2+
3+
#nullable enable
4+
5+
namespace Azure.Iot.Operations.Services.Observability.AkriObservabilityService
6+
{
7+
using System;
8+
using System.Collections.Generic;
9+
using System.Text.Json.Serialization;
10+
using Azure.Iot.Operations.Services.Observability;
11+
12+
/// <summary>
13+
/// Represents the result of a single metric operation, including structured error information if applicable.
14+
/// </summary>
15+
[System.CodeDom.Compiler.GeneratedCode("Azure.Iot.Operations.ProtocolCompiler", "0.10.0.0")]
16+
public partial class AkriMetricOperationResponse : IJsonOnDeserialized, IJsonOnSerializing
17+
{
18+
/// <summary>
19+
/// Structured classification of the error type, included only if status is Error.
20+
/// </summary>
21+
[JsonPropertyName("errorKind")]
22+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
23+
public AkriMetricErrorKind? ErrorKind { get; set; } = default;
24+
25+
/// <summary>
26+
/// Optional human-readable description of the error.
27+
/// </summary>
28+
[JsonPropertyName("errorMessage")]
29+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
30+
public string? ErrorMessage { get; set; } = default;
31+
32+
/// <summary>
33+
/// ID of the operation this response refers to.
34+
/// </summary>
35+
[JsonPropertyName("operationId")]
36+
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
37+
[JsonRequired]
38+
public string OperationId { get; set; } = default!;
39+
40+
/// <summary>
41+
/// Optional name of the field or conceptual field associated with the error.
42+
/// </summary>
43+
[JsonPropertyName("propertyName")]
44+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
45+
public string? PropertyName { get; set; } = default;
46+
47+
/// <summary>
48+
/// Status of the operation: either Success or Error.
49+
/// </summary>
50+
[JsonPropertyName("status")]
51+
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
52+
[JsonRequired]
53+
public AkriMetricOperationResponseStatus Status { get; set; } = default!;
54+
55+
void IJsonOnDeserialized.OnDeserialized()
56+
{
57+
if (OperationId is null)
58+
{
59+
throw new ArgumentNullException("operationId field cannot be null");
60+
}
61+
}
62+
63+
void IJsonOnSerializing.OnSerializing()
64+
{
65+
if (OperationId is null)
66+
{
67+
throw new ArgumentNullException("operationId field cannot be null");
68+
}
69+
}
70+
}
71+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* Code generated by Azure.Iot.Operations.ProtocolCompiler v0.10.0.0; DO NOT EDIT. */
2+
3+
#nullable enable
4+
5+
namespace Azure.Iot.Operations.Services.Observability.AkriObservabilityService
6+
{
7+
using System.Runtime.Serialization;
8+
using System.Text.Json.Serialization;
9+
10+
/// <summary>
11+
/// Defines possible statuses of a metric operation.
12+
/// </summary>
13+
[JsonConverter(typeof(JsonStringEnumMemberConverter))]
14+
[System.CodeDom.Compiler.GeneratedCode("Azure.Iot.Operations.ProtocolCompiler", "0.10.0.0")]
15+
public enum AkriMetricOperationResponseStatus
16+
{
17+
[EnumMember(Value = @"Error")]
18+
Error = 0,
19+
[EnumMember(Value = @"Success")]
20+
Success = 1,
21+
}
22+
}
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/* Code generated by Azure.Iot.Operations.ProtocolCompiler v0.10.0.0; DO NOT EDIT. */
2+
3+
#nullable enable
4+
5+
namespace Azure.Iot.Operations.Services.Observability.AkriObservabilityService
6+
{
7+
using System;
8+
using System.Collections.Generic;
9+
using System.Linq;
10+
using System.Threading;
11+
using System.Threading.Tasks;
12+
using Azure.Iot.Operations.Protocol.Models;
13+
using Azure.Iot.Operations.Protocol;
14+
using Azure.Iot.Operations.Protocol.RPC;
15+
using Azure.Iot.Operations.Protocol.Telemetry;
16+
using Azure.Iot.Operations.Services.Observability;
17+
18+
[CommandTopic("akri/observability/{ex:connectorClientId}/metrics")]
19+
[System.CodeDom.Compiler.GeneratedCode("Azure.Iot.Operations.ProtocolCompiler", "0.10.0.0")]
20+
public static partial class AkriObservabilityService
21+
{
22+
public abstract partial class Service : IAsyncDisposable
23+
{
24+
private ApplicationContext applicationContext;
25+
private IMqttPubSubClient mqttClient;
26+
private readonly PublishMetricsCommandExecutor publishMetricsCommandExecutor;
27+
28+
/// <summary>
29+
/// Construct a new instance of this service.
30+
/// </summary>
31+
/// <param name="applicationContext">The shared context for your application.</param>
32+
/// <param name="mqttClient">The MQTT client to use.</param>
33+
/// <param name="topicTokenMap">
34+
/// The topic token replacement map to use for all operations by default. Generally, this will include the token values
35+
/// for topic tokens such as "modelId" which should be the same for the duration of this service's lifetime. Note that
36+
/// additional topic tokens can be specified when starting the service with <see cref="StartAsync(Dictionary{string, string}?, int?, CancellationToken)"/> and
37+
/// can be specified per-telemetry message.
38+
/// </param>
39+
public Service(ApplicationContext applicationContext, IMqttPubSubClient mqttClient, Dictionary<string, string>? topicTokenMap = null)
40+
{
41+
this.applicationContext = applicationContext;
42+
this.mqttClient = mqttClient;
43+
44+
string? clientId = this.mqttClient.ClientId;
45+
if (string.IsNullOrEmpty(clientId))
46+
{
47+
throw new InvalidOperationException("No MQTT client Id configured. Must connect to MQTT broker before invoking command.");
48+
}
49+
50+
this.publishMetricsCommandExecutor = new PublishMetricsCommandExecutor(applicationContext, mqttClient) { OnCommandReceived = PublishMetricsInt };
51+
52+
if (topicTokenMap != null)
53+
{
54+
foreach (string topicTokenKey in topicTokenMap.Keys)
55+
{
56+
this.publishMetricsCommandExecutor.TopicTokenMap.TryAdd("ex:" + topicTokenKey, topicTokenMap[topicTokenKey]);
57+
}
58+
}
59+
60+
this.publishMetricsCommandExecutor.TopicTokenMap.TryAdd("executorId", clientId);
61+
}
62+
63+
public PublishMetricsCommandExecutor PublishMetricsCommandExecutor { get => this.publishMetricsCommandExecutor; }
64+
65+
public abstract Task<ExtendedResponse<PublishMetricsResponsePayload>> PublishMetricsAsync(PublishMetricsRequestPayload request, CommandRequestMetadata requestMetadata, CancellationToken cancellationToken);
66+
67+
/// <summary>
68+
/// Begin accepting command invocations for all command executors.
69+
/// </summary>
70+
/// <param name="additionalTopicTokenMap">
71+
/// The topic token replacements to use in addition to any topic tokens specified in the constructor. If this map
72+
/// contains any keys that topic tokens provided in the constructor also has, then values specified in this map will take precedence.
73+
/// </param>
74+
/// <param name="preferredDispatchConcurrency">The dispatch concurrency count for the command response cache to use.</param>
75+
/// <param name="cancellationToken">Cancellation token.</param>
76+
/// <remarks>
77+
/// Specifying custom topic tokens in <paramref name="additionalTopicTokenMap"/> allows you to make command executors only
78+
/// accept commands over a specific topic.
79+
///
80+
/// Note that a given command executor can only be started with one set of topic token replacements. If you want a command executor
81+
/// to only handle commands for several specific sets of topic token values (as opposed to all possible topic token values), then you will
82+
/// instead need to create a command executor per topic token set.
83+
/// </remarks>
84+
public async Task StartAsync(int? preferredDispatchConcurrency = null, CancellationToken cancellationToken = default)
85+
{
86+
string? clientId = this.mqttClient.ClientId;
87+
if (string.IsNullOrEmpty(clientId))
88+
{
89+
throw new InvalidOperationException("No MQTT client Id configured. Must connect to MQTT broker before starting service.");
90+
}
91+
92+
await Task.WhenAll(
93+
this.publishMetricsCommandExecutor.StartAsync(preferredDispatchConcurrency, cancellationToken)).ConfigureAwait(false);
94+
}
95+
96+
public async Task StopAsync(CancellationToken cancellationToken = default)
97+
{
98+
await Task.WhenAll(
99+
this.publishMetricsCommandExecutor.StopAsync(cancellationToken)).ConfigureAwait(false);
100+
}
101+
102+
private async Task<ExtendedResponse<PublishMetricsResponsePayload>> PublishMetricsInt(ExtendedRequest<PublishMetricsRequestPayload> req, CancellationToken cancellationToken)
103+
{
104+
ExtendedResponse<PublishMetricsResponsePayload> extended = await this.PublishMetricsAsync(req.Request!, req.RequestMetadata!, cancellationToken);
105+
return new ExtendedResponse<PublishMetricsResponsePayload> { Response = extended.Response, ResponseMetadata = extended.ResponseMetadata };
106+
}
107+
108+
public async ValueTask DisposeAsync()
109+
{
110+
await this.publishMetricsCommandExecutor.DisposeAsync().ConfigureAwait(false);
111+
}
112+
113+
public async ValueTask DisposeAsync(bool disposing)
114+
{
115+
await this.publishMetricsCommandExecutor.DisposeAsync(disposing).ConfigureAwait(false);
116+
}
117+
}
118+
119+
public abstract partial class Client : IAsyncDisposable
120+
{
121+
private ApplicationContext applicationContext;
122+
private IMqttPubSubClient mqttClient;
123+
private readonly PublishMetricsCommandInvoker publishMetricsCommandInvoker;
124+
125+
/// <summary>
126+
/// Construct a new instance of this client.
127+
/// </summary>
128+
/// <param name="applicationContext">The shared context for your application.</param>
129+
/// <param name="mqttClient">The MQTT client to use.</param>
130+
/// <param name="topicTokenMap">
131+
/// The topic token replacement map to use for all operations by default. Generally, this will include the token values
132+
/// for topic tokens such as "modelId" which should be the same for the duration of this client's lifetime. Note that
133+
/// additional topic tokens can be specified when starting the client with <see cref="StartAsync(Dictionary{string, string}?, int?, CancellationToken)"/>.
134+
/// </param>
135+
public Client(ApplicationContext applicationContext, IMqttPubSubClient mqttClient, Dictionary<string, string>? topicTokenMap = null)
136+
{
137+
this.applicationContext = applicationContext;
138+
this.mqttClient = mqttClient;
139+
140+
this.publishMetricsCommandInvoker = new PublishMetricsCommandInvoker(applicationContext, mqttClient);
141+
if (topicTokenMap != null)
142+
{
143+
foreach (string topicTokenKey in topicTokenMap.Keys)
144+
{
145+
this.publishMetricsCommandInvoker.TopicTokenMap.TryAdd("ex:" + topicTokenKey, topicTokenMap[topicTokenKey]);
146+
}
147+
}
148+
}
149+
150+
public PublishMetricsCommandInvoker PublishMetricsCommandInvoker { get => this.publishMetricsCommandInvoker; }
151+
152+
/// <summary>
153+
/// Invoke a command.
154+
/// </summary>
155+
/// <param name="requestMetadata">The metadata for this command request.</param>
156+
/// <param name="additionalTopicTokenMap">
157+
/// The topic token replacement map to use in addition to the topic tokens specified in the constructor. If this map
158+
/// contains any keys that the topic tokens specified in the constructor also has, then values specified in this map will take precedence.
159+
/// </param>
160+
/// <param name="commandTimeout">How long the command will be available on the broker for an executor to receive.</param>
161+
/// <param name="cancellationToken">Cancellation token.</param>
162+
/// <returns>The command response.</returns>
163+
public RpcCallAsync<PublishMetricsResponsePayload> PublishMetricsAsync(PublishMetricsRequestPayload request, CommandRequestMetadata? requestMetadata = null, Dictionary<string, string>? additionalTopicTokenMap = null, TimeSpan? commandTimeout = default, CancellationToken cancellationToken = default)
164+
{
165+
string? clientId = this.mqttClient.ClientId;
166+
if (string.IsNullOrEmpty(clientId))
167+
{
168+
throw new InvalidOperationException("No MQTT client Id configured. Must connect to MQTT broker before invoking command.");
169+
}
170+
171+
CommandRequestMetadata metadata = requestMetadata ?? new CommandRequestMetadata();
172+
additionalTopicTokenMap ??= new();
173+
174+
Dictionary<string, string> prefixedAdditionalTopicTokenMap = new();
175+
foreach (string key in additionalTopicTokenMap.Keys)
176+
{
177+
prefixedAdditionalTopicTokenMap["ex:" + key] = additionalTopicTokenMap[key];
178+
}
179+
180+
prefixedAdditionalTopicTokenMap["invokerClientId"] = clientId;
181+
182+
return new RpcCallAsync<PublishMetricsResponsePayload>(this.publishMetricsCommandInvoker.InvokeCommandAsync(request, metadata, prefixedAdditionalTopicTokenMap, commandTimeout, cancellationToken), metadata.CorrelationId);
183+
}
184+
185+
public async ValueTask DisposeAsync()
186+
{
187+
await this.publishMetricsCommandInvoker.DisposeAsync().ConfigureAwait(false);
188+
}
189+
190+
public async ValueTask DisposeAsync(bool disposing)
191+
{
192+
await this.publishMetricsCommandInvoker.DisposeAsync(disposing).ConfigureAwait(false);
193+
}
194+
}
195+
}
196+
}

0 commit comments

Comments
 (0)