Version 3.0.338

This commit is contained in:
Anja Müller-Meißner 2022-09-06 16:08:19 +02:00 committed by Anja
parent 573fe77e12
commit 0468955d49
751 changed files with 62747 additions and 60672 deletions

View file

@ -3,25 +3,25 @@ using TINK.Repository;
namespace TINK.Model.Connector
{
/// <summary>
/// Provides information required for copri commands/ query operations.
/// </summary>
public class Base
{
/// <summary> Reference to object which provides access to copri server. </summary>
protected ICopriServerBase CopriServer { get; }
/// <summary>
/// Provides information required for copri commands/ query operations.
/// </summary>
public class Base
{
/// <summary> Reference to object which provides access to copri server. </summary>
protected ICopriServerBase CopriServer { get; }
/// <summary> Gets the merchant id.</summary>
protected string MerchantId => CopriServer.MerchantId;
/// <summary> Gets the merchant id.</summary>
protected string MerchantId => CopriServer.MerchantId;
/// <summary> Constructs a query base object.</summary>
/// <param name="p_oCopriServer">Server which implements communication.</param>
/// <param name="p_oErrorStack">Object which hold communication objects.</param>
protected Base(
ICopriServerBase p_oCopriServer)
{
CopriServer = p_oCopriServer
?? throw new ArgumentException("Can not instantiate command/ query base- object. Copri server object must never be null or emtpy.");
}
}
/// <summary> Constructs a query base object.</summary>
/// <param name="p_oCopriServer">Server which implements communication.</param>
/// <param name="p_oErrorStack">Object which hold communication objects.</param>
protected Base(
ICopriServerBase p_oCopriServer)
{
CopriServer = p_oCopriServer
?? throw new ArgumentException("Can not instantiate command/ query base- object. Copri server object must never be null or emtpy.");
}
}
}

View file

@ -3,37 +3,37 @@ using TINK.Repository;
namespace TINK.Model.Connector
{
/// <summary>Holds user infromation required for copri related commands/ query operations. </summary>
public class BaseLoggedIn : Base
{
/// <summary>Session cookie used to sign in to copri.</summary>
public string SessionCookie { get; }
/// <summary>Holds user infromation required for copri related commands/ query operations. </summary>
public class BaseLoggedIn : Base
{
/// <summary>Session cookie used to sign in to copri.</summary>
public string SessionCookie { get; }
/// <summary> Mail address of the user. </summary>
protected string Mail { get; }
/// <summary> Mail address of the user. </summary>
protected string Mail { get; }
/// <summary> Object which provides date time info. </summary>
protected readonly Func<DateTime> DateTimeProvider;
/// <summary> Object which provides date time info. </summary>
protected readonly Func<DateTime> DateTimeProvider;
/// <summary>Constructs a copri query object.</summary>
/// <param name="copriServer">Server which implements communication.</param>
public BaseLoggedIn(ICopriServerBase copriServer,
string sessionCookie,
string mail,
Func<DateTime> p_oDateTimeProvider) : base(copriServer)
{
if (string.IsNullOrEmpty(sessionCookie))
throw new ArgumentException("Can not instantiate query object- object. Session cookie must never be null or emtpy.");
/// <summary>Constructs a copri query object.</summary>
/// <param name="copriServer">Server which implements communication.</param>
public BaseLoggedIn(ICopriServerBase copriServer,
string sessionCookie,
string mail,
Func<DateTime> p_oDateTimeProvider) : base(copriServer)
{
if (string.IsNullOrEmpty(sessionCookie))
throw new ArgumentException("Can not instantiate query object- object. Session cookie must never be null or emtpy.");
if (string.IsNullOrEmpty(mail))
throw new ArgumentException("Can not instantiate query object- object. Mail address must never be null or emtpy.");
if (string.IsNullOrEmpty(mail))
throw new ArgumentException("Can not instantiate query object- object. Mail address must never be null or emtpy.");
DateTimeProvider = p_oDateTimeProvider
?? throw new ArgumentException("Can not instantiate connector- object. No date time provider object available.");
DateTimeProvider = p_oDateTimeProvider
?? throw new ArgumentException("Can not instantiate connector- object. No date time provider object available.");
SessionCookie = sessionCookie;
SessionCookie = sessionCookie;
Mail = mail;
}
}
Mail = mail;
}
}
}

View file

@ -11,82 +11,82 @@ using BikeInfo = TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo;
namespace TINK.Model.Connector
{
public class CachedQuery : Base, IQuery
{
/// <summary> Cached copri server. </summary>
private readonly ICachedCopriServer server;
public class CachedQuery : Base, IQuery
{
/// <summary> Cached copri server. </summary>
private readonly ICachedCopriServer server;
/// <summary>Constructs a copri query object.</summary>
/// <param name="copriServer">Server which implements communication.</param>
public CachedQuery(
ICopriServerBase copriServer) : base(copriServer)
{
server = copriServer as ICachedCopriServer;
if (server == null)
{
throw new ArgumentException($"Copri server is not of expected typ. Type detected is {copriServer.GetType()}.");
}
}
/// <summary>Constructs a copri query object.</summary>
/// <param name="copriServer">Server which implements communication.</param>
public CachedQuery(
ICopriServerBase copriServer) : base(copriServer)
{
server = copriServer as ICachedCopriServer;
if (server == null)
{
throw new ArgumentException($"Copri server is not of expected typ. Type detected is {copriServer.GetType()}.");
}
}
/// <summary> Gets all stations including postions and bikes.</summary>
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
{
var resultStations = await server.GetStations();
/// <summary> Gets all stations including postions and bikes.</summary>
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
{
var resultStations = await server.GetStations();
if (resultStations.Source == typeof(CopriCallsMonkeyStore))
{
// Communication with copri in order to get stations failed.
return new Result<StationsAndBikesContainer>(
resultStations.Source,
new StationsAndBikesContainer(
resultStations.Response.GetStationsAllMutable(),
(await server.GetBikesAvailable(true)).Response.GetBikesAvailable()),
resultStations.GeneralData,
resultStations.Exception);
}
if (resultStations.Source == typeof(CopriCallsMonkeyStore))
{
// Communication with copri in order to get stations failed.
return new Result<StationsAndBikesContainer>(
resultStations.Source,
new StationsAndBikesContainer(
resultStations.Response.GetStationsAllMutable(),
(await server.GetBikesAvailable(true)).Response.GetBikesAvailable()),
resultStations.GeneralData,
resultStations.Exception);
}
var resultBikes = await server.GetBikesAvailable();
if (resultBikes.Source == typeof(CopriCallsMonkeyStore))
{
// Communication with copri in order to get bikes failed.
return new Result<StationsAndBikesContainer>(
resultBikes.Source,
new StationsAndBikesContainer(
(await server.GetStations(true)).Response.GetStationsAllMutable(),
resultBikes.Response.GetBikesAvailable()),
resultBikes.GeneralData,
resultBikes.Exception);
}
var resultBikes = await server.GetBikesAvailable();
if (resultBikes.Source == typeof(CopriCallsMonkeyStore))
{
// Communication with copri in order to get bikes failed.
return new Result<StationsAndBikesContainer>(
resultBikes.Source,
new StationsAndBikesContainer(
(await server.GetStations(true)).Response.GetStationsAllMutable(),
resultBikes.Response.GetBikesAvailable()),
resultBikes.GeneralData,
resultBikes.Exception);
}
// Communicatin with copri succeeded.
server.AddToCache(resultStations);
server.AddToCache(resultBikes);
// Communicatin with copri succeeded.
server.AddToCache(resultStations);
server.AddToCache(resultBikes);
return new Result<StationsAndBikesContainer>(
resultStations.Source,
new StationsAndBikesContainer(resultStations.Response.GetStationsAllMutable(), resultBikes.Response.GetBikesAvailable()),
resultStations.GeneralData);
}
return new Result<StationsAndBikesContainer>(
resultStations.Source,
new StationsAndBikesContainer(resultStations.Response.GetStationsAllMutable(), resultBikes.Response.GetBikesAvailable()),
resultStations.GeneralData);
}
/// <summary> Gets bikes occupied. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesOccupiedAsync()
{
Log.ForContext<CachedQuery>().Error("Unexpected call to get be bikes occpied detected. No user is logged in.");
return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore),
await Task.FromResult(new BikeCollection(new Dictionary<string, BikeInfo>())),
new GeneralData(),
new Exception("Abfrage der reservierten/ gebuchten Räder nicht möglich. Kein Benutzer angemeldet."));
}
/// <summary> Gets bikes occupied. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesOccupiedAsync()
{
Log.ForContext<CachedQuery>().Error("Unexpected call to get be bikes occpied detected. No user is logged in.");
return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore),
await Task.FromResult(new BikeCollection(new Dictionary<string, BikeInfo>())),
new GeneralData(),
new Exception("Abfrage der reservierten/ gebuchten Räder nicht möglich. Kein Benutzer angemeldet."));
}
/// <summary> Gets bikes available. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesAsync()
{
var result = await server.GetBikesAvailable();
server.AddToCache(result);
return new Result<BikeCollection>(result.Source, result.Response.GetBikesAvailable(), result.GeneralData, result.Exception);
}
}
/// <summary> Gets bikes available. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesAsync()
{
var result = await server.GetBikesAvailable();
server.AddToCache(result);
return new Result<BikeCollection>(result.Source, result.Response.GetBikesAvailable(), result.GeneralData, result.Exception);
}
}
}

View file

@ -9,210 +9,210 @@ using TINK.Repository;
namespace TINK.Model.Connector
{
/// <summary> Provides query functionality for a logged in user. </summary>
public class CachedQueryLoggedIn : BaseLoggedIn, IQuery
{
/// <summary> Cached copri server. </summary>
private ICachedCopriServer Server { get; }
/// <summary> Provides query functionality for a logged in user. </summary>
public class CachedQueryLoggedIn : BaseLoggedIn, IQuery
{
/// <summary> Cached copri server. </summary>
private ICachedCopriServer Server { get; }
/// <summary>Constructs a copri query object.</summary>
/// <param name="copriServer">Server which implements communication.</param>
public CachedQueryLoggedIn(ICopriServerBase copriServer,
string sessionCookie,
string mail,
Func<DateTime> dateTimeProvider) : base(copriServer, sessionCookie, mail, dateTimeProvider)
{
Server = copriServer as ICachedCopriServer;
if (Server == null)
{
throw new ArgumentException($"Copri server is not of expected typ. Type detected is {copriServer.GetType()}.");
}
}
/// <summary>Constructs a copri query object.</summary>
/// <param name="copriServer">Server which implements communication.</param>
public CachedQueryLoggedIn(ICopriServerBase copriServer,
string sessionCookie,
string mail,
Func<DateTime> dateTimeProvider) : base(copriServer, sessionCookie, mail, dateTimeProvider)
{
Server = copriServer as ICachedCopriServer;
if (Server == null)
{
throw new ArgumentException($"Copri server is not of expected typ. Type detected is {copriServer.GetType()}.");
}
}
/// <summary> Gets all stations including postions.</summary>
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
{
var stationsResponse = await Server.GetStations();
/// <summary> Gets all stations including postions.</summary>
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
{
var stationsResponse = await Server.GetStations();
if (stationsResponse.Source == typeof(CopriCallsMonkeyStore)
|| stationsResponse.Exception != null)
{
// Stations were read from cache ==> get bikes availbalbe and occupied from cache as well to avoid inconsistencies
return new Result<StationsAndBikesContainer>(
stationsResponse.Source,
new StationsAndBikesContainer(
stationsResponse.Response.GetStationsAllMutable(),
UpdaterJSON.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values,
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider)),
stationsResponse.GeneralData,
stationsResponse.Exception);
}
if (stationsResponse.Source == typeof(CopriCallsMonkeyStore)
|| stationsResponse.Exception != null)
{
// Stations were read from cache ==> get bikes availbalbe and occupied from cache as well to avoid inconsistencies
return new Result<StationsAndBikesContainer>(
stationsResponse.Source,
new StationsAndBikesContainer(
stationsResponse.Response.GetStationsAllMutable(),
UpdaterJSON.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values,
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider)),
stationsResponse.GeneralData,
stationsResponse.Exception);
}
var bikesAvailableResponse = await Server.GetBikesAvailable();
if (bikesAvailableResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesAvailableResponse.Exception != null)
{
// Bikes avilable were read from cache ==> get bikes occupied from cache as well to avoid inconsistencies
return new Result<StationsAndBikesContainer>(
bikesAvailableResponse.Source,
new StationsAndBikesContainer(
(await Server.GetStations(true)).Response.GetStationsAllMutable(),
UpdaterJSON.GetBikesAll(bikesAvailableResponse.Response?.bikes?.Values,
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider)),
bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception);
}
var bikesAvailableResponse = await Server.GetBikesAvailable();
if (bikesAvailableResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesAvailableResponse.Exception != null)
{
// Bikes avilable were read from cache ==> get bikes occupied from cache as well to avoid inconsistencies
return new Result<StationsAndBikesContainer>(
bikesAvailableResponse.Source,
new StationsAndBikesContainer(
(await Server.GetStations(true)).Response.GetStationsAllMutable(),
UpdaterJSON.GetBikesAll(bikesAvailableResponse.Response?.bikes?.Values,
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider)),
bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception);
}
var bikesOccupiedResponse = await Server.GetBikesOccupied();
if (bikesOccupiedResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesOccupiedResponse.Exception != null)
{
// Bikes occupied were read from cache ==> get bikes available from cache as well to avoid inconsistencies
return new Result<StationsAndBikesContainer>(
bikesOccupiedResponse.Source,
new StationsAndBikesContainer(
(await Server.GetStations(true)).Response.GetStationsAllMutable(),
UpdaterJSON.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider)),
bikesOccupiedResponse.GeneralData,
bikesOccupiedResponse.Exception);
}
var bikesOccupiedResponse = await Server.GetBikesOccupied();
if (bikesOccupiedResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesOccupiedResponse.Exception != null)
{
// Bikes occupied were read from cache ==> get bikes available from cache as well to avoid inconsistencies
return new Result<StationsAndBikesContainer>(
bikesOccupiedResponse.Source,
new StationsAndBikesContainer(
(await Server.GetStations(true)).Response.GetStationsAllMutable(),
UpdaterJSON.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider)),
bikesOccupiedResponse.GeneralData,
bikesOccupiedResponse.Exception);
}
// Both types bikes could read from copri => update cache
Server.AddToCache(stationsResponse);
Server.AddToCache(bikesAvailableResponse);
Server.AddToCache(bikesOccupiedResponse);
// Both types bikes could read from copri => update cache
Server.AddToCache(stationsResponse);
Server.AddToCache(bikesAvailableResponse);
Server.AddToCache(bikesOccupiedResponse);
var exceptions = new[] { stationsResponse?.Exception, bikesAvailableResponse?.Exception, bikesOccupiedResponse?.Exception }.Where(x => x != null).ToArray();
var exceptions = new[] { stationsResponse?.Exception, bikesAvailableResponse?.Exception, bikesOccupiedResponse?.Exception }.Where(x => x != null).ToArray();
var stationsMutable = stationsResponse.Response.GetStationsAllMutable();
var bikesMutable = UpdaterJSON.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider);
var stationsMutable = stationsResponse.Response.GetStationsAllMutable();
var bikesMutable = UpdaterJSON.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider);
return new Result<StationsAndBikesContainer>(
stationsResponse.Source,
new StationsAndBikesContainer(stationsMutable, bikesMutable),
stationsResponse.GeneralData,
exceptions.Length > 0 ? new AggregateException(exceptions) : null);
}
return new Result<StationsAndBikesContainer>(
stationsResponse.Source,
new StationsAndBikesContainer(stationsMutable, bikesMutable),
stationsResponse.GeneralData,
exceptions.Length > 0 ? new AggregateException(exceptions) : null);
}
/// <summary> Gets bikes occupied. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesOccupiedAsync()
{
var bikesAvailableResponse = await Server.GetBikesAvailable(false);
if (bikesAvailableResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesAvailableResponse.Exception != null)
{
// Bikes available were read from cache ==> get bikes occupied from cache as well to avoid inconsistencies.
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available read from cache. Reading bikes occupied from cache as well.");
return new Result<BikeCollection>(
bikesAvailableResponse.Source,
UpdaterJSON.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending),
(await Server.GetBikesOccupied(true))?.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception);
}
/// <summary> Gets bikes occupied. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesOccupiedAsync()
{
var bikesAvailableResponse = await Server.GetBikesAvailable(false);
if (bikesAvailableResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesAvailableResponse.Exception != null)
{
// Bikes available were read from cache ==> get bikes occupied from cache as well to avoid inconsistencies.
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available read from cache. Reading bikes occupied from cache as well.");
return new Result<BikeCollection>(
bikesAvailableResponse.Source,
UpdaterJSON.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending),
(await Server.GetBikesOccupied(true))?.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception);
}
var bikesOccupiedResponse = await Server.GetBikesOccupied(false);
if (bikesOccupiedResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesOccupiedResponse.Exception != null)
{
// Bikes occupied were read from cache ==> get bikes available from cache as well to avoid inconsistencies
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes occupied read from cache. Reread bikes available from cache as well.");
return new Result<BikeCollection>(
bikesOccupiedResponse.Source,
UpdaterJSON.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending),
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesOccupiedResponse.GeneralData,
bikesOccupiedResponse.Exception);
}
var bikesOccupiedResponse = await Server.GetBikesOccupied(false);
if (bikesOccupiedResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesOccupiedResponse.Exception != null)
{
// Bikes occupied were read from cache ==> get bikes available from cache as well to avoid inconsistencies
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes occupied read from cache. Reread bikes available from cache as well.");
return new Result<BikeCollection>(
bikesOccupiedResponse.Source,
UpdaterJSON.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending),
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesOccupiedResponse.GeneralData,
bikesOccupiedResponse.Exception);
}
// Both types bikes could read from copri => update bikes occupied cache.
// // Do not add bikes available to cache because this might lead to conflicts calls GetBikesAsync() and bikes with FeedbackPending state are of no use offline.
Server.AddToCache(bikesOccupiedResponse);
// Both types bikes could read from copri => update bikes occupied cache.
// // Do not add bikes available to cache because this might lead to conflicts calls GetBikesAsync() and bikes with FeedbackPending state are of no use offline.
Server.AddToCache(bikesOccupiedResponse);
return new Result<BikeCollection>(
bikesOccupiedResponse.Source,
UpdaterJSON.GetBikesAll(
bikesAvailableResponse?.Response.bikes?.Values?.Select(bike => bike)?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending),
bikesOccupiedResponse?.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesOccupiedResponse.GeneralData,
bikesOccupiedResponse.Exception);
}
return new Result<BikeCollection>(
bikesOccupiedResponse.Source,
UpdaterJSON.GetBikesAll(
bikesAvailableResponse?.Response.bikes?.Values?.Select(bike => bike)?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending),
bikesOccupiedResponse?.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesOccupiedResponse.GeneralData,
bikesOccupiedResponse.Exception);
}
/// <summary> Gets bikes available and bikes occupied. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesAsync()
{
var bikesAvailableResponse = await Server.GetBikesAvailable();
/// <summary> Gets bikes available and bikes occupied. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesAsync()
{
var bikesAvailableResponse = await Server.GetBikesAvailable();
if (bikesAvailableResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesAvailableResponse.Exception != null)
{
// Bikes available were read from cache ==> get bikes occupied from cache as well to avoid inconsistencies.
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available read from cache. Reading bikes occupied from cache as well.");
return new Result<BikeCollection>(
bikesAvailableResponse.Source,
UpdaterJSON.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values,
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception);
}
if (bikesAvailableResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesAvailableResponse.Exception != null)
{
// Bikes available were read from cache ==> get bikes occupied from cache as well to avoid inconsistencies.
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available read from cache. Reading bikes occupied from cache as well.");
return new Result<BikeCollection>(
bikesAvailableResponse.Source,
UpdaterJSON.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values,
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception);
}
var bikesOccupiedResponse = await Server.GetBikesOccupied();
if (bikesOccupiedResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesOccupiedResponse.Exception != null)
{
// Bikes occupied were read from cache ==> get bikes available from cache as well to avoid inconsistencies
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes occupied read from cache. Reread bikes available from cache as well.");
return new Result<BikeCollection>(
bikesOccupiedResponse.Source,
UpdaterJSON.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesOccupiedResponse.GeneralData,
bikesOccupiedResponse.Exception);
}
var bikesOccupiedResponse = await Server.GetBikesOccupied();
if (bikesOccupiedResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesOccupiedResponse.Exception != null)
{
// Bikes occupied were read from cache ==> get bikes available from cache as well to avoid inconsistencies
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes occupied read from cache. Reread bikes available from cache as well.");
return new Result<BikeCollection>(
bikesOccupiedResponse.Source,
UpdaterJSON.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesOccupiedResponse.GeneralData,
bikesOccupiedResponse.Exception);
}
// Both types bikes could read from copri => update cache
Server.AddToCache(bikesAvailableResponse);
Server.AddToCache(bikesOccupiedResponse);
// Both types bikes could read from copri => update cache
Server.AddToCache(bikesAvailableResponse);
Server.AddToCache(bikesOccupiedResponse);
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available and occupied read successfully from server.");
return new Result<BikeCollection>(
bikesAvailableResponse.Source,
UpdaterJSON.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception != null || bikesOccupiedResponse.Exception != null ? new AggregateException(new[] { bikesAvailableResponse.Exception, bikesOccupiedResponse.Exception }) : null);
}
}
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available and occupied read successfully from server.");
return new Result<BikeCollection>(
bikesAvailableResponse.Source,
UpdaterJSON.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception != null || bikesOccupiedResponse.Exception != null ? new AggregateException(new[] { bikesAvailableResponse.Exception, bikesOccupiedResponse.Exception }) : null);
}
}
}

View file

@ -4,17 +4,17 @@ using TINK.Model.Services.CopriApi;
namespace TINK.Model.Connector
{
public interface IQuery
{
/// <summary> Gets all stations including postions.</summary>
Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync();
public interface IQuery
{
/// <summary> Gets all stations including postions.</summary>
Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync();
/// <summary> Gets bikes occupied is a user is logged in. </summary>
/// <returns>Collection of bikes.</returns>
Task<Result<BikeCollection>> GetBikesOccupiedAsync();
/// <summary> Gets bikes occupied is a user is logged in. </summary>
/// <returns>Collection of bikes.</returns>
Task<Result<BikeCollection>> GetBikesOccupiedAsync();
/// <summary> Gets bikes either bikes available if no user is logged in or bikes available and bikes occupied if a user is logged in. </summary>
/// <returns>Collection of bikes.</returns>
Task<Result<BikeCollection>> GetBikesAsync();
}
/// <summary> Gets bikes either bikes available if no user is logged in or bikes available and bikes occupied if a user is logged in. </summary>
/// <returns>Collection of bikes.</returns>
Task<Result<BikeCollection>> GetBikesAsync();
}
}

View file

@ -11,56 +11,56 @@ using BikeInfo = TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo;
namespace TINK.Model.Connector
{
/// <summary> Provides query functionality without login. </summary>
public class Query : Base, IQuery
{
/// <summary> Cached copri server. </summary>
private readonly ICopriServer server;
/// <summary> Provides query functionality without login. </summary>
public class Query : Base, IQuery
{
/// <summary> Cached copri server. </summary>
private readonly ICopriServer server;
/// <summary>Constructs a copri query object.</summary>
/// <param name="p_oCopriServer">Server which implements communication.</param>
public Query(ICopriServerBase p_oCopriServer) : base(p_oCopriServer)
{
server = p_oCopriServer as ICopriServer;
if (server == null)
{
throw new ArgumentException($"Copri server is not of expected typ. Type detected is {p_oCopriServer.GetType()}.");
}
}
/// <summary>Constructs a copri query object.</summary>
/// <param name="p_oCopriServer">Server which implements communication.</param>
public Query(ICopriServerBase p_oCopriServer) : base(p_oCopriServer)
{
server = p_oCopriServer as ICopriServer;
if (server == null)
{
throw new ArgumentException($"Copri server is not of expected typ. Type detected is {p_oCopriServer.GetType()}.");
}
}
/// <summary> Gets all stations including postions.</summary>
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
{
var stationsAllResponse = await server.GetStationsAsync();
var bikesAvailableResponse = await server.GetBikesAvailableAsync();
/// <summary> Gets all stations including postions.</summary>
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
{
var stationsAllResponse = await server.GetStationsAsync();
var bikesAvailableResponse = await server.GetBikesAvailableAsync();
return new Result<StationsAndBikesContainer>(
typeof(CopriCallsMonkeyStore),
new StationsAndBikesContainer(stationsAllResponse.GetStationsAllMutable(), bikesAvailableResponse.GetBikesAvailable()),
stationsAllResponse.GetGeneralData());
}
return new Result<StationsAndBikesContainer>(
typeof(CopriCallsMonkeyStore),
new StationsAndBikesContainer(stationsAllResponse.GetStationsAllMutable(), bikesAvailableResponse.GetBikesAvailable()),
stationsAllResponse.GetGeneralData());
}
/// <summary> Gets bikes occupied. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesOccupiedAsync()
{
Log.ForContext<Query>().Error("Unexpected call to get be bikes occpied detected. No user is logged in.");
return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore),
await Task.FromResult(new BikeCollection(new Dictionary<string, BikeInfo>())),
new GeneralData(),
new Exception("Abfrage der reservierten/ gebuchten Räder fehlgeschlagen. Kein Benutzer angemeldet."));
}
/// <summary> Gets bikes occupied. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesOccupiedAsync()
{
Log.ForContext<Query>().Error("Unexpected call to get be bikes occpied detected. No user is logged in.");
return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore),
await Task.FromResult(new BikeCollection(new Dictionary<string, BikeInfo>())),
new GeneralData(),
new Exception("Abfrage der reservierten/ gebuchten Räder fehlgeschlagen. Kein Benutzer angemeldet."));
}
/// <summary> Gets bikes occupied. </summary>
/// <returns> Collection of bikes. </returns>
public async Task<Result<BikeCollection>> GetBikesAsync()
{
var bikesAvailableResponse = await server.GetBikesAvailableAsync();
return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore),
bikesAvailableResponse.GetBikesAvailable(),
bikesAvailableResponse.GetGeneralData());
}
}
/// <summary> Gets bikes occupied. </summary>
/// <returns> Collection of bikes. </returns>
public async Task<Result<BikeCollection>> GetBikesAsync()
{
var bikesAvailableResponse = await server.GetBikesAvailableAsync();
return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore),
bikesAvailableResponse.GetBikesAvailable(),
bikesAvailableResponse.GetGeneralData());
}
}
}

View file

@ -8,79 +8,79 @@ using TINK.Repository;
namespace TINK.Model.Connector
{
/// <summary> Provides query functionality for a logged in user. </summary>
public class QueryLoggedIn : BaseLoggedIn, IQuery
{
/// <summary> Copri server. </summary>
private readonly ICopriServer server;
/// <summary> Provides query functionality for a logged in user. </summary>
public class QueryLoggedIn : BaseLoggedIn, IQuery
{
/// <summary> Copri server. </summary>
private readonly ICopriServer server;
/// <summary>Constructs a copri query object.</summary>
/// <param name="copriServer">Server which implements communication.</param>
public QueryLoggedIn(ICopriServerBase copriServer,
string sessionCookie,
string mail,
Func<DateTime> dateTimeProvider) : base(copriServer, sessionCookie, mail, dateTimeProvider)
{
server = copriServer as ICopriServer;
if (server == null)
{
throw new ArgumentException($"Copri server is not of expected typ. Type detected is {copriServer.GetType()}.");
}
/// <summary>Constructs a copri query object.</summary>
/// <param name="copriServer">Server which implements communication.</param>
public QueryLoggedIn(ICopriServerBase copriServer,
string sessionCookie,
string mail,
Func<DateTime> dateTimeProvider) : base(copriServer, sessionCookie, mail, dateTimeProvider)
{
server = copriServer as ICopriServer;
if (server == null)
{
throw new ArgumentException($"Copri server is not of expected typ. Type detected is {copriServer.GetType()}.");
}
server = copriServer as ICopriServer;
}
server = copriServer as ICopriServer;
}
/// <summary> Gets all stations including postions.</summary>
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
{
var stationResponse = await server.GetStationsAsync();
var bikesAvailableResponse = await server.GetBikesAvailableAsync();
var bikesOccupiedResponse = await server.GetBikesOccupiedAsync();
/// <summary> Gets all stations including postions.</summary>
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
{
var stationResponse = await server.GetStationsAsync();
var bikesAvailableResponse = await server.GetBikesAvailableAsync();
var bikesOccupiedResponse = await server.GetBikesOccupiedAsync();
return new Result<StationsAndBikesContainer>(
typeof(CopriCallsMonkeyStore),
new StationsAndBikesContainer(
stationResponse.GetStationsAllMutable(),
UpdaterJSON.GetBikesAll(
bikesAvailableResponse?.bikes?.Values,
bikesOccupiedResponse?.bikes_occupied?.Values,
Mail,
DateTimeProvider)),
stationResponse.GetGeneralData());
}
return new Result<StationsAndBikesContainer>(
typeof(CopriCallsMonkeyStore),
new StationsAndBikesContainer(
stationResponse.GetStationsAllMutable(),
UpdaterJSON.GetBikesAll(
bikesAvailableResponse?.bikes?.Values,
bikesOccupiedResponse?.bikes_occupied?.Values,
Mail,
DateTimeProvider)),
stationResponse.GetGeneralData());
}
/// <summary> Gets bikes occupied and bikes for which feedback is required. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesOccupiedAsync()
{
var bikesFeedbackRequired = await server.GetBikesAvailableAsync();
var bikesOccupiedResponse = await server.GetBikesOccupiedAsync();
/// <summary> Gets bikes occupied and bikes for which feedback is required. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesOccupiedAsync()
{
var bikesFeedbackRequired = await server.GetBikesAvailableAsync();
var bikesOccupiedResponse = await server.GetBikesOccupiedAsync();
return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore),
UpdaterJSON.GetBikesAll(
bikesFeedbackRequired.bikes?.Values?.Select(bike => bike)?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending),
bikesOccupiedResponse?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesOccupiedResponse.GetGeneralData());
}
return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore),
UpdaterJSON.GetBikesAll(
bikesFeedbackRequired.bikes?.Values?.Select(bike => bike)?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending),
bikesOccupiedResponse?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesOccupiedResponse.GetGeneralData());
}
/// <summary> Gets bikes available and bikes occupied. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesAsync()
{
var bikesAvailableResponse = await server.GetBikesAvailableAsync();
var bikesOccupiedResponse = await server.GetBikesOccupiedAsync();
/// <summary> Gets bikes available and bikes occupied. </summary>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesAsync()
{
var bikesAvailableResponse = await server.GetBikesAvailableAsync();
var bikesOccupiedResponse = await server.GetBikesOccupiedAsync();
return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore),
UpdaterJSON.GetBikesAll(
bikesAvailableResponse?.bikes?.Values,
bikesOccupiedResponse?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesAvailableResponse.GetGeneralData());
}
}
return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore),
UpdaterJSON.GetBikesAll(
bikesAvailableResponse?.bikes?.Values,
bikesOccupiedResponse?.bikes_occupied?.Values,
Mail,
DateTimeProvider),
bikesAvailableResponse.GetGeneralData());
}
}
}