public UpdatedVesselFactoryTests() { _progressMock = new Mock <IUpdatingProgress>(); _scrapperMock = new Mock <IScrapper>(); _exMethodName = "method_name"; _correctImo = 9482469; VesselUpdateModel vslModel = new VesselUpdateModel() { AISLatestActivity = new DateTime(2020, 10, 02), AISStatus = "some_status", ETA = new DateTime(2020, 10, 03), GeographicalArea = "some_sea", Course = 200.3, Speed = 8.4, Destination = "some_port", Draught = 10.3, IMO = _correctImo, MMSI = 312619000, Lat = 41.842, Lon = 3.7294 }; _scrapperMock.Setup(mock => mock.ScrapSingleVessel(It.IsAny <int>(), It.IsAny <int>())).Returns(vslModel); _progressMock.Setup(mock => mock.GetIsUpdatingDatabase()).Returns(false); _progressMock.Setup(mock => mock.GetIsUpdatingPaused()).Returns(false); _service = new UpdatedVesselFactory(_scrapperMock.Object, _progressMock.Object); }
private string BuildResult(VesselUpdateModel result) { StringBuilder sb = new StringBuilder(); sb.Append(result.IMO); sb.Append(" | "); if (result.AISLatestActivity.HasValue) { sb.Append(result.AISLatestActivity.Value.ToShortDateString()); } else { sb.Append("(no activity time)"); } sb.Append(" | "); if (!string.IsNullOrEmpty(result.AISStatus)) { sb.Append(result.AISStatus); } else { sb.Append("(no status)"); } sb.Append(" | "); if (!string.IsNullOrEmpty(result.Destination)) { sb.Append(result.Destination); } else { sb.Append("(no destination)"); } return(sb.ToString()); }
//todo: unit test private VesselUpdateModel GetVesselUpdates(string html_document_1, string html_document_2, int imo, int mmsi) { double? lat = _nodeProcessor.ExtractLatFromHtml(html_document_2); double? lon = _nodeProcessor.ExtractLonFromHtml(html_document_2); DateTime?time = _nodeProcessor.ExtractAisUpdateTimeFromHtml(html_document_1, html_document_2); VesselUpdateModel vessel = new VesselUpdateModel() { Destination = _nodeProcessor.ExtractDestinationFromHtml(html_document_2), AISStatus = _nodeProcessor.ExtractNaviStatusFromHtml(html_document_1, time), ETA = _nodeProcessor.ExtractEtaTimeFromHtml(html_document_2), Course = _nodeProcessor.ExtractCourseFromHtml(html_document_2), Speed = _nodeProcessor.ExtractSpeedFromHtml(html_document_2), Draught = _nodeProcessor.ExtractDraughtFromHtml(html_document_2), AISLatestActivity = time, Lat = lat, Lon = lon, IMO = imo, MMSI = mmsi }; vessel.Destination = _areaFinder.VerifyDestinationWithLocode(vessel.Destination); vessel.GeographicalArea = _areaFinder.GetGeographicalArea(lat, lon); vessel.CurrnetPortLocode = _areaFinder.GetPortLocode(vessel.Speed, lat, lon); return(vessel); }
private int NonNullPropertiesCount(VesselUpdateModel entity) { return(entity.GetType() .GetProperties() .Select(x => x.GetValue(entity, null)) .Count(v => v != null)); }
public string BuildUpdatedVesselInfo(VesselUpdateModel result) { if (result != null) { return(BuildResult(result)); } return(null); }
private string GetVesselUpdateQuery(VesselUpdateModel update) { VesselAisUpdateModel existingVessel = FindExistingVessel(update.VesselId); existingVessel.VesselId = update.VesselId; existingVessel.Imo = update.IMO; string query = BuildSingleVesselQuery(existingVessel, update) ?? ""; return(query); }
public async Task <VesselUpdateModel> GetVesselUpdatesAsync(VesselAisUpdateModel aisUpdateModel, CancellationToken token, SemaphoreSlim semaphoreThrottel) { VesselUpdateModel vessel = null; try { bool skip = false; if (aisUpdateModel.Mmsi == 0) //if could not be scrapped with "full" { skip = true; _progress.AddSkipped(); } await semaphoreThrottel.WaitAsync(); if (!skip) { vessel = _scrapper.ScrapSingleVessel(aisUpdateModel.Mmsi, aisUpdateModel.Imo); vessel.VesselId = aisUpdateModel.VesselId; if (vessel.IMO != aisUpdateModel.Imo) { throw new Exception("Received vessel imo differs from the one passed."); } while (_progress.GetIsUpdatingDatabase() || _progress.GetIsUpdatingPaused()) { await Task.Delay(100); } _progress.AddToReturnedResultsQuantity(); } } catch (Exception ex) { _progress.SetLastError(ex.Message); _progress.AddFailedRequest(); vessel = null; } finally { while (_progress.GetIsUpdatingDatabase() || _progress.GetIsUpdatingPaused()) { await Task.Delay(100); } semaphoreThrottel.Release(); } return(vessel); }
private bool IsUpdateValid(VesselUpdateModel update) { if (update == null) { return(false); } if (NonNullPropertiesCount(update) <= 2) { return(false); } return(true); }
private void BuildUpdatedVesselInfo_OnSpecificParameters_ReturnsCorrectString(int imo, DateTime?activity, string status, string destination, string expected) { VesselUpdateModel model = new VesselUpdateModel() { IMO = imo, AISLatestActivity = activity, AISStatus = status, Destination = destination, }; string result = _service.BuildUpdatedVesselInfo(model); Assert.Equal(expected, result); }
public void UpdateMissingProperties(VesselUpdateModel updatedVessel) { if (updatedVessel != null) { if (!updatedVessel.Lat.HasValue) { _missingLatCounter++; } if (!updatedVessel.Lon.HasValue) { _missingLonCounter++; } if (!updatedVessel.Draught.HasValue) { _missingDraughtCounter++; } if (!updatedVessel.Speed.HasValue) { _missingSpeedCounter++; } if (!updatedVessel.Course.HasValue) { _missingCourseCounter++; } if (!updatedVessel.AISLatestActivity.HasValue) { _missingActivityCounter++; } if (!updatedVessel.ETA.HasValue) { _missingEtaCounter++; } if (string.IsNullOrEmpty(updatedVessel.Destination)) { _missingDestinationCounter++; } if (string.IsNullOrEmpty(updatedVessel.AISStatus)) { _missingStatusCounter++; } if (string.IsNullOrEmpty(updatedVessel.GeographicalArea)) { _missingAreaCounter++; } } }
private async Task ProcessNextStepAsync(List <VesselAisUpdateModel> updateList) { List <VesselUpdateModel> updatedVesselsStep = new List <VesselUpdateModel>(); try { List <Task> currentRunningTasks = new List <Task>(); CancellationTokenSource tokenSource = GetCancellationTokenSource(); SemaphoreSlim semaphoreThrottel = GetSemaphoreThrottel(); for (int i = _counter; i < _progress.GetCurrentUpdateStep(_counter, _configuration.GetValue <int>("Iteration:Step")); i++) { int iteration = i; currentRunningTasks.Add(Task.Run(async() => { VesselUpdateModel updatedVessel = await _vesselUpdates.GetVesselUpdatesAsync(updateList[iteration], tokenSource.Token, semaphoreThrottel); _progress.UpdateMissingProperties(updatedVessel); _progress.SetLastUpdatedVessel(_stringParser.BuildUpdatedVesselInfo(updatedVessel)); lock (((ICollection)updatedVesselsStep).SyncRoot) { updatedVesselsStep.Add(updatedVessel); } _counter++; }, tokenSource.Token)); } await Task.WhenAll(currentRunningTasks); } catch (Exception ex) { _counter++; _progress.SetLastError(ex.Message + " from: " + _exceptionProcessor.GetMethodNameThrowingException(ex)); } finally { _progress.SetUpdatingDatabaseTrue(); SaveUpdatedVesselsStep(updatedVesselsStep); _progress.SetUpdatingDatabaseFalse(); } }
public DataProcessorTests() { _progressMock = new Mock <IUpdatingProgress>(); _configMock = new Mock <IConfiguration>(); _updatesMock = new Mock <IUpdatedVesselFactory>(); _stringParser = new Mock <IStringParser>(); _dataServMock = new Mock <IDataAccessService>(); _exceptionsMock = new Mock <IExceptionProcessor>(); _exMethodName = "method_name"; _returnedSingleVessel = new VesselUpdateModel() { Course = 0.1, AISLatestActivity = null, AISStatus = "some_status", Destination = "some_dest", ETA = null, GeographicalArea = "some_area", Draught = 1.1, IMO = 11111111, Lat = 1.11, Lon = 1.12, MMSI = 11111112, Speed = 1.3 }; _returnedVessels = new List <VesselUpdateModel>() { _returnedSingleVessel }; _exceptionsMock.Setup(mock => mock.GetMethodNameThrowingException(It.IsAny <Exception>())).Returns(_exMethodName); _configMock.Setup(mock => mock.GetSection("Iteration:ParalelizmDegree")).Returns(new Mock <IConfigurationSection>().Object); _configMock.Setup(mock => mock.GetSection("Iteration:Step")).Returns(new Mock <IConfigurationSection>().Object); _progressMock.Setup(mock => mock.GetTotalResultsQuantity()).Returns(1); _progressMock.Setup(mock => mock.GetCurrentUpdateStep(It.IsAny <int>(), It.IsAny <int>())).Returns(1); _service = new DataProcessor (_progressMock.Object, _configMock.Object, _updatesMock.Object, _stringParser.Object, _dataServMock.Object, _exceptionsMock.Object); }
public async Task <bool> UpdateSingleVesselAsync(int mmsi, int imo, string searchType) { VesselUpdateModel updatedVessel = await _vesselUpdates.GetVesselUpdatesAsync (new VesselAisUpdateModel() { Mmsi = mmsi, Imo = imo, Speed = 0 }, GetCancellationTokenSource().Token, GetSemaphoreThrottel()); if (updatedVessel != null) { _dataService.SaveUpdatedVessels(new List <VesselUpdateModel>() { updatedVessel }); return(true); } return(false); }
private void UpdateMissingProperties_OnNotNullVesselModelWithNullProps_UpdatesCounters() { int expected = 1; VesselUpdateModel vesselUpdates = new VesselUpdateModel(); _service.SetUpdatingStarted(); _service.UpdateMissingProperties(vesselUpdates); StatusModel model = _service.GetProgressStatus(); Assert.Equal(expected, model.MissingActivityTimes); Assert.Equal(expected, model.MissingAreas); Assert.Equal(expected, model.MissingCourses); Assert.Equal(expected, model.MissingDestinations); Assert.Equal(expected, model.MissingDraughts); Assert.Equal(expected, model.MissingEtas); Assert.Equal(expected, model.MissingLats); Assert.Equal(expected, model.MissingLongs); Assert.Equal(expected, model.MissingSpeeds); Assert.Equal(expected, model.MissingStatuses); }
private void GetVesselUpdatesAsync_OnReceivedResultWithDifferentImo_ThrowsException() { int _incorrectImo = _correctImo - 1; Exception ex = new Exception("Received vessel imo differs from the one passed."); VesselAisUpdateModel updateModel = new VesselAisUpdateModel() { Imo = 9482469, Mmsi = 12345678, Speed = 0.1 }; VesselUpdateModel returnedModel = new VesselUpdateModel() { IMO = _incorrectImo }; _scrapperMock.Setup(mock => mock.ScrapSingleVessel(It.IsAny <int>(), It.IsAny <int>())).Returns(returnedModel); Task <VesselUpdateModel> result = _service.GetVesselUpdatesAsync(updateModel, new CancellationToken(), new SemaphoreSlim(1)); Assert.Null(result.Result); _progressMock.Verify(mock => mock.GetIsUpdatingDatabase(), Times.Once()); _progressMock.Verify(mock => mock.GetIsUpdatingPaused(), Times.Once()); _progressMock.Verify(mock => mock.AddFailedRequest(), Times.Once()); _progressMock.Verify(mock => mock.SetLastError(ex.Message), Times.Once()); }
private string BuildSingleVesselQuery(VesselAisUpdateModel existingVessel, VesselUpdateModel update) { StringBuilder vesselQuerySb = new StringBuilder(); vesselQuerySb.Append("UPDATE dbo.Vessels SET IMO = '" + update.IMO + "'"); if (existingVessel.Mmsi == 0) { if (update.MMSI.HasValue) { vesselQuerySb.Append(" , MMSI = '" + update.MMSI + "'"); } } if (update.AISLatestActivity.HasValue) { vesselQuerySb.Append(" , AISLatestActivity = '" + update.AISLatestActivity.Value.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"); } if (update.ETA.HasValue) { vesselQuerySb.Append(" , ETA = '" + update.ETA.Value.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"); } if (update.Course.HasValue) { vesselQuerySb.Append(" , Course = '" + update.Course.Value.ToString("0.0", System.Globalization.CultureInfo.InvariantCulture) + "'"); } if (update.Lat.HasValue) { vesselQuerySb.Append(" , Lat = '" + update.Lat.Value.ToString("0.0000", System.Globalization.CultureInfo.InvariantCulture) + "'"); } if (update.Lon.HasValue) { vesselQuerySb.Append(" , Lon = '" + update.Lon.Value.ToString("0.0000", System.Globalization.CultureInfo.InvariantCulture) + "'"); } if (update.Speed.HasValue) { vesselQuerySb.Append(" , Speed = '" + update.Speed.Value.ToString("0.0", System.Globalization.CultureInfo.InvariantCulture) + "'"); if ((existingVessel.SpeedMax < update.Speed || existingVessel.SpeedMax == null) && update.Speed != 0) { vesselQuerySb.Append(" , SpeedMax = '" + update.Speed.Value.ToString("0.0", System.Globalization.CultureInfo.InvariantCulture) + "'"); } } if (update.Draught.HasValue) { vesselQuerySb.Append(" , Draught = '" + update.Draught.Value.ToString("0.0", System.Globalization.CultureInfo.InvariantCulture) + "'"); if ((existingVessel.DraughtMax < update.Draught || existingVessel.DraughtMax == null) && update.Draught != 0) { vesselQuerySb.Append(" , DraughtMax = '" + update.Draught.Value.ToString("0.0", System.Globalization.CultureInfo.InvariantCulture) + "'"); } } if (!string.IsNullOrEmpty(update.AISStatus)) { vesselQuerySb.Append(" , AISStatus = '" + _stringParser.MakeFirstCharactersToUpper(update.AISStatus) + "'"); } if (!string.IsNullOrEmpty(update.Destination)) { vesselQuerySb.Append(" , Destination = '" + _stringParser.MakeFirstCharactersToUpper(update.Destination) + "'"); } if (!string.IsNullOrEmpty(update.GeographicalArea)) { vesselQuerySb.Append(" , GeographicalArea = '" + update.GeographicalArea + "'"); } if (!string.IsNullOrEmpty(update.CurrnetPortLocode)) { vesselQuerySb.Append(" , CurrnetPortLocode = '" + update.CurrnetPortLocode + "'"); } vesselQuerySb.Append(" WHERE VesselId = " + existingVessel.VesselId + "; "); vesselQuerySb.AppendLine(); return(vesselQuerySb.ToString()); }
public async Task <Vessel> UpdateAsync(VesselUpdateModel vessel) { await BodyGetService.ValidateAsync(vessel); return(await VesselDataAccess.UpdateAsync(vessel)); }