< Summary

Information
Class: LGDXRobotCloud.API.Services.Navigation.RobotService
Assembly: LGDXRobotCloud.API
File(s): /builds/yukaitung/lgdxrobot2-cloud/LGDXRobotCloud.API/Services/Navigation/RobotService.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 299
Coverable lines: 299
Total lines: 374
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 24
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/builds/yukaitung/lgdxrobot2-cloud/LGDXRobotCloud.API/Services/Navigation/RobotService.cs

#LineLine coverage
 1using LGDXRobotCloud.API.Exceptions;
 2using LGDXRobotCloud.API.Services.Administration;
 3using LGDXRobotCloud.Data.DbContexts;
 4using LGDXRobotCloud.Data.Entities;
 5using LGDXRobotCloud.Data.Models.Business.Administration;
 6using LGDXRobotCloud.Data.Models.Business.Automation;
 7using LGDXRobotCloud.Data.Models.Business.Navigation;
 8using LGDXRobotCloud.Utilities.Enums;
 9using LGDXRobotCloud.Utilities.Helpers;
 10using Microsoft.EntityFrameworkCore;
 11using Microsoft.Extensions.Caching.Memory;
 12
 13namespace LGDXRobotCloud.API.Services.Navigation;
 14
 15public interface IRobotService
 16{
 17  Task<(IEnumerable<RobotListBusinessModel>, PaginationHelper)> GetRobotsAsync(int? realmId, string? name, int pageNumbe
 18  Task<RobotBusinessModel> GetRobotAsync(Guid robotId);
 19  Task<RobotCreateResponseBusinessModel> CreateRobotAsync(RobotCreateBusinessModel robotCreateBusinessModel);
 20  Task<bool> UpdateRobotAsync(Guid id, RobotUpdateBusinessModel robotUpdateDtoBusinessModel);
 21  Task<RobotChassisInfoBusinessModel?> GetRobotChassisInfoAsync(Guid robotId);
 22  Task<bool> UpdateRobotChassisInfoAsync(Guid id, RobotChassisInfoUpdateBusinessModel robotChassisInfoUpdateBusinessMode
 23  Task<bool> TestDeleteRobotAsync(Guid id);
 24  Task<bool> DeleteRobotAsync(Guid id);
 25
 26  Task<RobotSystemInfoBusinessModel?> GetRobotSystemInfoAsync(Guid robotId);
 27  Task<bool> CreateRobotSystemInfoAsync(Guid robotId, RobotSystemInfoCreateBusinessModel robotSystemInfoCreateBusinessMo
 28  Task<bool> UpdateRobotSystemInfoAsync(Guid robotId, RobotSystemInfoUpdateBusinessModel robotSystemInfoUpdateBusinessMo
 29
 30  Task<IEnumerable<RobotSearchBusinessModel>> SearchRobotsAsync(int realmId, string? name, Guid? robotId);
 31
 32  Task<int?> GetRobotRealmIdAsync(Guid robotId);
 33  Task<bool> GetRobotIsRealtimeExchange(Guid robotId);
 34}
 35
 036public class RobotService(
 037    IMemoryCache memoryCache,
 038    IRobotCertificateService robotCertificateService,
 039    LgdxContext context
 040  ) : IRobotService
 41{
 042  private readonly IMemoryCache _memoryCache = memoryCache ?? throw new ArgumentNullException(nameof(memoryCache));
 043  private readonly IRobotCertificateService _robotCertificateService = robotCertificateService ?? throw new ArgumentNull
 044  private readonly LgdxContext _context = context ?? throw new ArgumentNullException(nameof(context));
 45
 46  public async Task<(IEnumerable<RobotListBusinessModel>, PaginationHelper)> GetRobotsAsync(int? realmId, string? name, 
 047  {
 048    var query = _context.Robots as IQueryable<Robot>;
 049    if (realmId != null)
 050    {
 051      query = query.Where(r => r.RealmId == realmId);
 052    }
 053    if (!string.IsNullOrWhiteSpace(name))
 054    {
 055      name = name.Trim();
 056      query = query.Where(r => r.Name.Contains(name));
 057    }
 058    var itemCount = await query.CountAsync();
 059    var PaginationHelper = new PaginationHelper(itemCount, pageNumber, pageSize);
 060    var robots = await query.AsNoTracking()
 061      .OrderBy(r => r.Id)
 062      .Skip(pageSize * (pageNumber - 1))
 063      .Take(pageSize)
 064      .Select(r => new RobotListBusinessModel {
 065        Id = r.Id,
 066        Name = r.Name,
 067        RealmId = r.RealmId,
 068        RealmName = r.Realm.Name,
 069      })
 070      .AsSplitQuery()
 071      .ToListAsync();
 072    return (robots, PaginationHelper);
 073  }
 74
 75  public async Task<RobotBusinessModel> GetRobotAsync(Guid robotId)
 076  {
 077    return await _context.Robots.AsNoTracking()
 078      .Where(r => r.Id == robotId)
 079      .Select(r => new RobotBusinessModel {
 080        Id = r.Id,
 081        Name = r.Name,
 082        RealmId = r.RealmId,
 083        RealmName = r.Realm.Name,
 084        IsRealtimeExchange = r.IsRealtimeExchange,
 085        IsProtectingHardwareSerialNumber = r.IsProtectingHardwareSerialNumber,
 086        RobotCertificate = new RobotCertificateBusinessModel {
 087          Id = r.RobotCertificate.Id,
 088          RobotId = r.Id,
 089          RobotName = r.Name,
 090          Thumbprint = r.RobotCertificate.Thumbprint,
 091          ThumbprintBackup = r.RobotCertificate.ThumbprintBackup,
 092          NotBefore = r.RobotCertificate.NotBefore,
 093          NotAfter = r.RobotCertificate.NotAfter,
 094        },
 095        RobotSystemInfo = r.RobotSystemInfo == null ? null : new RobotSystemInfoBusinessModel {
 096          Id = r.RobotSystemInfo.Id,
 097          Cpu = r.RobotSystemInfo.Cpu,
 098          IsLittleEndian = r.RobotSystemInfo.IsLittleEndian,
 099          Motherboard = r.RobotSystemInfo.Motherboard,
 0100          MotherboardSerialNumber = r.RobotSystemInfo.MotherboardSerialNumber,
 0101          RamMiB = r.RobotSystemInfo.RamMiB,
 0102          Gpu = r.RobotSystemInfo.Gpu,
 0103          Os = r.RobotSystemInfo.Os,
 0104          Is32Bit = r.RobotSystemInfo.Is32Bit,
 0105          McuSerialNumber = r.RobotSystemInfo.McuSerialNumber,
 0106        },
 0107        RobotChassisInfo = r.RobotChassisInfo == null ? null : new RobotChassisInfoBusinessModel {
 0108          Id = r.RobotChassisInfo.Id,
 0109          RobotTypeId = r.RobotChassisInfo.RobotTypeId,
 0110          ChassisLengthX = r.RobotChassisInfo.ChassisLengthX,
 0111          ChassisLengthY = r.RobotChassisInfo.ChassisLengthY,
 0112          ChassisWheelCount = r.RobotChassisInfo.ChassisWheelCount,
 0113          ChassisWheelRadius = r.RobotChassisInfo.ChassisWheelRadius,
 0114          BatteryCount = r.RobotChassisInfo.BatteryCount,
 0115          BatteryMaxVoltage = r.RobotChassisInfo.BatteryMaxVoltage,
 0116          BatteryMinVoltage = r.RobotChassisInfo.BatteryMinVoltage,
 0117        },
 0118        AssignedTasks = r.AssignedTasks
 0119          .Where(t =>  t.CurrentProgressId != (int)ProgressState.Aborted
 0120                    && t.CurrentProgressId != (int)ProgressState.Completed
 0121                    && t.CurrentProgressId != (int)ProgressState.Template)
 0122          .OrderByDescending(t => t.CurrentProgressId)
 0123          .ThenBy(t => t.Id)
 0124          .Select(t => new AutoTaskListBusinessModel {
 0125          Id = t.Id,
 0126          Name = t.Name,
 0127          Priority = t.Priority,
 0128          FlowId = t.FlowId,
 0129          FlowName = t.Flow!.Name,
 0130          RealmId = r.RealmId,
 0131          RealmName = r.Realm.Name,
 0132          AssignedRobotId = r.Id,
 0133          AssignedRobotName = r.Name,
 0134          CurrentProgressId = t.CurrentProgressId,
 0135          CurrentProgressName = t.CurrentProgress.Name,
 0136        })
 0137        .ToList(),
 0138      })
 0139      .FirstOrDefaultAsync()
 0140        ?? throw new LgdxNotFound404Exception();
 0141  }
 142
 143  public async Task<RobotCreateResponseBusinessModel> CreateRobotAsync(RobotCreateBusinessModel robotCreateBusinessModel
 0144  {
 0145    var realm = await _context.Realms.Where(r => r.Id == robotCreateBusinessModel.RealmId).AnyAsync();
 0146    if (realm == false)
 0147    {
 0148      throw new LgdxValidation400Expection(nameof(robotCreateBusinessModel.RealmId), "Realm does not exist.");
 149    }
 150
 0151    var id = Guid.CreateVersion7();
 0152    var robotCertificate = _robotCertificateService.IssueRobotCertificate(id);
 0153    var robot = new Robot {
 0154      Id = id,
 0155      Name = robotCreateBusinessModel.Name,
 0156      RealmId = robotCreateBusinessModel.RealmId,
 0157      IsRealtimeExchange = robotCreateBusinessModel.IsRealtimeExchange,
 0158      IsProtectingHardwareSerialNumber = robotCreateBusinessModel.IsProtectingHardwareSerialNumber,
 0159      RobotCertificate = new RobotCertificate {
 0160        Thumbprint = robotCertificate.RobotCertificateThumbprint,
 0161        NotBefore = DateTime.SpecifyKind(robotCertificate.RobotCertificateNotBefore, DateTimeKind.Utc),
 0162        NotAfter = DateTime.SpecifyKind(robotCertificate.RobotCertificateNotAfter, DateTimeKind.Utc)
 0163      },
 0164      RobotChassisInfo = new RobotChassisInfo {
 0165        RobotTypeId = robotCreateBusinessModel.RobotChassisInfo.RobotTypeId,
 0166        ChassisLengthX = robotCreateBusinessModel.RobotChassisInfo.ChassisLengthX,
 0167        ChassisLengthY = robotCreateBusinessModel.RobotChassisInfo.ChassisLengthY,
 0168        ChassisWheelCount = robotCreateBusinessModel.RobotChassisInfo.ChassisWheelCount,
 0169        ChassisWheelRadius = robotCreateBusinessModel.RobotChassisInfo.ChassisWheelRadius,
 0170        BatteryCount = robotCreateBusinessModel.RobotChassisInfo.BatteryCount,
 0171        BatteryMaxVoltage = robotCreateBusinessModel.RobotChassisInfo.BatteryMaxVoltage,
 0172        BatteryMinVoltage = robotCreateBusinessModel.RobotChassisInfo.BatteryMinVoltage,
 0173      }
 0174    };
 0175    await _context.Robots.AddAsync(robot);
 0176    await _context.SaveChangesAsync();
 177
 0178    return new RobotCreateResponseBusinessModel {
 0179      RobotId = robot.Id,
 0180      RobotName = robot.Name,
 0181      RootCertificate = robotCertificate.RootCertificate,
 0182      RobotCertificatePrivateKey = robotCertificate.RobotCertificatePrivateKey,
 0183      RobotCertificatePublicKey = robotCertificate.RobotCertificatePublicKey
 0184    };
 0185  }
 186
 187  public async Task<bool> UpdateRobotAsync(Guid id, RobotUpdateBusinessModel robotUpdateDtoBusinessModel)
 0188  {
 0189    return await _context.Robots
 0190      .Where(r => r.Id == id)
 0191      .ExecuteUpdateAsync(setters => setters
 0192        .SetProperty(r => r.Name, robotUpdateDtoBusinessModel.Name)
 0193        .SetProperty(r => r.IsRealtimeExchange, robotUpdateDtoBusinessModel.IsRealtimeExchange)
 0194        .SetProperty(r => r.IsProtectingHardwareSerialNumber, robotUpdateDtoBusinessModel.IsProtectingHardwareSerialNumb
 0195      ) == 1;
 0196  }
 197
 198  public async Task<bool> UpdateRobotChassisInfoAsync(Guid id, RobotChassisInfoUpdateBusinessModel robotChassisInfoUpdat
 0199  {
 0200    return await _context.RobotChassisInfos
 0201      .Where(r => r.RobotId == id)
 0202      .ExecuteUpdateAsync(setters => setters
 0203        .SetProperty(r => r.RobotTypeId, robotChassisInfoUpdateBusinessModel.RobotTypeId)
 0204        .SetProperty(r => r.ChassisLengthX, robotChassisInfoUpdateBusinessModel.ChassisLengthX)
 0205        .SetProperty(r => r.ChassisLengthY, robotChassisInfoUpdateBusinessModel.ChassisLengthY)
 0206        .SetProperty(r => r.ChassisWheelCount, robotChassisInfoUpdateBusinessModel.ChassisWheelCount)
 0207        .SetProperty(r => r.ChassisWheelRadius, robotChassisInfoUpdateBusinessModel.ChassisWheelRadius)
 0208        .SetProperty(r => r.BatteryCount, robotChassisInfoUpdateBusinessModel.BatteryCount)
 0209        .SetProperty(r => r.BatteryMaxVoltage, robotChassisInfoUpdateBusinessModel.BatteryMaxVoltage)
 0210        .SetProperty(r => r.BatteryMinVoltage, robotChassisInfoUpdateBusinessModel.BatteryMinVoltage)
 0211      ) == 1;
 0212  }
 213
 214  public async Task<RobotChassisInfoBusinessModel?> GetRobotChassisInfoAsync(Guid robotId)
 0215  {
 0216    return await _context.RobotChassisInfos.AsNoTracking()
 0217      .Where(r => r.RobotId == robotId)
 0218      .Select(r => new RobotChassisInfoBusinessModel {
 0219        Id = r.Id,
 0220        RobotTypeId = r.RobotTypeId,
 0221        ChassisLengthX = r.ChassisLengthX,
 0222        ChassisLengthY = r.ChassisLengthY,
 0223        ChassisWheelCount = r.ChassisWheelCount,
 0224        ChassisWheelRadius = r.ChassisWheelRadius,
 0225        BatteryCount = r.BatteryCount,
 0226        BatteryMaxVoltage = r.BatteryMaxVoltage,
 0227        BatteryMinVoltage = r.BatteryMinVoltage,
 0228      }).FirstOrDefaultAsync();
 0229  }
 230
 231  public async Task<bool> TestDeleteRobotAsync(Guid id)
 0232  {
 0233    var depeendencies = await _context.AutoTasks
 0234      .Where(t => t.AssignedRobotId == id)
 0235      .Where(t => t.CurrentProgressId != (int)ProgressState.Completed && t.CurrentProgressId != (int)ProgressState.Abort
 0236      .CountAsync();
 0237    if (depeendencies > 0)
 0238    {
 0239      throw new LgdxValidation400Expection(nameof(id), $"This robot has been used by {depeendencies} running/waiting/tem
 240    }
 0241    return true;
 0242  }
 243
 244  public async Task<bool> DeleteRobotAsync(Guid id)
 0245  {
 0246    return await _context.Robots.Where(r => r.Id == id)
 0247      .ExecuteDeleteAsync() >= 1;
 0248  }
 249
 250  public async Task<RobotSystemInfoBusinessModel?> GetRobotSystemInfoAsync(Guid robotId)
 0251  {
 0252    return await _context.RobotSystemInfos.AsNoTracking()
 0253      .Where(r => r.RobotId == robotId)
 0254      .Select(r => new RobotSystemInfoBusinessModel {
 0255        Id = r.Id,
 0256        Cpu = r.Cpu,
 0257        IsLittleEndian = r.IsLittleEndian,
 0258        Motherboard = r.Motherboard,
 0259        MotherboardSerialNumber = r.MotherboardSerialNumber,
 0260        RamMiB = r.RamMiB,
 0261        Gpu = r.Gpu,
 0262        Os = r.Os,
 0263        Is32Bit = r.Is32Bit,
 0264        McuSerialNumber = r.McuSerialNumber,
 0265      })
 0266      .FirstOrDefaultAsync();
 0267  }
 268
 269  public async Task<bool> CreateRobotSystemInfoAsync(Guid robotId, RobotSystemInfoCreateBusinessModel robotSystemInfoCre
 0270  {
 0271    var robotSystemInfo = new RobotSystemInfo {
 0272      Cpu = robotSystemInfoCreateBusinessModel.Cpu,
 0273      IsLittleEndian = robotSystemInfoCreateBusinessModel.IsLittleEndian,
 0274      Motherboard = robotSystemInfoCreateBusinessModel.Motherboard,
 0275      MotherboardSerialNumber = robotSystemInfoCreateBusinessModel.MotherboardSerialNumber,
 0276      RamMiB = robotSystemInfoCreateBusinessModel.RamMiB,
 0277      Gpu = robotSystemInfoCreateBusinessModel.Gpu,
 0278      Os = robotSystemInfoCreateBusinessModel.Os,
 0279      Is32Bit = robotSystemInfoCreateBusinessModel.Is32Bit,
 0280      McuSerialNumber = robotSystemInfoCreateBusinessModel.McuSerialNumber,
 0281      RobotId = robotId
 0282    };
 0283    _context.RobotSystemInfos.Add(robotSystemInfo);
 0284    return await _context.SaveChangesAsync() >= 1;
 0285  }
 286
 287  public async Task<bool> UpdateRobotSystemInfoAsync(Guid robotId, RobotSystemInfoUpdateBusinessModel robotSystemInfoUpd
 0288  {
 0289    return await _context.RobotSystemInfos
 0290      .Where(r => r.RobotId == robotId)
 0291      .ExecuteUpdateAsync(setters => setters
 0292        .SetProperty(r => r.Cpu, robotSystemInfoUpdateBusinessModel.Cpu)
 0293        .SetProperty(r => r.IsLittleEndian, robotSystemInfoUpdateBusinessModel.IsLittleEndian)
 0294        .SetProperty(r => r.Motherboard, robotSystemInfoUpdateBusinessModel.Motherboard)
 0295        .SetProperty(r => r.MotherboardSerialNumber, robotSystemInfoUpdateBusinessModel.MotherboardSerialNumber)
 0296        .SetProperty(r => r.RamMiB, robotSystemInfoUpdateBusinessModel.RamMiB)
 0297        .SetProperty(r => r.Gpu, robotSystemInfoUpdateBusinessModel.Gpu)
 0298        .SetProperty(r => r.Os, robotSystemInfoUpdateBusinessModel.Os)
 0299        .SetProperty(r => r.Is32Bit, robotSystemInfoUpdateBusinessModel.Is32Bit)
 0300        .SetProperty(r => r.McuSerialNumber, robotSystemInfoUpdateBusinessModel.McuSerialNumber)
 0301      ) == 1;
 0302  }
 303
 304  public async Task UpsertRobotChassisInfoAsync(Guid robotId, RobotChassisInfoBusinessModel robotChassisInfo)
 0305  {
 0306    var robotChassisInfoEntity = await _context.RobotChassisInfos.Where(r => r.RobotId == robotId).FirstOrDefaultAsync()
 0307    if (robotChassisInfoEntity == null)
 0308    {
 0309      _context.RobotChassisInfos.Add(new RobotChassisInfo {
 0310        RobotId = robotId,
 0311        RobotTypeId = robotChassisInfo.RobotTypeId,
 0312        ChassisLengthX = robotChassisInfo.ChassisLengthX,
 0313        ChassisLengthY = robotChassisInfo.ChassisLengthY,
 0314        ChassisWheelCount = robotChassisInfo.ChassisWheelCount,
 0315        ChassisWheelRadius = robotChassisInfo.ChassisWheelRadius,
 0316        BatteryCount = robotChassisInfo.BatteryCount,
 0317        BatteryMaxVoltage = robotChassisInfo.BatteryMaxVoltage,
 0318        BatteryMinVoltage = robotChassisInfo.BatteryMinVoltage,
 0319      });
 0320    }
 321    else
 0322    {
 0323      robotChassisInfoEntity.RobotTypeId = robotChassisInfo.RobotTypeId;
 0324      robotChassisInfoEntity.ChassisLengthX = robotChassisInfo.ChassisLengthX;
 0325      robotChassisInfoEntity.ChassisLengthY = robotChassisInfo.ChassisLengthY;
 0326      robotChassisInfoEntity.ChassisWheelCount = robotChassisInfo.ChassisWheelCount;
 0327      robotChassisInfoEntity.ChassisWheelRadius = robotChassisInfo.ChassisWheelRadius;
 0328      robotChassisInfoEntity.BatteryCount = robotChassisInfo.BatteryCount;
 0329      robotChassisInfoEntity.BatteryMaxVoltage = robotChassisInfo.BatteryMaxVoltage;
 0330      robotChassisInfoEntity.BatteryMinVoltage = robotChassisInfo.BatteryMinVoltage;
 0331    }
 0332    await _context.SaveChangesAsync();
 0333  }
 334
 335  public async Task<IEnumerable<RobotSearchBusinessModel>> SearchRobotsAsync(int realmId, string? name, Guid? robotId)
 0336  {
 0337    var n = name ?? string.Empty;
 0338    return await _context.Robots.AsNoTracking()
 0339      .Where(r => r.RealmId == realmId)
 0340      .Where(t => t.Name.ToLower().Contains(n.ToLower()))
 0341      .Where(r => robotId == null || r.Id == robotId)
 0342      .Take(10)
 0343      .Select(m => new RobotSearchBusinessModel {
 0344        Id = m.Id,
 0345        Name = m.Name,
 0346      })
 0347      .ToListAsync();
 0348  }
 349
 350  public async Task<int?> GetRobotRealmIdAsync(Guid robotId)
 0351  {
 0352    if (_memoryCache.TryGetValue<int>($"RobotService_GetRobotRealmIdAsync_{robotId}", out var RealmId))
 0353    {
 0354      return RealmId;
 355    }
 356
 0357    var robot = await _context.Robots.AsNoTracking()
 0358      .Select(m => new { m.Id, m.RealmId })
 0359      .FirstOrDefaultAsync();
 0360    if (robot == null)
 0361      return null;
 362
 0363    _memoryCache.Set($"RobotService_GetRobotRealmIdAsync_{robotId}", robot!.RealmId, TimeSpan.FromDays(1));
 0364    return robot.RealmId;
 0365  }
 366
 367  public async Task<bool> GetRobotIsRealtimeExchange(Guid robotId)
 0368  {
 0369    return await _context.Robots.AsNoTracking()
 0370      .Where(r => r.Id == robotId)
 0371      .Select(r => r.IsRealtimeExchange)
 0372      .FirstOrDefaultAsync();
 0373  }
 374}