Browse Source

feat: 添加网络配置复制和接口管理功能

master
root 3 days ago
parent
commit
2de5279712
  1. 19
      CoreAgent.Domain/Interfaces/Network/INetworkConfigCopier.cs
  2. 31
      CoreAgent.Domain/Interfaces/Network/INetworkInterfaceManager.cs
  3. 34
      CoreAgent.Domain/Models/Network/NetworkConfigCopyResult.cs
  4. 34
      CoreAgent.Domain/Models/Network/NetworkInterfaceOperationResult.cs
  5. 3
      CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs
  6. 452
      CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs
  7. 180
      CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs
  8. 312
      CoreAgent.Infrastructure/Services/Network/NetworkInterfaceManager.cs

19
CoreAgent.Domain/Interfaces/Network/INetworkConfigCopier.cs

@ -0,0 +1,19 @@
using CoreAgent.Domain.Entities;
using CoreAgent.Domain.Models.Network;
using CoreAgent.Domain.Models.System;
namespace CoreAgent.Domain.Interfaces.Network;
/// <summary>
/// 网络配置复制器接口
/// </summary>
public interface INetworkConfigCopier
{
/// <summary>
/// 将配置值复制到临时目录并更新配置路径
/// </summary>
/// <param name="networkConfig">网络配置</param>
/// <param name="appSettings">应用设置</param>
/// <returns>复制结果</returns>
Task<NetworkConfigCopyResult> CopyConfigValuesToTempAsync(NetworkConfiguration networkConfig, AppSettings appSettings);
}

31
CoreAgent.Domain/Interfaces/Network/INetworkInterfaceManager.cs

@ -0,0 +1,31 @@
using CoreAgent.Domain.Entities;
using CoreAgent.Domain.Models.Network;
namespace CoreAgent.Domain.Interfaces.Network;
/// <summary>
/// 网络接口管理器接口
/// </summary>
public interface INetworkInterfaceManager
{
/// <summary>
/// 执行初始化命令
/// </summary>
/// <param name="isStartup">是否为启动时的初始化</param>
/// <returns>初始化结果</returns>
Task<NetworkInterfaceOperationResult> ExecuteInitializeCommandsAsync(bool isStartup = false);
/// <summary>
/// 启用网络接口
/// </summary>
/// <param name="networkConfig">网络配置</param>
/// <returns>启用结果</returns>
Task<NetworkInterfaceOperationResult> EnableAsync(NetworkConfiguration networkConfig);
/// <summary>
/// 禁用网络接口
/// </summary>
/// <param name="neConfigKey">网络配置键</param>
/// <returns>禁用结果</returns>
Task<NetworkInterfaceOperationResult> DisableAsync(string neConfigKey);
}

34
CoreAgent.Domain/Models/Network/NetworkConfigCopyResult.cs

@ -0,0 +1,34 @@
namespace CoreAgent.Domain.Models.Network;
/// <summary>
/// 网络配置复制结果
/// </summary>
public class NetworkConfigCopyResult
{
/// <summary>
/// 是否成功
/// </summary>
public bool IsSuccess { get; }
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMessage { get; }
private NetworkConfigCopyResult(bool isSuccess, string errorMessage = null)
{
IsSuccess = isSuccess;
ErrorMessage = errorMessage;
}
/// <summary>
/// 创建成功结果
/// </summary>
public static NetworkConfigCopyResult Success() => new(true);
/// <summary>
/// 创建失败结果
/// </summary>
/// <param name="errorMessage">错误信息</param>
public static NetworkConfigCopyResult Failure(string errorMessage) => new(false, errorMessage);
}

34
CoreAgent.Domain/Models/Network/NetworkInterfaceOperationResult.cs

@ -0,0 +1,34 @@
namespace CoreAgent.Domain.Models.Network;
/// <summary>
/// 网络接口操作结果
/// </summary>
public class NetworkInterfaceOperationResult
{
/// <summary>
/// 是否成功
/// </summary>
public bool IsSuccess { get; }
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMessage { get; }
private NetworkInterfaceOperationResult(bool isSuccess, string errorMessage = null)
{
IsSuccess = isSuccess;
ErrorMessage = errorMessage;
}
/// <summary>
/// 创建成功结果
/// </summary>
public static NetworkInterfaceOperationResult Success() => new(true);
/// <summary>
/// 创建失败结果
/// </summary>
/// <param name="errorMessage">错误信息</param>
public static NetworkInterfaceOperationResult Failure(string errorMessage) => new(false, errorMessage);
}

3
CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs

@ -36,7 +36,8 @@ public static class CommandServiceExtensions
services.AddScoped<INetworkConfigurationRepository, NetworkConfigurationRepository>();
// 注册网络配置器
services.AddScoped<INetworkConfigurationService, NetworkConfigurationService>();
services.AddScoped<INetworkConfigCopier, NetworkConfigCopier>();
services.AddScoped<INetworkInterfaceManager, NetworkInterfaceManager>();
// 注册网络服务
services.AddScoped<ICellularNetworkService, CellularNetworkService>();

452
CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs

@ -21,23 +21,30 @@ public class CellularNetworkService : ICellularNetworkService
private readonly ISystemCommandExecutor _commandExecutor;
private readonly INetworkConfigurationService _configService;
private readonly ICellularNetworkContext _context;
private readonly INetworkConfigCopier _configCopier;
private readonly INetworkInterfaceManager _interfaceManager;
private static readonly SemaphoreSlim _startLock = new(1, 1);
private const int MaxConnectionAttempts = 30;
private const int ConnectionCheckDelayMs = 1000;
private const int LockTimeoutSeconds = 5;
private const string NULL_CONFIG = "NULL";
private const string KILL_COMMAND_TEMPLATE = "ps -ef | grep {0} | grep -v grep | awk '{{print $2}}' | xargs kill -9";
private const string COM_ADDR_TEMPLATE = "cat {0} | grep com_addr | awk -F'\"' '{{print $4}}'";
public CellularNetworkService(
ILogger<CellularNetworkService> logger,
ISystemCommandExecutor commandExecutor,
INetworkConfigurationService configService,
ICellularNetworkContext context)
ICellularNetworkContext context,
INetworkConfigCopier configCopier,
INetworkInterfaceManager interfaceManager)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor));
_configService = configService ?? throw new ArgumentNullException(nameof(configService));
_context = context ?? throw new ArgumentNullException(nameof(context));
_configCopier = configCopier ?? throw new ArgumentNullException(nameof(configCopier));
_interfaceManager = interfaceManager ?? throw new ArgumentNullException(nameof(interfaceManager));
}
/// <summary>
@ -163,30 +170,16 @@ public class CellularNetworkService : ICellularNetworkService
}
// 2. 执行初始化命令
await ExecuteInitializeCommandsAsync();
// 3. 执行停止命令
_logger.LogInformation("正在执行停止命令: {ConfigKey}", neConfigKey);
var commands = _context.GetNetworkCommandConfig();
if (commands?.NetworkCommands != null)
{
var stopCommands = commands.NetworkCommands
.Where(s => s.Type == NetworkCommandType.StopNetwork)
.ToArray();
foreach (var cmd in stopCommands)
{
if (!await ExecuteCommandAsync(cmd))
var initResult = await _interfaceManager.ExecuteInitializeCommandsAsync();
if (!initResult.IsSuccess)
{
_logger.LogWarning("停止命令执行失败: {Template}", cmd.Template);
_logger.LogWarning("执行初始化命令失败: {ErrorMessage}", initResult.ErrorMessage);
}
}
}
// 4. 停止网络配置
if (!await DisableNetworkInterfaceAsync(neConfigKey))
var disableResult = await _interfaceManager.DisableAsync(neConfigKey);
if (!disableResult.IsSuccess)
{
return CellularNetworkOperationResult.Failure("停止网络配置失败");
return CellularNetworkOperationResult.Failure(disableResult.ErrorMessage);
}
// 5. 更新状态
@ -215,414 +208,35 @@ public class CellularNetworkService : ICellularNetworkService
}
// 2. 执行初始化命令
await ExecuteInitializeCommandsAsync(true);
var initResult = await _interfaceManager.ExecuteInitializeCommandsAsync(true);
if (!initResult.IsSuccess)
{
_logger.LogWarning("执行初始化命令失败: {ErrorMessage}", initResult.ErrorMessage);
}
// 3. 复制配置值到临时目录并更新配置路径
var copyResult = await _configCopier.CopyConfigValuesToTempAsync(config, _context.GetAppSettings());
if (!copyResult.IsSuccess)
{
var message = $"复制配置值到临时目录失败: {copyResult.ErrorMessage}";
_logger.LogError(message);
return CellularNetworkOperationResult.Failure(message);
}
// 3. 启动网络配置
// 4. 启动网络配置
_logger.LogInformation("正在启动蜂窝网络配置: {ConfigKey}", key);
if (!await EnableNetworkInterfaceAsync(config))
var enableResult = await _interfaceManager.EnableAsync(config);
if (!enableResult.IsSuccess)
{
var message = $"启动网络配置失败: {key}";
var message = $"启动网络配置失败: {enableResult.ErrorMessage}";
_logger.LogError(message);
return CellularNetworkOperationResult.Failure(message);
}
// 4. 更新状态
// 5. 更新状态
var state = _context.GetNetworkState();
state.MarkAsStarted();
_logger.LogInformation("蜂窝网络配置 {ConfigKey} 启动成功", key);
return CellularNetworkOperationResult.Success(state.CurrentStatus);
}
private async Task ExecuteInitializeCommandsAsync(bool bStartInit = false)
{
var commands = _context.GetNetworkCommandConfig();
if (commands?.NetworkCommands != null)
{
var initCommands = commands.NetworkCommands
.Where(s => s.Type == NetworkCommandType.Initialize ||
(bStartInit && s.Type == NetworkCommandType.PreNetworkOperation))
.ToArray();
foreach (var cmd in initCommands)
{
if (!await ExecuteCommandAsync(cmd))
{
_logger.LogWarning("初始化命令执行失败: {Template}", cmd.Template);
}
}
}
}
private async Task<bool> ExecuteCommandAsync(CommandTemplateConfig command)
{
try
{
if (command.CanBeKilled)
{
return await KillProcessAsync(command.Template, command.Timeout);
}
var result = await _commandExecutor.ExecuteCommandAsync(command.Template, new CancellationTokenSource(),command.Timeout);
return result.IsSuccess;
}
catch (Exception ex)
{
_logger.LogError(ex, "执行命令失败: {Template}", command.Template);
return false;
}
}
private async Task<bool> KillProcessAsync(string template,int Timeout)
{
string killCmd = string.Format(KILL_COMMAND_TEMPLATE, template);
var result = await _commandExecutor.ExecuteCommandAsync(killCmd, new CancellationTokenSource());
_logger.LogInformation("已终止进程: {Template}", template);
return result.IsSuccess;
}
private async Task<bool> EnableNetworkInterfaceAsync(NetworkConfiguration networkConfig)
{
try
{
// 验证配置
if (!ValidateConfig(networkConfig))
{
_logger.LogError("网络配置验证失败");
return false;
}
// 复制配置值到临时目录并更新配置路径
if (!CopyConfigValuesToTempAsync(networkConfig))
{
_logger.LogError("复制配置值到临时目录失败");
return false;
}
var commands = _context.GetNetworkCommandConfig();
var startCommand = commands.NetworkCommands.FirstOrDefault(s => s.Type == NetworkCommandType.NetworkOperation);
if (startCommand == null)
{
_logger.LogError("未找到启动命令配置");
return false;
}
// 根据配置类型执行不同的启动命令
if (HasBothRagAndCoreConfigs(networkConfig))
{
return await ExecuteFullConfigStartCommandAsync(startCommand, networkConfig);
}
else if (HasOnlyRagConfig(networkConfig))
{
return await ExecuteRagOnlyStartCommandAsync(startCommand, networkConfig);
}
else if (HasOnlyCoreConfigs(networkConfig))
{
return await ExecuteCoreOnlyStartCommandsAsync(startCommand, networkConfig);
}
_logger.LogWarning("无有效配置,跳过启动");
return false;
}
catch (Exception ex)
{
_logger.LogError(ex, "启动网络接口失败");
return false;
}
}
/// <summary>
/// 将配置值复制到临时目录并更新配置路径
/// </summary>
private bool CopyConfigValuesToTempAsync(NetworkConfiguration networkConfig)
{
try
{
// 确保所需目录存在
EnsureDirectoriesExist();
// 复制 RAG 配置文件
if (!string.IsNullOrEmpty(networkConfig.RagConfig))
{
if (!CopyConfigFile(networkConfig.RagConfig, _context.GetAppSettings().RanConfigDirectory,
path => networkConfig.RagConfig = path, "RAG"))
{
return false;
}
}
// 复制核心网络配置文件和IMS配置文件
foreach (var config in networkConfig.CoreOrImsConfigs)
{
if (!string.IsNullOrEmpty(config.CoreNetworkConfig))
{
if (!CopyConfigFile(config.CoreNetworkConfig, _context.GetAppSettings().MmeConfigDirectory,
path => config.CoreNetworkConfig = path, "核心网络"))
{
return false;
}
}
if (!string.IsNullOrEmpty(config.ImsConfig))
{
if (!CopyConfigFile(config.ImsConfig, _context.GetAppSettings().MmeConfigDirectory,
path => config.ImsConfig = path, "IMS"))
{
return false;
}
}
}
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "复制配置文件到临时目录时发生错误");
return false;
}
}
private void EnsureDirectoriesExist()
{
var appSettings = _context.GetAppSettings();
if (!Directory.Exists(appSettings.TempDirectory))
{
Directory.CreateDirectory(appSettings.TempDirectory);
}
if (!Directory.Exists(appSettings.RanConfigDirectory))
{
Directory.CreateDirectory(appSettings.RanConfigDirectory);
}
if (!Directory.Exists(appSettings.MmeConfigDirectory))
{
Directory.CreateDirectory(appSettings.MmeConfigDirectory);
}
}
private bool CopyConfigFile(string sourcePath, string targetDirectory, Action<string> updatePath, string configType)
{
var appSettings = _context.GetAppSettings();
if (!File.Exists(sourcePath))
{
_logger.LogError("{ConfigType}配置文件不存在: {FilePath}", configType, sourcePath);
return false;
}
var fileName = Path.GetFileName(sourcePath);
var tempPath = Path.Combine(appSettings.TempDirectory, fileName);
// 始终复制到临时目录
File.Copy(sourcePath, tempPath, true);
// 如果不在目标目录下,则复制到该目录并更新路径
if (!sourcePath.StartsWith(targetDirectory))
{
var targetPath = Path.Combine(targetDirectory, fileName);
File.Copy(sourcePath, targetPath, true);
updatePath(targetPath);
_logger.LogInformation("{ConfigType}配置文件已复制到目标目录: {FilePath}", configType, targetPath);
}
else
{
_logger.LogInformation("{ConfigType}配置文件已在目标目录中: {FilePath}", configType, sourcePath);
}
return true;
}
private bool HasBothRagAndCoreConfigs(NetworkConfiguration config)
{
return !string.IsNullOrWhiteSpace(config.RagConfig) && config.CoreOrImsConfigs.Any();
}
private bool HasOnlyRagConfig(NetworkConfiguration config)
{
return !string.IsNullOrWhiteSpace(config.RagConfig) && !config.CoreOrImsConfigs.Any();
}
private bool HasOnlyCoreConfigs(NetworkConfiguration config)
{
return string.IsNullOrWhiteSpace(config.RagConfig) && config.CoreOrImsConfigs.Any();
}
private async Task<bool> ExecuteFullConfigStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
if (networkConfig.CoreOrImsConfigs.Count == 1)
{
return await ExecuteSingleConfigStartCommandAsync(startCommand, networkConfig);
}
return await ExecuteMultiConfigStartCommandsAsync(startCommand, networkConfig);
}
private async Task<bool> ExecuteRagOnlyStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
var command = string.Format(startCommand.Template, 1);
var fullCommand = $"{command} {networkConfig.RagConfig}";
_logger.LogInformation("执行RAG配置启动命令: {Command}", fullCommand);
var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, new CancellationTokenSource());
return result.IsSuccess;
}
private async Task<bool> ExecuteCoreOnlyStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
var commands = new List<string>();
var secondaryConfigs = networkConfig.CoreOrImsConfigs.ToArray();
var secondaryTasks = new List<Task<CommandExecutionResult>>();
for (int i = 0; i < secondaryConfigs.Length; i++)
{
var config = secondaryConfigs[i];
var command = string.Format(startCommand.Template, i + 1);
var fullCommand = $"{command} {NULL_CONFIG} {config.CoreNetworkConfig} {config.ImsConfig}";
_logger.LogInformation("并发执行次要配置启动命令: {Command}", fullCommand);
secondaryTasks.Add(_commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource));
}
// 等待所有次要配置命令执行完成
var secondaryResults = await Task.WhenAll(secondaryTasks);
if (secondaryResults.Any(r => !r.IsSuccess))
{
_logger.LogWarning("部分次要配置命令执行失败");
return false;
}
return true;
}
private async Task<bool> ExecuteSingleConfigStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
var config = networkConfig.CoreOrImsConfigs.First();
var command = string.Format(startCommand.Template, 1);
var fullCommand = $"{command} {networkConfig.RagConfig} {config.CoreNetworkConfig} {config.ImsConfig}";
_logger.LogInformation("执行单配置启动命令: {Command}", fullCommand);
var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource);
return result.IsSuccess;
}
private async Task<bool> ExecuteMultiConfigStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
var commands = new List<string>();
// 添加次要配置命令
var secondaryConfigs = networkConfig.CoreOrImsConfigs.Where(s => s.Index != 1).ToArray();
var secondaryTasks = new List<Task<CommandExecutionResult>>();
for (int i = 0; i < secondaryConfigs.Length; i++)
{
var config = secondaryConfigs[i];
var command = string.Format(startCommand.Template, i + 2);
var fullCommand = $"{command} NULL {config.CoreNetworkConfig} {config.ImsConfig}";
_logger.LogInformation("并发执行次要配置启动命令: {Command}", fullCommand);
secondaryTasks.Add(_commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource));
}
// 等待所有次要配置命令执行完成
var secondaryResults = await Task.WhenAll(secondaryTasks);
if (secondaryResults.Any(r => !r.IsSuccess))
{
_logger.LogWarning("部分次要配置命令执行失败");
return false;
}
// 执行主配置命令
var primaryConfig = networkConfig.CoreOrImsConfigs.FirstOrDefault(s => s.Index == 1);
if (primaryConfig != null)
{
var primaryCommand = string.Format(startCommand.Template, 1);
var fullCommand = $"{primaryCommand} {networkConfig.RagConfig} {primaryConfig.CoreNetworkConfig} {primaryConfig.ImsConfig}";
_logger.LogInformation("执行主配置启动命令: {Command}", fullCommand);
var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource);
if (!result.IsSuccess)
{
_logger.LogWarning("主配置命令执行失败: {Command}", fullCommand);
return false;
}
}
return true;
}
private async Task<bool> DisableNetworkInterfaceAsync(string neConfigKey)
{
var result = await _commandExecutor.ExecuteCommandAsync(
$"netsh interface cellular set interface \"{neConfigKey}\" admin=disable",
new CancellationTokenSource());
if (!result.IsSuccess)
{
_logger.LogError("停止网络配置失败");
return false;
}
return true;
}
private async Task<bool> WaitForConnectionAsync(string neConfigKey)
{
for (int i = 0; i < MaxConnectionAttempts; i++)
{
var status = await _commandExecutor.ExecuteCommandAsync(
$"netsh interface cellular show interfaces \"{neConfigKey}\"",
new CancellationTokenSource());
if (status.IsSuccess && status.Output.Contains("已连接", StringComparison.OrdinalIgnoreCase))
{
return true;
}
await Task.Delay(ConnectionCheckDelayMs);
}
_logger.LogError("蜂窝网络连接超时");
return false;
}
/// <summary>
/// 验证网络配置是否有效
/// </summary>
private bool ValidateConfig(NetworkConfiguration config)
{
if (config == null)
{
_logger.LogError("网络配置为空");
return false;
}
// 验证RAG配置
if (!string.IsNullOrEmpty(config.RagConfig) && !File.Exists(config.RagConfig))
{
_logger.LogError("RAG配置文件不存在: {FilePath}", config.RagConfig);
return false;
}
// 验证核心网络和IMS配置
if (config.CoreOrImsConfigs != null)
{
foreach (var coreConfig in config.CoreOrImsConfigs)
{
if (!string.IsNullOrEmpty(coreConfig.CoreNetworkConfig) && !File.Exists(coreConfig.CoreNetworkConfig))
{
_logger.LogError("核心网络配置文件不存在: {FilePath}", coreConfig.CoreNetworkConfig);
return false;
}
if (!string.IsNullOrEmpty(coreConfig.ImsConfig) && !File.Exists(coreConfig.ImsConfig))
{
_logger.LogError("IMS配置文件不存在: {FilePath}", coreConfig.ImsConfig);
return false;
}
}
}
// 验证至少有一个有效配置
if (string.IsNullOrEmpty(config.RagConfig) && (config.CoreOrImsConfigs == null || !config.CoreOrImsConfigs.Any()))
{
_logger.LogError("没有有效的网络配置");
return false;
}
return true;
}
}

180
CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs

@ -0,0 +1,180 @@
using CoreAgent.Domain.Entities;
using CoreAgent.Domain.Interfaces;
using CoreAgent.Domain.Interfaces.Network;
using CoreAgent.Domain.Interfaces.System.Command;
using CoreAgent.Domain.Models.Network;
using CoreAgent.Domain.Models.System;
using Microsoft.Extensions.Logging;
namespace CoreAgent.Infrastructure.Services.Network;
/// <summary>
/// 网络配置复制器实现
/// </summary>
public class NetworkConfigCopier : INetworkConfigCopier
{
private readonly ILogger<NetworkConfigCopier> _logger;
private readonly ISystemCommandExecutor _commandExecutor;
private const string COM_ADDR_TEMPLATE = "cat {0} | grep com_addr | awk -F'\"' '{{print $4}}'";
public NetworkConfigCopier(
ILogger<NetworkConfigCopier> logger,
ISystemCommandExecutor commandExecutor)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor));
}
/// <summary>
/// 将配置值复制到临时目录并更新配置路径
/// </summary>
public async Task<NetworkConfigCopyResult> CopyConfigValuesToTempAsync(NetworkConfiguration networkConfig, AppSettings appSettings)
{
try
{
// 确保所需目录存在
EnsureDirectoriesExist(appSettings);
// 复制 RAG 配置文件
if (!string.IsNullOrEmpty(networkConfig.RagConfig))
{
// 获取com_addr值
var (isSuccess, comAddr, errorMessage) = await GetComAddrValueAsync(networkConfig.RagConfig, "RAG");
if (!isSuccess)
{
return NetworkConfigCopyResult.Failure($"RAG配置文件验证失败: {errorMessage}");
}
if (!CopyConfigFile(networkConfig.RagConfig, appSettings.RanConfigDirectory,
path => networkConfig.RagConfig = path, "RAG"))
{
return NetworkConfigCopyResult.Failure("复制RAG配置文件失败");
}
}
// 复制核心网络配置文件和IMS配置文件
foreach (var config in networkConfig.CoreOrImsConfigs)
{
if (!string.IsNullOrEmpty(config.CoreNetworkConfig))
{
// 获取CN com_addr值
var (isSuccess, comAddr, errorMessage) = await GetComAddrValueAsync(config.CoreNetworkConfig, "CN");
if (!isSuccess)
{
return NetworkConfigCopyResult.Failure($"CN配置文件验证失败: {errorMessage}");
}
if (!CopyConfigFile(config.CoreNetworkConfig, appSettings.MmeConfigDirectory,
path => config.CoreNetworkConfig = path, "核心网络"))
{
return NetworkConfigCopyResult.Failure("复制CN配置文件失败");
}
}
if (!string.IsNullOrEmpty(config.ImsConfig))
{
// 获取IMS com_addr值
var (isSuccess, comAddr, errorMessage) = await GetComAddrValueAsync(config.ImsConfig, "IMS");
if (!isSuccess)
{
return NetworkConfigCopyResult.Failure($"IMS配置文件验证失败: {errorMessage}");
}
if (!CopyConfigFile(config.ImsConfig, appSettings.MmeConfigDirectory,
path => config.ImsConfig = path, "IMS"))
{
return NetworkConfigCopyResult.Failure("复制IMS配置文件失败");
}
}
}
return NetworkConfigCopyResult.Success();
}
catch (Exception ex)
{
_logger.LogError(ex, "复制配置文件到临时目录时发生错误");
return NetworkConfigCopyResult.Failure($"复制配置文件时发生错误: {ex.Message}");
}
}
/// <summary>
/// 获取配置文件中的com_addr值
/// </summary>
private async Task<(bool IsSuccess, string ComAddr, string ErrorMessage)> GetComAddrValueAsync(string configPath, string configType)
{
if (string.IsNullOrEmpty(configPath))
{
return (false, null, $"{configType}配置文件路径为空");
}
if (!File.Exists(configPath))
{
return (false, null, $"{configType}配置文件不存在: {configPath}");
}
var result = await _commandExecutor.ExecuteCommandAsync(
string.Format(COM_ADDR_TEMPLATE, configPath),
new CancellationTokenSource());
if (result.IsSuccess)
{
var comAddr = result.Output.Trim();
if (string.IsNullOrEmpty(comAddr))
{
return (false, null, $"{configType}配置文件中未找到com_addr值");
}
_logger.LogInformation("获取到{ConfigType} com_addr值: {ComAddr}", configType, comAddr);
return (true, comAddr, null);
}
else
{
return (false, null, $"获取{configType} com_addr值失败: {result.Error}");
}
}
private void EnsureDirectoriesExist(AppSettings appSettings)
{
if (!Directory.Exists(appSettings.TempDirectory))
{
Directory.CreateDirectory(appSettings.TempDirectory);
}
if (!Directory.Exists(appSettings.RanConfigDirectory))
{
Directory.CreateDirectory(appSettings.RanConfigDirectory);
}
if (!Directory.Exists(appSettings.MmeConfigDirectory))
{
Directory.CreateDirectory(appSettings.MmeConfigDirectory);
}
}
private bool CopyConfigFile(string sourcePath, string targetDirectory, Action<string> updatePath, string configType)
{
if (!File.Exists(sourcePath))
{
_logger.LogError("{ConfigType}配置文件不存在: {FilePath}", configType, sourcePath);
return false;
}
var fileName = Path.GetFileName(sourcePath);
var tempPath = Path.Combine(targetDirectory, fileName);
// 始终复制到临时目录
File.Copy(sourcePath, tempPath, true);
// 如果不在目标目录下,则复制到该目录并更新路径
if (!sourcePath.StartsWith(targetDirectory))
{
var targetPath = Path.Combine(targetDirectory, fileName);
File.Copy(sourcePath, targetPath, true);
updatePath(targetPath);
_logger.LogInformation("{ConfigType}配置文件已复制到目标目录: {FilePath}", configType, targetPath);
}
else
{
_logger.LogInformation("{ConfigType}配置文件已在目标目录中: {FilePath}", configType, sourcePath);
}
return true;
}
}

312
CoreAgent.Infrastructure/Services/Network/NetworkInterfaceManager.cs

@ -0,0 +1,312 @@
using CoreAgent.Domain.Entities;
using CoreAgent.Domain.Interfaces.Network;
using CoreAgent.Domain.Interfaces.System.Command;
using CoreAgent.Domain.Models.Network;
using CoreAgent.Domain.Models.System;
using Microsoft.Extensions.Logging;
namespace CoreAgent.Infrastructure.Services.Network;
/// <summary>
/// 网络接口管理器实现
/// </summary>
public class NetworkInterfaceManager : INetworkInterfaceManager
{
private readonly ILogger<NetworkInterfaceManager> _logger;
private readonly ISystemCommandExecutor _commandExecutor;
private readonly ICellularNetworkContext _context;
private const string NULL_CONFIG = "NULL";
private const string KILL_COMMAND_TEMPLATE = "ps -ef | grep {0} | grep -v grep | awk '{{print $2}}' | xargs kill -9";
public NetworkInterfaceManager(
ILogger<NetworkInterfaceManager> logger,
ISystemCommandExecutor commandExecutor,
ICellularNetworkContext context)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor));
_context = context ?? throw new ArgumentNullException(nameof(context));
}
/// <summary>
/// 执行初始化命令
/// </summary>
public async Task<NetworkInterfaceOperationResult> ExecuteInitializeCommandsAsync(bool isStartup = false)
{
try
{
var commands = _context.GetNetworkCommandConfig();
if (commands?.NetworkCommands != null)
{
var initCommands = commands.NetworkCommands
.Where(s => s.Type == NetworkCommandType.Initialize ||
(isStartup && s.Type == NetworkCommandType.PreNetworkOperation))
.ToArray();
foreach (var cmd in initCommands)
{
if (!await ExecuteCommandAsync(cmd))
{
_logger.LogWarning("初始化命令执行失败: {Template}", cmd.Template);
}
}
}
return NetworkInterfaceOperationResult.Success();
}
catch (Exception ex)
{
_logger.LogError(ex, "执行初始化命令失败");
return NetworkInterfaceOperationResult.Failure($"执行初始化命令失败: {ex.Message}");
}
}
/// <summary>
/// 启用网络接口
/// </summary>
public async Task<NetworkInterfaceOperationResult> EnableAsync(NetworkConfiguration networkConfig)
{
try
{
// 验证配置
if (!ValidateConfig(networkConfig))
{
return NetworkInterfaceOperationResult.Failure("网络配置验证失败");
}
var commands = _context.GetNetworkCommandConfig();
var startCommand = commands.NetworkCommands.FirstOrDefault(s => s.Type == NetworkCommandType.NetworkOperation);
if (startCommand == null)
{
return NetworkInterfaceOperationResult.Failure("未找到启动命令配置");
}
// 根据配置类型执行不同的启动命令
if (HasBothRagAndCoreConfigs(networkConfig))
{
return await ExecuteFullConfigStartCommandAsync(startCommand, networkConfig);
}
else if (HasOnlyRagConfig(networkConfig))
{
return await ExecuteRagOnlyStartCommandAsync(startCommand, networkConfig);
}
else if (HasOnlyCoreConfigs(networkConfig))
{
return await ExecuteCoreOnlyStartCommandsAsync(startCommand, networkConfig);
}
return NetworkInterfaceOperationResult.Failure("无有效配置,跳过启动");
}
catch (Exception ex)
{
_logger.LogError(ex, "启动网络接口失败");
return NetworkInterfaceOperationResult.Failure($"启动网络接口失败: {ex.Message}");
}
}
/// <summary>
/// 禁用网络接口
/// </summary>
public async Task<NetworkInterfaceOperationResult> DisableAsync(string neConfigKey)
{
try
{
await Task.CompletedTask.ConfigureAwait(false);
return NetworkInterfaceOperationResult.Success();
}
catch (Exception ex)
{
_logger.LogError(ex, "停止网络配置失败");
return NetworkInterfaceOperationResult.Failure($"停止网络配置失败: {ex.Message}");
}
}
private async Task<bool> ExecuteCommandAsync(CommandTemplateConfig command)
{
try
{
if (command.CanBeKilled)
{
return await KillProcessAsync(command.Template, command.Timeout);
}
var result = await _commandExecutor.ExecuteCommandAsync(command.Template, new CancellationTokenSource(), command.Timeout);
return result.IsSuccess;
}
catch (Exception ex)
{
_logger.LogError(ex, "执行命令失败: {Template}", command.Template);
return false;
}
}
private async Task<bool> KillProcessAsync(string template, int timeout)
{
string killCmd = string.Format(KILL_COMMAND_TEMPLATE, template);
var result = await _commandExecutor.ExecuteCommandAsync(killCmd, new CancellationTokenSource());
_logger.LogInformation("已终止进程: {Template}", template);
return result.IsSuccess;
}
/// <summary>
/// 验证网络配置是否有效
/// </summary>
private bool ValidateConfig(NetworkConfiguration config)
{
if (config == null)
{
_logger.LogError("网络配置为空");
return false;
}
// 验证RAG配置
if (!string.IsNullOrEmpty(config.RagConfig) && !File.Exists(config.RagConfig))
{
_logger.LogError("RAG配置文件不存在: {FilePath}", config.RagConfig);
return false;
}
// 验证核心网络和IMS配置
if (config.CoreOrImsConfigs != null)
{
foreach (var coreConfig in config.CoreOrImsConfigs)
{
if (!string.IsNullOrEmpty(coreConfig.CoreNetworkConfig) && !File.Exists(coreConfig.CoreNetworkConfig))
{
_logger.LogError("核心网络配置文件不存在: {FilePath}", coreConfig.CoreNetworkConfig);
return false;
}
if (!string.IsNullOrEmpty(coreConfig.ImsConfig) && !File.Exists(coreConfig.ImsConfig))
{
_logger.LogError("IMS配置文件不存在: {FilePath}", coreConfig.ImsConfig);
return false;
}
}
}
// 验证至少有一个有效配置
if (string.IsNullOrEmpty(config.RagConfig) && (config.CoreOrImsConfigs == null || !config.CoreOrImsConfigs.Any()))
{
_logger.LogError("没有有效的网络配置");
return false;
}
return true;
}
private bool HasBothRagAndCoreConfigs(NetworkConfiguration config)
{
return !string.IsNullOrWhiteSpace(config.RagConfig) && config.CoreOrImsConfigs.Any();
}
private bool HasOnlyRagConfig(NetworkConfiguration config)
{
return !string.IsNullOrWhiteSpace(config.RagConfig) && !config.CoreOrImsConfigs.Any();
}
private bool HasOnlyCoreConfigs(NetworkConfiguration config)
{
return string.IsNullOrWhiteSpace(config.RagConfig) && config.CoreOrImsConfigs.Any();
}
private async Task<NetworkInterfaceOperationResult> ExecuteFullConfigStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
if (networkConfig.CoreOrImsConfigs.Count == 1)
{
return await ExecuteSingleConfigStartCommandAsync(startCommand, networkConfig);
}
return await ExecuteMultiConfigStartCommandsAsync(startCommand, networkConfig);
}
private async Task<NetworkInterfaceOperationResult> ExecuteRagOnlyStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
var command = string.Format(startCommand.Template, 1);
var fullCommand = $"{command} {networkConfig.RagConfig}";
_logger.LogInformation("执行RAG配置启动命令: {Command}", fullCommand);
var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, new CancellationTokenSource());
return result.IsSuccess
? NetworkInterfaceOperationResult.Success()
: NetworkInterfaceOperationResult.Failure($"执行RAG配置启动命令失败: {result.Error}");
}
private async Task<NetworkInterfaceOperationResult> ExecuteCoreOnlyStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
var commands = new List<string>();
var secondaryConfigs = networkConfig.CoreOrImsConfigs.ToArray();
var secondaryTasks = new List<Task<CommandExecutionResult>>();
for (int i = 0; i < secondaryConfigs.Length; i++)
{
var config = secondaryConfigs[i];
var command = string.Format(startCommand.Template, i + 1);
var fullCommand = $"{command} {NULL_CONFIG} {config.CoreNetworkConfig} {config.ImsConfig}";
_logger.LogInformation("并发执行次要配置启动命令: {Command}", fullCommand);
secondaryTasks.Add(_commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource));
}
// 等待所有次要配置命令执行完成
var secondaryResults = await Task.WhenAll(secondaryTasks);
if (secondaryResults.Any(r => !r.IsSuccess))
{
return NetworkInterfaceOperationResult.Failure("部分次要配置命令执行失败");
}
return NetworkInterfaceOperationResult.Success();
}
private async Task<NetworkInterfaceOperationResult> ExecuteSingleConfigStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
var config = networkConfig.CoreOrImsConfigs.First();
var command = string.Format(startCommand.Template, 1);
var fullCommand = $"{command} {networkConfig.RagConfig} {config.CoreNetworkConfig} {config.ImsConfig}";
_logger.LogInformation("执行单配置启动命令: {Command}", fullCommand);
var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource);
return result.IsSuccess
? NetworkInterfaceOperationResult.Success()
: NetworkInterfaceOperationResult.Failure($"执行单配置启动命令失败: {result.Error}");
}
private async Task<NetworkInterfaceOperationResult> ExecuteMultiConfigStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig)
{
// 添加次要配置命令
var secondaryConfigs = networkConfig.CoreOrImsConfigs.Where(s => s.Index != 1).ToArray();
var secondaryTasks = new List<Task<CommandExecutionResult>>();
for (int i = 0; i < secondaryConfigs.Length; i++)
{
var config = secondaryConfigs[i];
var command = string.Format(startCommand.Template, i + 2);
var fullCommand = $"{command} NULL {config.CoreNetworkConfig} {config.ImsConfig}";
_logger.LogInformation("并发执行次要配置启动命令: {Command}", fullCommand);
secondaryTasks.Add(_commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource));
}
// 等待所有次要配置命令执行完成
var secondaryResults = await Task.WhenAll(secondaryTasks);
if (secondaryResults.Any(r => !r.IsSuccess))
{
return NetworkInterfaceOperationResult.Failure("部分次要配置命令执行失败");
}
// 执行主配置命令
var primaryConfig = networkConfig.CoreOrImsConfigs.FirstOrDefault(s => s.Index == 1);
if (primaryConfig != null)
{
var primaryCommand = string.Format(startCommand.Template, 1);
var fullCommand = $"{primaryCommand} {networkConfig.RagConfig} {primaryConfig.CoreNetworkConfig} {primaryConfig.ImsConfig}";
_logger.LogInformation("执行主配置启动命令: {Command}", fullCommand);
var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource);
if (!result.IsSuccess)
{
return NetworkInterfaceOperationResult.Failure($"主配置命令执行失败: {result.Error}");
}
}
return NetworkInterfaceOperationResult.Success();
}
}
Loading…
Cancel
Save