-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathILicenseManagementClient.cs
More file actions
327 lines (279 loc) · 15.5 KB
/
Copy pathILicenseManagementClient.cs
File metadata and controls
327 lines (279 loc) · 15.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
using LicenseManagement.Client.Models;
using LicenseManagement.Client.Requests;
namespace LicenseManagement.Client;
/// <summary>
/// Client interface for the License Management API.
/// </summary>
/// <remarks>
/// All non-success HTTP responses throw <see cref="Exceptions.LicenseManagementException"/>.
/// The exception's <c>StatusCode</c>, <c>ResponseContent</c>, and <c>CorrelationId</c> properties
/// can be used for diagnostics and support escalation.
///
/// On 429 Too Many Requests the API returns a <c>Retry-After</c> header in seconds; callers should
/// configure a Polly retry policy on the registered <see cref="System.Net.Http.HttpClient"/> that
/// honours it. See <see cref="Extensions.ServiceCollectionExtensions"/>.
///
/// Methods that create resources accept an optional idempotency key. Supplying a stable key
/// (stored alongside the operation in the caller's database) ensures that a retried request after
/// a transient failure produces the same result rather than a duplicate.
/// </remarks>
public interface ILicenseManagementClient
{
#region Licenses
/// <summary>
/// Gets a license by product and computer.
/// </summary>
/// <param name="productId">The product ID (ULID with PRD_ prefix).</param>
/// <param name="computerId">The computer ID (ULID with PC_ prefix).</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The license if found.</returns>
/// <exception cref="Exceptions.LicenseManagementException">Thrown when the API returns a non-success status (including 404).</exception>
Task<License?> GetLicenseAsync(string productId, string computerId, CancellationToken cancellationToken = default);
/// <summary>
/// Creates a new trial license.
/// </summary>
/// <param name="request">The license creation request.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The created license.</returns>
Task<License> CreateLicenseAsync(CreateLicenseRequest request, CancellationToken cancellationToken = default);
/// <summary>
/// Creates a new trial license with an idempotency key. Repeated calls with the same key
/// (within the server's idempotency window) replay the original response instead of creating
/// a duplicate.
/// </summary>
Task<License> CreateLicenseAsync(CreateLicenseRequest request, string? idempotencyKey, CancellationToken cancellationToken = default);
/// <summary>
/// Updates a license (attach or detach a receipt).
/// </summary>
/// <param name="request">The license update request.</param>
/// <param name="cancellationToken">Cancellation token.</param>
Task UpdateLicenseAsync(UpdateLicenseRequest request, CancellationToken cancellationToken = default);
#endregion
#region Receipts
/// <summary>
/// Gets a receipt by code.
/// </summary>
/// <param name="code">The receipt code.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The receipt.</returns>
/// <exception cref="Exceptions.LicenseManagementException">Thrown when the API returns a non-success status (including 404).</exception>
Task<Receipt?> GetReceiptAsync(string code, CancellationToken cancellationToken = default);
/// <summary>
/// Creates a new receipt.
/// </summary>
/// <param name="request">The receipt creation request.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The created receipt.</returns>
Task<Receipt> CreateReceiptAsync(CreateReceiptRequest request, CancellationToken cancellationToken = default);
/// <summary>
/// Creates a new receipt with an idempotency key. Repeated calls with the same key replay the
/// original response.
/// </summary>
Task<Receipt> CreateReceiptAsync(CreateReceiptRequest request, string? idempotencyKey, CancellationToken cancellationToken = default);
/// <summary>
/// Updates an existing receipt.
/// </summary>
/// <param name="request">The receipt update request.</param>
/// <param name="cancellationToken">Cancellation token.</param>
Task UpdateReceiptAsync(UpdateReceiptRequest request, CancellationToken cancellationToken = default);
/// <summary>
/// Generates a receipt code for a product and email combination.
/// </summary>
/// <param name="productName">The product name.</param>
/// <param name="email">The buyer's email address.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The generated receipt code.</returns>
Task<string> GenerateReceiptCodeAsync(string productName, string email, CancellationToken cancellationToken = default);
/// <summary>
/// Atomically rotates a receipt's code on the server. The existing receipt is voided and a
/// replacement is inserted inside a single transaction, so a partial failure cannot leave the
/// buyer without seats.
/// </summary>
/// <param name="code">The current receipt code to rotate.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The new receipt code.</returns>
/// <exception cref="Exceptions.LicenseManagementException">Thrown when the receipt is not found or the operation fails.</exception>
Task<string> ResetReceiptCodeAsync(string code, CancellationToken cancellationToken = default);
/// <summary>
/// Gets all receipts for a buyer and product combination.
/// </summary>
/// <param name="buyerEmail">The buyer's email address.</param>
/// <param name="productId">The product ID (ULID with PRD_ prefix).</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>A list of receipts, or empty if none found.</returns>
Task<IEnumerable<Receipt>> GetReceiptsAsync(string buyerEmail, string productId, CancellationToken cancellationToken = default);
#endregion
#region Products
/// <summary>
/// Gets a product by ID.
/// </summary>
/// <param name="productId">The product ID (ULID with PRD_ prefix).</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The product.</returns>
/// <exception cref="Exceptions.LicenseManagementException">Thrown when the API returns a non-success status (including 404).</exception>
Task<Product?> GetProductAsync(string productId, CancellationToken cancellationToken = default);
/// <summary>
/// Gets all products for the vendor.
/// </summary>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>A list of products.</returns>
Task<IEnumerable<Product>> GetProductsAsync(CancellationToken cancellationToken = default);
/// <summary>
/// Creates a new product.
/// </summary>
/// <param name="request">The product creation request.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The created product.</returns>
Task<Product> CreateProductAsync(CreateProductRequest request, CancellationToken cancellationToken = default);
/// <summary>
/// Creates a new product with an idempotency key. Repeated calls with the same key replay the
/// original response.
/// </summary>
Task<Product> CreateProductAsync(CreateProductRequest request, string? idempotencyKey, CancellationToken cancellationToken = default);
#endregion
#region Computers
/// <summary>
/// Gets a computer by device identifier.
/// </summary>
/// <param name="macAddress">The device identifier (typically MAC address or hardware ID).</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The computer.</returns>
/// <exception cref="Exceptions.LicenseManagementException">Thrown when the API returns a non-success status (including 404).</exception>
Task<Computer?> GetComputerAsync(string macAddress, CancellationToken cancellationToken = default);
/// <summary>
/// Registers a new computer.
/// </summary>
/// <param name="request">The computer registration request.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The registered computer.</returns>
Task<Computer> RegisterComputerAsync(RegisterComputerRequest request, CancellationToken cancellationToken = default);
/// <summary>
/// Registers a new computer with an idempotency key. Repeated calls with the same key replay
/// the original response.
/// </summary>
Task<Computer> RegisterComputerAsync(RegisterComputerRequest request, string? idempotencyKey, CancellationToken cancellationToken = default);
/// <summary>
/// Gets all computers registered to a receipt.
/// </summary>
/// <param name="receiptCode">The receipt code.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>A list of computers.</returns>
Task<IEnumerable<Computer>> GetComputersAsync(string receiptCode, CancellationToken cancellationToken = default);
#endregion
#region Signing Keys
/// <summary>
/// Gets the vendor's public signing key.
/// </summary>
/// <param name="format">The key format: "xml" or "pem". Default is "xml".</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The public key in the requested format.</returns>
Task<string> GetPublicKeyAsync(string format = "xml", CancellationToken cancellationToken = default);
#endregion
#region Webhooks
/// <summary>
/// Gets all webhooks for the vendor.
/// </summary>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>A list of webhooks.</returns>
Task<IEnumerable<Webhook>> GetWebhooksAsync(CancellationToken cancellationToken = default);
/// <summary>
/// Gets a webhook by ID. Returns <c>null</c> when the webhook does not exist (404).
/// </summary>
/// <param name="webhookId">The webhook ID (ULID).</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The webhook if found, null otherwise.</returns>
Task<Webhook?> GetWebhookAsync(string webhookId, CancellationToken cancellationToken = default);
/// <summary>
/// Creates a new webhook.
/// </summary>
/// <param name="request">The webhook creation request.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The created webhook including the signing secret.</returns>
Task<WebhookCreated> CreateWebhookAsync(CreateWebhookRequest request, CancellationToken cancellationToken = default);
/// <summary>
/// Creates a new webhook with an idempotency key. Repeated calls with the same key replay the
/// original response.
/// </summary>
Task<WebhookCreated> CreateWebhookAsync(CreateWebhookRequest request, string? idempotencyKey, CancellationToken cancellationToken = default);
/// <summary>
/// Updates a webhook.
/// </summary>
/// <param name="webhookId">The webhook ID (ULID).</param>
/// <param name="request">The webhook update request.</param>
/// <param name="cancellationToken">Cancellation token.</param>
Task UpdateWebhookAsync(string webhookId, UpdateWebhookRequest request, CancellationToken cancellationToken = default);
/// <summary>
/// Deletes a webhook.
/// </summary>
/// <param name="webhookId">The webhook ID (ULID).</param>
/// <param name="cancellationToken">Cancellation token.</param>
Task DeleteWebhookAsync(string webhookId, CancellationToken cancellationToken = default);
/// <summary>
/// Rotates the webhook secret.
/// </summary>
/// <param name="webhookId">The webhook ID (ULID).</param>
/// <param name="immediateRotation">If true, immediately invalidate the old secret.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The new secret information.</returns>
Task<WebhookSecretRotated> RotateWebhookSecretAsync(string webhookId, bool immediateRotation = false, CancellationToken cancellationToken = default);
/// <summary>
/// Completes secret rotation by removing the old secret.
/// </summary>
/// <param name="webhookId">The webhook ID (ULID).</param>
/// <param name="cancellationToken">Cancellation token.</param>
Task CompleteSecretRotationAsync(string webhookId, CancellationToken cancellationToken = default);
/// <summary>
/// Gets webhook delivery history.
/// </summary>
/// <param name="webhookId">The webhook ID (ULID).</param>
/// <param name="limit">Maximum number of deliveries to return (default 50).</param>
/// <param name="offset">Offset for pagination (default 0).</param>
/// <param name="status">Optional status filter (pending, success, failed, retrying, dead_letter).</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>A list of webhook deliveries.</returns>
Task<IEnumerable<WebhookDelivery>> GetWebhookDeliveriesAsync(string webhookId, int limit = 50, int offset = 0, string? status = null, CancellationToken cancellationToken = default);
/// <summary>
/// Gets a specific webhook delivery. Returns <c>null</c> when the delivery does not exist (404).
/// </summary>
/// <param name="webhookId">The webhook ID (ULID).</param>
/// <param name="deliveryId">The delivery ID (ULID).</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The delivery details, or null if not found.</returns>
Task<WebhookDeliveryDetail?> GetWebhookDeliveryAsync(string webhookId, string deliveryId, CancellationToken cancellationToken = default);
/// <summary>
/// Replays a failed webhook delivery.
/// </summary>
/// <param name="webhookId">The webhook ID (ULID).</param>
/// <param name="deliveryId">The delivery ID (ULID).</param>
/// <param name="targetUrl">Optional override URL for the replay.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The replay delivery result.</returns>
Task<WebhookDelivery> ReplayWebhookDeliveryAsync(string webhookId, string deliveryId, string? targetUrl = null, CancellationToken cancellationToken = default);
/// <summary>
/// Gets webhook health status.
/// </summary>
/// <param name="webhookId">The webhook ID (ULID).</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The webhook health status.</returns>
Task<WebhookHealth> GetWebhookHealthAsync(string webhookId, CancellationToken cancellationToken = default);
/// <summary>
/// Gets webhook delivery statistics.
/// </summary>
/// <param name="webhookId">The webhook ID (ULID).</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The webhook statistics.</returns>
Task<WebhookStats> GetWebhookStatsAsync(string webhookId, CancellationToken cancellationToken = default);
/// <summary>
/// Gets available webhook event types.
/// </summary>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The available event types.</returns>
Task<WebhookEventTypes> GetWebhookEventTypesAsync(CancellationToken cancellationToken = default);
/// <summary>
/// Sends a test webhook to the specified endpoint.
/// </summary>
/// <param name="webhookId">The webhook ID (ULID).</param>
/// <param name="cancellationToken">Cancellation token.</param>
Task TestWebhookAsync(string webhookId, CancellationToken cancellationToken = default);
#endregion
}