122 lines
4.0 KiB
C#
Raw Normal View History

2025-04-09 14:33:20 +08:00
using Confluent.Kafka;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Confluent.Kafka.Admin;
using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection;
namespace JiShe.CollectBus.Kafka.AdminClient
{
2025-04-12 15:11:18 +08:00
public class AdminClientService : IAdminClientService, IDisposable,ISingletonDependency
2025-04-09 14:33:20 +08:00
{
private readonly ILogger<AdminClientService> _logger;
/// <summary>
/// Initializes a new instance of the <see cref="AdminClientService"/> class.
/// </summary>
/// <param name="configuration">The configuration.</param>
/// <param name="logger">The logger.</param>
public AdminClientService(IConfiguration configuration, ILogger<AdminClientService> logger)
{
_logger = logger;
GetInstance(configuration);
}
/// <summary>
/// Gets or sets the instance.
/// </summary>
/// <value>
/// The instance.
/// </value>
public IAdminClient Instance { get; set; } = default;
/// <summary>
/// Gets the instance.
/// </summary>
/// <param name="configuration">The configuration.</param>
/// <returns></returns>
public IAdminClient GetInstance(IConfiguration configuration)
{
var enableAuthorization = bool.Parse(configuration["Kafka:EnableAuthorization"]);
var adminClientConfig = new AdminClientConfig()
{
BootstrapServers = configuration["Kafka:BootstrapServers"],
};
if (enableAuthorization)
{
adminClientConfig.SecurityProtocol = SecurityProtocol.SaslPlaintext;
adminClientConfig.SaslMechanism = SaslMechanism.Plain;
adminClientConfig.SaslUsername = configuration["Kafka:SaslUserName"];
adminClientConfig.SaslPassword = configuration["Kafka:SaslPassword"];
}
Instance = new AdminClientBuilder(adminClientConfig).Build();
return Instance;
}
/// <summary>
/// Checks the topic asynchronous.
/// </summary>
/// <param name="topic">The topic.</param>
/// <returns></returns>
public async Task<bool> CheckTopicAsync(string topic)
{
var metadata = Instance.GetMetadata(TimeSpan.FromSeconds(5));
return await Task.FromResult(metadata.Topics.Exists(a => a.Topic == topic));
}
2025-04-12 15:11:18 +08:00
public async Task CreateTopicAsync(string topic, int numPartitions, short replicationFactor)
2025-04-09 14:33:20 +08:00
{
2025-04-14 09:29:12 +08:00
2025-04-09 14:33:20 +08:00
try
{
2025-04-14 09:29:12 +08:00
if (await CheckTopicAsync(topic)) return;
2025-04-10 16:58:32 +08:00
await Instance.CreateTopicsAsync(new[]
2025-04-09 14:33:20 +08:00
{
2025-04-12 15:11:18 +08:00
new TopicSpecification
{
Name = topic,
NumPartitions = numPartitions,
ReplicationFactor = replicationFactor
}
2025-04-09 14:33:20 +08:00
});
}
catch (CreateTopicsException e)
{
2025-04-12 15:11:18 +08:00
if (e.Results[0].Error.Code != ErrorCode.TopicAlreadyExists)
{
throw;
}
2025-04-09 14:33:20 +08:00
}
}
2025-04-12 15:11:18 +08:00
public async Task DeleteTopicAsync(string topic)
2025-04-09 14:33:20 +08:00
{
2025-04-12 15:11:18 +08:00
await Instance.DeleteTopicsAsync(new[] { topic });
}
public async Task<List<string>> ListTopicsAsync()
{
var metadata = Instance.GetMetadata(TimeSpan.FromSeconds(10));
return new List<string>(metadata.Topics.Select(t => t.Topic));
}
public async Task<bool> TopicExistsAsync(string topic)
{
var metadata = Instance.GetMetadata(TimeSpan.FromSeconds(10));
return metadata.Topics.Any(t => t.Topic == topic);
}
public void Dispose()
{
Instance?.Dispose();
2025-04-09 14:33:20 +08:00
}
}
}