|
1 | 1 | using Aspire.Hosting; |
2 | 2 | using Aspire.Hosting.ApplicationModel; |
3 | 3 | using Couchbase.Aspire.Hosting; |
| 4 | +using Couchbase.Aspire.Hosting.Api; |
4 | 5 | using Couchbase.KeyValue; |
5 | 6 | using Couchbase.Management.Buckets; |
6 | 7 | using Microsoft.Extensions.DependencyInjection; |
@@ -207,11 +208,78 @@ public static IResourceBuilder<CouchbaseBucketResource> WithFlushEnabled(this IR |
207 | 208 | { |
208 | 209 | ArgumentNullException.ThrowIfNull(builder); |
209 | 210 |
|
210 | | - return builder.WithSettings(context => |
| 211 | + builder.WithSettings(context => |
211 | 212 | { |
212 | 213 | context.Settings.FlushEnabled = enabled; |
213 | 214 | return Task.CompletedTask; |
214 | 215 | }); |
| 216 | + |
| 217 | + const string flushCommandName = "flush-bucket"; |
| 218 | + if (enabled ?? false) |
| 219 | + { |
| 220 | + // Add a command to flush the bucket |
| 221 | + builder.WithCommand(flushCommandName, "Flush", |
| 222 | + async (context) => |
| 223 | + { |
| 224 | + var apiService = context.ServiceProvider.GetRequiredService<ICouchbaseApiService>(); |
| 225 | + var api = apiService.GetApi(builder.Resource.Parent); |
| 226 | + |
| 227 | + var server = builder.Resource.Parent.GetPrimaryServer(); |
| 228 | + if (server is null) |
| 229 | + { |
| 230 | + return new ExecuteCommandResult |
| 231 | + { |
| 232 | + Success = false, |
| 233 | + ErrorMessage = "No available server to flush the bucket." |
| 234 | + }; |
| 235 | + } |
| 236 | + |
| 237 | + await api.FlushBucketAsync(server, builder.Resource.BucketName, context.CancellationToken).ConfigureAwait(false); |
| 238 | + |
| 239 | + // Wait for bucket to be healthy |
| 240 | + while (true) |
| 241 | + { |
| 242 | + context.CancellationToken.ThrowIfCancellationRequested(); |
| 243 | + |
| 244 | + var bucketInfo = await api.GetBucketAsync(server, builder.Resource.BucketName, context.CancellationToken).ConfigureAwait(false); |
| 245 | + if (bucketInfo?.Nodes?.All(p => p.Status == BucketNode.HealthyStatus) ?? false) |
| 246 | + { |
| 247 | + break; |
| 248 | + } |
| 249 | + |
| 250 | + await Task.Delay(250, context.CancellationToken).ConfigureAwait(false); |
| 251 | + } |
| 252 | + |
| 253 | + return new ExecuteCommandResult { Success = true }; |
| 254 | + }, |
| 255 | + new CommandOptions |
| 256 | + { |
| 257 | + UpdateState = context => |
| 258 | + { |
| 259 | + var state = context.ResourceSnapshot.State?.Text; |
| 260 | + return state == KnownResourceStates.Running |
| 261 | + ? ResourceCommandState.Enabled |
| 262 | + : ResourceCommandState.Hidden; |
| 263 | + }, |
| 264 | + IconName = "DeleteLines", |
| 265 | + IsHighlighted = true, |
| 266 | + ConfirmationMessage = $"Flushing bucket '{builder.Resource.BucketName}', are you sure?", |
| 267 | + }); |
| 268 | + } |
| 269 | + else |
| 270 | + { |
| 271 | + // Remove the command if it was previously added |
| 272 | + var existingCommand = builder.Resource.Annotations |
| 273 | + .OfType<ResourceCommandAnnotation>() |
| 274 | + .FirstOrDefault(p => p.Name == flushCommandName); |
| 275 | + |
| 276 | + if (existingCommand is not null) |
| 277 | + { |
| 278 | + builder.Resource.Annotations.Remove(existingCommand); |
| 279 | + } |
| 280 | + } |
| 281 | + |
| 282 | + return builder; |
215 | 283 | } |
216 | 284 |
|
217 | 285 | /// <summary> |
|
0 commit comments