Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 59 additions & 25 deletions src/ShippingRecorder.Api/Controllers/ExportController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Mvc;
using ShippingRecorder.Api.Interfaces;
using ShippingRecorder.Api.Entities;
using ShippingRecorder.Entities.Jobs;

namespace HealthTracker.Api.Controllers
{
Expand All @@ -14,35 +15,55 @@ public class ExportController : Controller
private readonly IBackgroundQueue<CountryExportWorkItem> _countryQueue;
private readonly IBackgroundQueue<LocationExportWorkItem> _locationQueue;
private readonly IBackgroundQueue<OperatorExportWorkItem> _operatorQueue;
private readonly IBackgroundQueue<PortExportWorkItem> _portQueue;
private readonly IBackgroundQueue<SightingExportWorkItem> _sightingQueue;
private readonly IBackgroundQueue<VesselExportWorkItem> _vesselQueue;
private readonly IBackgroundQueue<VesselTypeExportWorkItem> _vesselTypeQueue;
private readonly IBackgroundQueue<VoyageExportWorkItem> _voyageQueue;
private readonly IBackgroundQueue<SightingExportWorkItem> _sightingQueue;
private readonly IBackgroundQueue<PortExportWorkItem> _portQueue;

public ExportController(
IBackgroundQueue<CountryExportWorkItem> countryQueue,
IBackgroundQueue<LocationExportWorkItem> locationQueue,
IBackgroundQueue<OperatorExportWorkItem> operatorQueue,
IBackgroundQueue<PortExportWorkItem> portQueue,
IBackgroundQueue<SightingExportWorkItem> sightingQueue,
IBackgroundQueue<VesselExportWorkItem> vesselQueue,
IBackgroundQueue<VesselTypeExportWorkItem> vesselTypeQueue,
IBackgroundQueue<VoyageExportWorkItem> voyageQueue,
IBackgroundQueue<SightingExportWorkItem> sightingQueue,
IBackgroundQueue<PortExportWorkItem> portQueue)
IBackgroundQueue<VoyageExportWorkItem> voyageQueue)
{
_countryQueue = countryQueue;
_locationQueue = locationQueue;
_operatorQueue = operatorQueue;
_portQueue = portQueue;
_sightingQueue = sightingQueue;
_vesselQueue = vesselQueue;
_vesselTypeQueue = vesselTypeQueue;
_voyageQueue = voyageQueue;
_sightingQueue = sightingQueue;
_portQueue = portQueue;
}

[HttpPost]
[Route("all")]
public IActionResult ExportAll([FromBody] AllExportWorkItem item)
{
// Get the file name without the extension or path
var fileName = Path.GetFileNameWithoutExtension(item.FileName);

// Queue exports for each data type
_countryQueue.Enqueue(BuildWorkItem<CountryExportWorkItem>("Countries", fileName));
_locationQueue.Enqueue(BuildWorkItem<LocationExportWorkItem>("Locations", fileName));
_operatorQueue.Enqueue(BuildWorkItem<OperatorExportWorkItem>("Operators", fileName));
_portQueue.Enqueue(BuildWorkItem<PortExportWorkItem>("Ports", fileName));
_sightingQueue.Enqueue(BuildWorkItem<SightingExportWorkItem>("Sightings", fileName));
_vesselQueue.Enqueue(BuildWorkItem<VesselExportWorkItem>("Vessels", fileName));
_vesselTypeQueue.Enqueue(BuildWorkItem<VesselTypeExportWorkItem>("Vessel-Types", fileName));
_voyageQueue.Enqueue(BuildWorkItem<VoyageExportWorkItem>("Voyages", fileName));

return Accepted();
}

[HttpPost]
[Route("countries")]
public IActionResult ExportCountris([FromBody] CountryExportWorkItem item)
public IActionResult ExportCountries([FromBody] CountryExportWorkItem item)
{
item.JobName = "Country Export";
_countryQueue.Enqueue(item);
Expand All @@ -67,6 +88,24 @@ public IActionResult ExportOperators([FromBody] OperatorExportWorkItem item)
return Accepted();
}

[HttpPost]
[Route("ports")]
public IActionResult ExportPorts([FromBody] PortExportWorkItem item)
{
item.JobName = "Port Export";
_portQueue.Enqueue(item);
return Accepted();
}

[HttpPost]
[Route("sightings")]
public IActionResult ExportSightings([FromBody] SightingExportWorkItem item)
{
item.JobName = "Sighting Export";
_sightingQueue.Enqueue(item);
return Accepted();
}

[HttpPost]
[Route("vessels")]
public IActionResult ExportVessels([FromBody] VesselExportWorkItem item)
Expand All @@ -85,15 +124,6 @@ public IActionResult ExportVesselTypes([FromBody] VesselTypeExportWorkItem item)
return Accepted();
}

[HttpPost]
[Route("sightings")]
public IActionResult ExportSightings([FromBody] SightingExportWorkItem item)
{
item.JobName = "Sighting Export";
_sightingQueue.Enqueue(item);
return Accepted();
}

[HttpPost]
[Route("voyages")]
public IActionResult ExportVoyages([FromBody] VoyageExportWorkItem item)
Expand All @@ -103,13 +133,17 @@ public IActionResult ExportVoyages([FromBody] VoyageExportWorkItem item)
return Accepted();
}

[HttpPost]
[Route("ports")]
public IActionResult ExportPorts([FromBody] PortExportWorkItem item)
{
item.JobName = "Port Export";
_portQueue.Enqueue(item);
return Accepted();
}
/// <summary>
/// Helper method to build a work item for the specified entity type
/// </summary>
/// <param name="entityName"></param>
/// <param name="fileName"></param>
/// <returns></returns>
private T BuildWorkItem<T>(string entityName, string fileName) where T : ExportWorkItem, new()
=> new()
{
JobName = $"{entityName} Export",
FileName = $"{fileName}-{entityName}.csv"
};
}
}
18 changes: 9 additions & 9 deletions src/ShippingRecorder.Api/Controllers/ImportController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ public IActionResult ImportPorts([FromBody] PortImportWorkItem item)
return Accepted();
}

[HttpPost]
[Route("sightings")]
public IActionResult ImportSightings([FromBody] SightingImportWorkItem item)
{
item.JobName = "Sighting Import";
_sightingQueue.Enqueue(item);
return Accepted();
}

[HttpPost]
[Route("vessels")]
public IActionResult ImportVessels([FromBody] VesselImportWorkItem item)
Expand All @@ -94,15 +103,6 @@ public IActionResult ImportVesselTypes([FromBody] VesselTypeImportWorkItem item)
return Accepted();
}

[HttpPost]
[Route("sightings")]
public IActionResult ImportSightings([FromBody] SightingImportWorkItem item)
{
item.JobName = "Sighting Import";
_sightingQueue.Enqueue(item);
return Accepted();
}

[HttpPost]
[Route("voyages")]
public IActionResult ImportVoyages([FromBody] VoyageImportWorkItem item)
Expand Down
6 changes: 5 additions & 1 deletion src/ShippingRecorder.Api/Controllers/PortsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using ShippingRecorder.Entities.Logging;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Linq.Expressions;

namespace ShippingRecorder.Api.Controllers
{
Expand All @@ -23,7 +24,10 @@ public async Task<ActionResult<List<Port>>> GetPortsAsync(int countryId, int pag
{
LogMessage(Severity.Debug, $"Retrieving list of ports (page {pageNumber}, page size {pageSize})");

List<Port> ports = await Factory.Ports.ListAsync(x => x.CountryId == countryId, pageNumber, pageSize).ToListAsync();
// If the country's 0 or less, just return all ports. Otherwise, return only ports for the specified
// country ID
Expression<Func<Port, bool>> predicate = x => countryId > 0 ? x.CountryId == countryId : true;
List<Port> ports = await Factory.Ports.ListAsync(predicate, pageNumber, pageSize).ToListAsync();

LogMessage(Severity.Debug, $"Retrieved {ports.Count} port(s)");

Expand Down
8 changes: 8 additions & 0 deletions src/ShippingRecorder.Api/Entities/AllExportWorkItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using ShippingRecorder.Entities.Jobs;

namespace ShippingRecorder.Api.Entities
{
public class AllExportWorkItem : ExportWorkItem
{
}
}
41 changes: 41 additions & 0 deletions src/ShippingRecorder.Client/ApiClient/ExportClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using ShippingRecorder.Client.Interfaces;
using ShippingRecorder.Entities.Interfaces;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
using ShippingRecorder.Entities.Db;
using System.Net.Http;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using System;

namespace ShippingRecorder.Client.ApiClient
{
public class ExportClient : ShippingRecorderClientBase, IExportClient
{
private const string RouteKey = "Export";

public ExportClient(
IShippingRecorderHttpClient client,
IShippingRecorderApplicationSettings settings,
IAuthenticationTokenProvider tokenProvider,
ICacheWrapper cache,
ILogger<ExportClient> logger)
: base(client, settings, tokenProvider, cache, logger)
{
}

/// <summary>
/// Request an export of allexports to a named file in the export allexport
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task ExportAsync(string fileName)
{
dynamic data = new{ FileName = fileName };
var json = Serialize(data);
await SendIndirectAsync(RouteKey, json, HttpMethod.Post);
}
}
}
20 changes: 17 additions & 3 deletions src/ShippingRecorder.Client/ApiClient/PortClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,21 @@ public PortClient(
{
}

/// <summary>
/// Return a port given its ID
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
public async Task<Port> GetAsync(long id)
{
// Request the specified port
string baseRoute = @$"{Settings.ApiRoutes.First(r => r.Name == RouteKey).Route}";
var route = $"{baseRoute}/{id}";
string json = await SendDirectAsync(route, null, HttpMethod.Get);
Port port = Deserialize<Port>(json);
return port;
}

/// <summary>
/// Return a port given a UN/LOCODE
/// </summary>
Expand All @@ -40,7 +55,6 @@ public async Task<Port> GetAsync(string code)
Port port = Deserialize<Port>(json);
return port;
}


/// <summary>
/// Add a new port to the database
Expand Down Expand Up @@ -110,11 +124,11 @@ public async Task DeleteAsync(long id)
/// <param name="pageNumber"></param>
/// <param name="pageSize"></param>
/// <returns></returns>
public async Task<List<Port>> ListAsync(long countryId, int pageNumber, int pageSize)
public async Task<List<Port>> ListAsync(long? countryId, int pageNumber, int pageSize)
{
// Request a list of countries
string baseRoute = @$"{Settings.ApiRoutes.First(r => r.Name == RouteKey).Route}";
var route = $"{baseRoute}/{countryId}/{pageNumber}/{pageSize}";
var route = $"{baseRoute}/{countryId ?? 0}/{pageNumber}/{pageSize}";
string json = await SendDirectAsync(route, null, HttpMethod.Get);

// The returned JSON will be empty if there are no countries in the database
Expand Down
6 changes: 6 additions & 0 deletions src/ShippingRecorder.Client/Interfaces/IExportClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace ShippingRecorder.Client.Interfaces
{
public interface IExportClient : IExporter
{
}
}
3 changes: 2 additions & 1 deletion src/ShippingRecorder.Client/Interfaces/IPortClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ namespace ShippingRecorder.Client.Interfaces
{
public interface IPortClient : IPortsRetriever, IImporter, IExporter
{
Task<Port> GetAsync(long id);
Task<Port> AddAsync(long countryId, string code, string name);
Task DeleteAsync(long id);
Task<List<Port>> ListAsync(long countryId, int pageNumber, int pageSize);
Task<List<Port>> ListAsync(long? countryId, int pageNumber, int pageSize);
Task<Port> UpdateAsync(long id, long countryId, string code, string name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public abstract class DataExchangeControllerBase : ShippingRecorderControllerBas

public DataExchangeControllerBase(
ICountryClient countryClient,
IExportClient exportClient,
ILocationClient locationClient,
IOperatorClient operatorClient,
IPortClient portClient,
Expand All @@ -42,6 +43,7 @@ public DataExchangeControllerBase(
_importers.Add(DataExchangeType.VesselTypes, vesselTypeClient);
_importers.Add(DataExchangeType.Voyages, voyageClient);

_exporters.Add(DataExchangeType.All, exportClient);
_exporters.Add(DataExchangeType.Countries, countryClient);
_exporters.Add(DataExchangeType.Locations, locationClient);
_exporters.Add(DataExchangeType.Operators, operatorClient);
Expand Down
2 changes: 2 additions & 0 deletions src/ShippingRecorder.Mvc/Controllers/ExportController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class ExportController : DataExchangeControllerBase
{
public ExportController(
ICountryClient countryClient,
IExportClient exportClient,
ILocationClient locationClient,
IOperatorClient operatorClient,
IPortClient portClient,
Expand All @@ -22,6 +23,7 @@ public ExportController(
IPartialViewToStringRenderer renderer,
ILogger<ExportController> logger) : base(
countryClient,
exportClient,
locationClient,
operatorClient,
portClient,
Expand Down
2 changes: 2 additions & 0 deletions src/ShippingRecorder.Mvc/Controllers/ImportController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class ImportController : DataExchangeControllerBase

public ImportController(
ICountryClient countryClient,
IExportClient exportClient,
ILocationClient locationClient,
IOperatorClient operatorClient,
IPortClient portClient,
Expand All @@ -25,6 +26,7 @@ public ImportController(
IPartialViewToStringRenderer renderer,
ILogger<ImportController> logger) : base(
countryClient,
exportClient,
locationClient,
operatorClient,
portClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public async Task<IActionResult> Index(LocationListViewModel model)
// and amend the page number, above, then apply it, below
ModelState.Clear();

// Retrieve the matching airport records
// Retrieve the matching location records
var locations = await _client.ListAsync(page, _settings.SearchPageSize);
model.SetLocations(locations, page, _settings.SearchPageSize);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public async Task<IActionResult> Index(OperatorListViewModel model)
// and amend the page number, above, then apply it, below
ModelState.Clear();

// Retrieve the matching airport records
// Retrieve the matching operator records
var operators = await _client.ListAsync(page, _settings.SearchPageSize);
model.SetOperators(operators, page, _settings.SearchPageSize);
}
Expand Down
Loading