mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2024-12-23 07:36:31 +01:00
786 lines
32 KiB
C#
786 lines
32 KiB
C#
|
|
|||
|
using Serilog;
|
|||
|
using System;
|
|||
|
using System.IO;
|
|||
|
using System.Net;
|
|||
|
using System.Text;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using TINK.Model.Repository.Exception;
|
|||
|
using TINK.Model.Repository.Request;
|
|||
|
using TINK.Model.Repository.Response;
|
|||
|
using TINK.Model.Logging;
|
|||
|
using TINK.Repository.Response;
|
|||
|
|
|||
|
namespace TINK.Model.Repository
|
|||
|
{
|
|||
|
/// <summary> Object which manages calls to copri. </summary>
|
|||
|
public class CopriCallsHttps : ICopriServer
|
|||
|
{
|
|||
|
/// <summary> Builds requests.</summary>
|
|||
|
private IRequestBuilder requestBuilder;
|
|||
|
|
|||
|
/// <summary> Initializes a instance of the copri calls https object. </summary>
|
|||
|
/// <param name="p_oCopriHost">Host to connect to. </param>
|
|||
|
/// <param name="p_strMerchantId">Id of the merchant.</param>
|
|||
|
/// <param name="userAgent">Holds the name and version of the TINKApp.</param>
|
|||
|
/// <param name="sessionCookie">Session cookie if user is logged in, null otherwise.</param>
|
|||
|
public CopriCallsHttps(
|
|||
|
Uri p_oCopriHost,
|
|||
|
string p_strMerchantId,
|
|||
|
string userAgent,
|
|||
|
string sessionCookie = null)
|
|||
|
{
|
|||
|
m_oCopriHost = p_oCopriHost
|
|||
|
?? throw new System.Exception($"Can not construct {GetType().ToString()}- object. Uri of copri host must not be null.");
|
|||
|
|
|||
|
UserAgent = !string.IsNullOrEmpty(userAgent)
|
|||
|
? userAgent
|
|||
|
: throw new System.Exception($"Can not construct {GetType().ToString()}- object. User agent must not be null or empty.");
|
|||
|
|
|||
|
requestBuilder = string.IsNullOrEmpty(sessionCookie)
|
|||
|
? new RequestBuilder(p_strMerchantId) as IRequestBuilder
|
|||
|
: new RequestBuilderLoggedIn(p_strMerchantId, sessionCookie);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Holds the URL for rest calls.</summary>
|
|||
|
private Uri m_oCopriHost;
|
|||
|
|
|||
|
/// <summary> Spacifies name and version of app. </summary>
|
|||
|
private string UserAgent { get; }
|
|||
|
|
|||
|
/// <summary> Returns true because value requested form copri server are returned. </summary>
|
|||
|
public bool IsConnected => true;
|
|||
|
|
|||
|
/// <summary> Gets the merchant id.</summary>
|
|||
|
public string MerchantId => requestBuilder.MerchantId;
|
|||
|
|
|||
|
/// <summary> Gets the session cookie if user is logged in, an empty string otherwise. </summary>
|
|||
|
public string SessionCookie => requestBuilder.SessionCookie;
|
|||
|
|
|||
|
/// <summary> Logs user in. </summary>
|
|||
|
/// <param name="mailAddress">Mailaddress of user to log in.</param>
|
|||
|
/// <param name="password">Password to log in.</param>
|
|||
|
/// <param name="deviceId">Id specifying user and hardware.</param>
|
|||
|
/// <remarks>Response which holds auth cookie <see cref="ResponseBase.authcookie"/></remarks>
|
|||
|
public async Task<AuthorizationResponse> DoAuthorizationAsync(
|
|||
|
string mailAddress,
|
|||
|
string password,
|
|||
|
string deviceId)
|
|||
|
{
|
|||
|
return await DoAuthorizationAsync(
|
|||
|
m_oCopriHost.AbsoluteUri,
|
|||
|
requestBuilder.DoAuthorization(mailAddress, password, deviceId),
|
|||
|
() => requestBuilder.DoAuthorization(mailAddress, "********", deviceId),
|
|||
|
UserAgent);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Logs user out. </summary>
|
|||
|
/// <remarks>Response which holds auth cookie <see cref="ResponseBase.authcookie"/></remarks>
|
|||
|
public async Task<AuthorizationoutResponse> DoAuthoutAsync()
|
|||
|
{
|
|||
|
return await DoAuthoutAsync(m_oCopriHost.AbsoluteUri, requestBuilder.DoAuthout(), UserAgent);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>Gets bikes available.</summary>
|
|||
|
/// <returns>Response holding list of bikes.</returns>
|
|||
|
public async Task<BikesAvailableResponse> GetBikesAvailableAsync()
|
|||
|
{
|
|||
|
return await GetBikesAvailableAsync(m_oCopriHost.AbsoluteUri, requestBuilder.GetBikesAvailable(), UserAgent);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Gets a list of bikes reserved/ booked by acctive user. </summary>
|
|||
|
/// <returns>Response holding list of bikes.</returns>
|
|||
|
public async Task<BikesReservedOccupiedResponse> GetBikesOccupiedAsync()
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
return await GetBikesOccupiedAsync(m_oCopriHost.AbsoluteUri, requestBuilder.GetBikesOccupied(), UserAgent);
|
|||
|
}
|
|||
|
catch (NotSupportedException)
|
|||
|
{
|
|||
|
// No user logged in.
|
|||
|
await Task.CompletedTask;
|
|||
|
return ResponseHelper.GetBikesOccupiedNone();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Get list of stations. </summary>
|
|||
|
/// <returns>List of files.</returns>
|
|||
|
public async Task<StationsAllResponse> GetStationsAsync()
|
|||
|
{
|
|||
|
return await GetStationsAsync(m_oCopriHost.AbsoluteUri, requestBuilder.GetStations(), UserAgent);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Get authentication keys. </summary>
|
|||
|
/// <param name="bikeId">Id of the bike to get keys for.</param>
|
|||
|
/// <returns>Response holding authentication keys.</returns>
|
|||
|
public async Task<ReservationBookingResponse> GetAuthKeys(int bikeId)
|
|||
|
=> await GetAuthKeysAsync(m_oCopriHost.AbsoluteUri, requestBuilder.CalculateAuthKeys(bikeId), UserAgent);
|
|||
|
|
|||
|
|
|||
|
/// <summary> Gets booking request response.</summary>
|
|||
|
/// <param name="bikeId">Id of the bike to book.</param>
|
|||
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|||
|
/// <returns>Booking response.</returns>
|
|||
|
public async Task<ReservationBookingResponse> DoReserveAsync(
|
|||
|
int bikeId,
|
|||
|
Uri operatorUri)
|
|||
|
{
|
|||
|
return await DoReserveAsync(
|
|||
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|||
|
requestBuilder.DoReserve(bikeId),
|
|||
|
UserAgent);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Gets canel booking request response.</summary>
|
|||
|
/// <param name="bikeId">Id of the bike to book.</param>
|
|||
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|||
|
/// <returns>Response on cancel booking request.</returns>
|
|||
|
public async Task<ReservationCancelReturnResponse> DoCancelReservationAsync(
|
|||
|
int bikeId,
|
|||
|
Uri operatorUri)
|
|||
|
{
|
|||
|
return await DoCancelReservationAsync(
|
|||
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|||
|
requestBuilder.DoCancelReservation(bikeId),
|
|||
|
UserAgent);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Get authentication keys. </summary>
|
|||
|
/// <param name="bikeId">Id of the bike to get keys for.</param>
|
|||
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|||
|
/// <returns>Response holding authentication keys.</returns>
|
|||
|
public async Task<ReservationBookingResponse> CalculateAuthKeysAsync(
|
|||
|
int bikeId,
|
|||
|
Uri operatorUri)
|
|||
|
=> await GetAuthKeysAsync(
|
|||
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|||
|
requestBuilder.CalculateAuthKeys(bikeId),
|
|||
|
UserAgent);
|
|||
|
|
|||
|
/// <summary> Updates lock state for a booked bike. </summary>
|
|||
|
/// <param name="bikeId">Id of the bike to update locking state for.</param>
|
|||
|
/// <param name="location">Geolocation of lock.</param>
|
|||
|
/// <param name="state">New locking state.</param>
|
|||
|
/// <param name="batteryPercentage">Holds the filling level percentage of the battery.</param>
|
|||
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|||
|
/// <returns>Response on updating locking state.</returns>
|
|||
|
public async Task<ReservationBookingResponse> UpdateLockingStateAsync(
|
|||
|
int bikeId,
|
|||
|
LocationDto location,
|
|||
|
lock_state state,
|
|||
|
double batteryLevel,
|
|||
|
Uri operatorUri)
|
|||
|
{
|
|||
|
return await DoUpdateLockingStateAsync(
|
|||
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|||
|
requestBuilder.UpateLockingState(bikeId, location, state, batteryLevel),
|
|||
|
UserAgent);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Gets booking request request. </summary>
|
|||
|
/// <param name="bikeId">Id of the bike to book.</param>
|
|||
|
/// <param name="guid">Used to publish GUID from app to copri. Used for initial setup of bike in copri.</param>
|
|||
|
/// <param name="batteryPercentage">Holds the filling level percentage of the battery.</param>
|
|||
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|||
|
/// <returns>Requst on booking request.</returns>
|
|||
|
public async Task<ReservationBookingResponse> DoBookAsync(
|
|||
|
int bikeId,
|
|||
|
Guid guid,
|
|||
|
double batteryPercentage,
|
|||
|
Uri operatorUri)
|
|||
|
{
|
|||
|
return await DoBookAsync(
|
|||
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|||
|
requestBuilder.DoBook(bikeId, guid, batteryPercentage),
|
|||
|
UserAgent);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Returns a bike. </summary>
|
|||
|
/// <param name="bikeId">Id of the bike to return.</param>
|
|||
|
/// <param name="location">Geolocation of lock.</param>
|
|||
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|||
|
/// <returns>Response on returning request.</returns>
|
|||
|
public async Task<ReservationCancelReturnResponse> DoReturn(
|
|||
|
int bikeId,
|
|||
|
LocationDto location,
|
|||
|
Uri operatorUri)
|
|||
|
{
|
|||
|
return await DoReturn(
|
|||
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|||
|
requestBuilder.DoReturn(bikeId, location),
|
|||
|
UserAgent);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Submits feedback to copri server. </summary>
|
|||
|
/// <param name="isBikeBroken">True if bike is broken.</param>
|
|||
|
/// <param name="message">General purpose message or error description.</param>
|
|||
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|||
|
/// <returns>Response on submitting feedback request.</returns>
|
|||
|
public async Task<SubmitFeedbackResponse> DoSubmitFeedback(
|
|||
|
string message,
|
|||
|
bool isBikeBroken,
|
|||
|
Uri operatorUri) =>
|
|||
|
await DoSubmitFeedback(
|
|||
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|||
|
requestBuilder.DoSubmitFeedback(message, isBikeBroken),
|
|||
|
UserAgent);
|
|||
|
|
|||
|
/// <summary> Logs user in. </summary>
|
|||
|
/// <param name="copriHost">Host to connect to. </param>
|
|||
|
/// <param name="command">Command to log user in.</param>
|
|||
|
/// <remarks>Response which holds auth cookie <see cref="ResponseBase.authcookie"/></remarks>
|
|||
|
public static async Task<AuthorizationResponse> DoAuthorizationAsync(
|
|||
|
string copriHost,
|
|||
|
string command,
|
|||
|
Func<string> displayCommand,
|
|||
|
string userAgent = null)
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
/// Extract session cookie from response.
|
|||
|
string l_oResponseText = string.Empty;
|
|||
|
try
|
|||
|
{
|
|||
|
l_oResponseText = await PostAsync(
|
|||
|
copriHost,
|
|||
|
command,
|
|||
|
userAgent,
|
|||
|
displayCommand); // Do not include password into exception output when an error occurres.
|
|||
|
}
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
if (l_oException.GetIsConnectFailureException())
|
|||
|
{
|
|||
|
throw new WebConnectFailureException("Login fehlgeschlagen aufgrund eines Netzwerkfehlers.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
if (l_oException.GetIsForbiddenException())
|
|||
|
{
|
|||
|
throw new WebForbiddenException("Login fehlgeschlagen aufgrund eines Netzwerkfehlers.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
return JsonConvert.DeserializeObject<ResponseContainer<AuthorizationResponse>>(l_oResponseText)?.tinkjson;
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Logs user out. </summary>
|
|||
|
/// <param name="copriHost">Host to connect to. </param>
|
|||
|
/// <param name="command">Command to log user out.</param>
|
|||
|
public static async Task<AuthorizationoutResponse> DoAuthoutAsync(
|
|||
|
string p_strCopriHost,
|
|||
|
string p_oCommand,
|
|||
|
string userAgent = null)
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
string l_oLogoutResponse;
|
|||
|
try
|
|||
|
{
|
|||
|
l_oLogoutResponse = await PostAsync(p_strCopriHost, p_oCommand, userAgent);
|
|||
|
}
|
|||
|
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
if (l_oException.GetIsConnectFailureException())
|
|||
|
{
|
|||
|
throw new WebConnectFailureException("Login fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
if (l_oException.GetIsForbiddenException())
|
|||
|
{
|
|||
|
throw new WebForbiddenException("Login fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
/// Extract session cookie from response.
|
|||
|
return JsonConvert.DeserializeObject<ResponseContainer<AuthorizationoutResponse>>(l_oLogoutResponse)?.tinkjson;
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get list of stations from file.
|
|||
|
/// </summary>
|
|||
|
/// <param name="p_strCopriHost">URL of the copri host to connect to.</param>
|
|||
|
/// <param name="p_oCommand">Command to get stations.</param>
|
|||
|
/// <returns>List of files.</returns>
|
|||
|
public static async Task<StationsAllResponse> GetStationsAsync(
|
|||
|
string p_strCopriHost,
|
|||
|
string p_oCommand,
|
|||
|
string userAgent = null)
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
string l_oStationsAllResponse;
|
|||
|
try
|
|||
|
{
|
|||
|
l_oStationsAllResponse = await PostAsync(p_strCopriHost, p_oCommand, userAgent);
|
|||
|
}
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
if (l_oException.GetIsConnectFailureException())
|
|||
|
{
|
|||
|
throw new WebConnectFailureException("Abfage der verfügbaren Räder fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
if (l_oException.GetIsForbiddenException())
|
|||
|
{
|
|||
|
throw new WebForbiddenException("Abfage der verfügbaren Räder fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
// Extract bikes from response.
|
|||
|
return JsonConvert.DeserializeObject<ResponseContainer<StationsAllResponse>>(l_oStationsAllResponse)?.tinkjson;
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Gets a list of bikes from Copri. </summary>
|
|||
|
/// <param name="p_strCopriHost">URL of the copri host to connect to.</param>
|
|||
|
/// <param name="p_oCommand">Command to get bikes.</param>
|
|||
|
/// <returns>Response holding list of bikes.</returns>
|
|||
|
public static async Task<BikesAvailableResponse> GetBikesAvailableAsync(
|
|||
|
string p_strCopriHost,
|
|||
|
string l_oCommand,
|
|||
|
string userAgent = null)
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
string l_oBikesAvaialbeResponse;
|
|||
|
try
|
|||
|
{
|
|||
|
l_oBikesAvaialbeResponse = await PostAsync(p_strCopriHost, l_oCommand, userAgent);
|
|||
|
}
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
if (l_oException.GetIsConnectFailureException())
|
|||
|
{
|
|||
|
throw new WebConnectFailureException("Abfage der verfügbaren Räder fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
if (l_oException.GetIsForbiddenException())
|
|||
|
{
|
|||
|
throw new WebForbiddenException("Abfage der verfügbaren Räder fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
// Extract bikes from response.
|
|||
|
return CopriCallsStatic.DeserializeBikesAvailableResponse(l_oBikesAvaialbeResponse);
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Gets a list of bikes reserved/ booked by acctive user from Copri.</summary>
|
|||
|
/// <param name="p_strCopriHost">URL of the copri host to connect to.</param>
|
|||
|
/// <param name="p_oCommand">Command to post.</param>
|
|||
|
/// <returns>Response holding list of bikes.</returns>
|
|||
|
public static async Task<BikesReservedOccupiedResponse> GetBikesOccupiedAsync(
|
|||
|
string p_strCopriHost,
|
|||
|
string p_oCommand,
|
|||
|
string userAgent = null)
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
string l_oBikesOccupiedResponse;
|
|||
|
try
|
|||
|
{
|
|||
|
l_oBikesOccupiedResponse = await PostAsync(p_strCopriHost, p_oCommand, userAgent);
|
|||
|
}
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
if (l_oException.GetIsConnectFailureException())
|
|||
|
{
|
|||
|
throw new WebConnectFailureException("Abfage der reservierten/ gebuchten Räder fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
if (l_oException.GetIsForbiddenException())
|
|||
|
{
|
|||
|
throw new WebForbiddenException("Abfage der reservierten/ gebuchten Räder fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
// Extract bikes from response.
|
|||
|
return CopriCallsStatic.DeserializeBikesOccupiedResponse(l_oBikesOccupiedResponse);
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Get auth keys from COPRI. </summary>
|
|||
|
/// <param name="copriHost">Host to connect to. </param>
|
|||
|
/// <param name="command">Command to log user in.</param>
|
|||
|
/// <returns>Response on booking request.</returns>
|
|||
|
public static async Task<ReservationBookingResponse> GetAuthKeysAsync(
|
|||
|
string p_strCopriHost,
|
|||
|
string p_oCommand,
|
|||
|
string userAgent = null)
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
string l_oBikesAvaialbeResponse;
|
|||
|
try
|
|||
|
{
|
|||
|
l_oBikesAvaialbeResponse = await PostAsync(p_strCopriHost, p_oCommand, userAgent);
|
|||
|
}
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
if (l_oException.GetIsConnectFailureException())
|
|||
|
{
|
|||
|
throw new WebConnectFailureException("Schlosssuche wegen Netzwerkfehler fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
if (l_oException.GetIsForbiddenException())
|
|||
|
{
|
|||
|
throw new WebForbiddenException("Schlosssuche wegen Netzwerkfehler fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
// Extract bikes from response.
|
|||
|
return JsonConvert.DeserializeObject<ResponseContainer<ReservationBookingResponse>>(l_oBikesAvaialbeResponse)?.tinkjson;
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
/// <summary> Gets booking request response. </summary>
|
|||
|
/// <param name="copriHost">Host to connect to. </param>
|
|||
|
/// <param name="command">Command to log user in.</param>
|
|||
|
/// <returns>Response on booking request.</returns>
|
|||
|
public static async Task<ReservationBookingResponse> DoReserveAsync(
|
|||
|
string p_strCopriHost,
|
|||
|
string p_oCommand,
|
|||
|
string userAgent = null)
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
string l_oBikesAvaialbeResponse;
|
|||
|
try
|
|||
|
{
|
|||
|
l_oBikesAvaialbeResponse = await PostAsync(p_strCopriHost, p_oCommand, userAgent);
|
|||
|
}
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
if (l_oException.GetIsConnectFailureException())
|
|||
|
{
|
|||
|
throw new WebConnectFailureException("Reservierung des Fahrrads wegen Netzwerkfehler fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
if (l_oException.GetIsForbiddenException())
|
|||
|
{
|
|||
|
throw new WebForbiddenException("Reservierung des Fahrrads wegen Netzwerkfehler fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
// Extract bikes from response.
|
|||
|
return JsonConvert.DeserializeObject<ResponseContainer<ReservationBookingResponse>>(l_oBikesAvaialbeResponse)?.tinkjson;
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> Gets canel booking request response.</summary>
|
|||
|
/// <param name="copriHost">Host to connect to. </param>
|
|||
|
/// <param name="command">Command to log user in.</param>
|
|||
|
/// <returns>Response on cancel booking request.</returns>
|
|||
|
public static async Task<ReservationCancelReturnResponse> DoCancelReservationAsync(
|
|||
|
string copriHost,
|
|||
|
string command,
|
|||
|
string userAgent = null)
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
string l_oBikesAvaialbeResponse;
|
|||
|
try
|
|||
|
{
|
|||
|
l_oBikesAvaialbeResponse = await PostAsync(copriHost, command, userAgent);
|
|||
|
}
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
if (l_oException.GetIsConnectFailureException())
|
|||
|
{
|
|||
|
throw new WebConnectFailureException("Reservierung des Fahrrads aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
if (l_oException.GetIsForbiddenException())
|
|||
|
{
|
|||
|
throw new WebForbiddenException("Reservierung des Fahrrads aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
// Extract bikes from response.
|
|||
|
return JsonConvert.DeserializeObject<ResponseContainer<ReservationCancelReturnResponse>>(l_oBikesAvaialbeResponse)?.tinkjson;
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
public static async Task<ReservationBookingResponse> DoUpdateLockingStateAsync(
|
|||
|
string copriHost,
|
|||
|
string command,
|
|||
|
string agent = null)
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
string l_oBikesAvaialbeResponse;
|
|||
|
try
|
|||
|
{
|
|||
|
l_oBikesAvaialbeResponse = await PostAsync(copriHost, command, agent);
|
|||
|
}
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
if (l_oException.GetIsConnectFailureException())
|
|||
|
{
|
|||
|
throw new WebConnectFailureException("Aktualisierung des Schlossstatuses wegen Netzwerkfehler fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
if (l_oException.GetIsForbiddenException())
|
|||
|
{
|
|||
|
throw new WebForbiddenException("Aktualisierung des Schlossstatuses wegen Netzwerkfehler fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
// Extract bikes from response.
|
|||
|
return JsonConvert.DeserializeObject<ResponseContainer<ReservationBookingResponse>>(l_oBikesAvaialbeResponse)?.tinkjson;
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
public static async Task<ReservationBookingResponse> DoBookAsync(
|
|||
|
string copriHost,
|
|||
|
string command,
|
|||
|
string agent = null)
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
string l_oBikesAvaialbeResponse;
|
|||
|
try
|
|||
|
{
|
|||
|
l_oBikesAvaialbeResponse = await PostAsync(copriHost, command, agent);
|
|||
|
}
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
if (l_oException.GetIsConnectFailureException())
|
|||
|
{
|
|||
|
throw new WebConnectFailureException("Buchung des Fahrrads wegen Netzwerkfehler fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
if (l_oException.GetIsForbiddenException())
|
|||
|
{
|
|||
|
throw new WebForbiddenException("Buchung des Fahrrads wegen Netzwerkfehler fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
// Extract bikes from response.
|
|||
|
return JsonConvert.DeserializeObject<ResponseContainer<ReservationBookingResponse>>(l_oBikesAvaialbeResponse)?.tinkjson;
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
public static async Task<ReservationCancelReturnResponse> DoReturn(
|
|||
|
string copriHost,
|
|||
|
string command,
|
|||
|
string userAgent = null)
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
string l_oBikesAvaialbeResponse;
|
|||
|
try
|
|||
|
{
|
|||
|
l_oBikesAvaialbeResponse = await PostAsync(copriHost, command, userAgent);
|
|||
|
}
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
if (l_oException.GetIsConnectFailureException())
|
|||
|
{
|
|||
|
throw new WebConnectFailureException("Rückgabe des Fahrrads aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
if (l_oException.GetIsForbiddenException())
|
|||
|
{
|
|||
|
throw new WebForbiddenException("Rückgabe des Fahrrads aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
// Extract bikes from response.
|
|||
|
return JsonConvert.DeserializeObject<ResponseContainer<ReservationCancelReturnResponse>>(l_oBikesAvaialbeResponse)?.tinkjson;
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
public async Task<SubmitFeedbackResponse> DoSubmitFeedback(
|
|||
|
string copriHost,
|
|||
|
string command,
|
|||
|
string userAgent = null)
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
string userFeedbackResponse;
|
|||
|
try
|
|||
|
{
|
|||
|
userFeedbackResponse = await PostAsync(copriHost, command, userAgent);
|
|||
|
}
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
if (l_oException.GetIsConnectFailureException())
|
|||
|
{
|
|||
|
throw new WebConnectFailureException("Senden der Rückmeldung aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
if (l_oException.GetIsForbiddenException())
|
|||
|
{
|
|||
|
throw new WebForbiddenException("Senden der Rückmeldung aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|||
|
}
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
// Extract bikes from response.
|
|||
|
return JsonConvert.DeserializeObject<ResponseContainer<SubmitFeedbackResponse>>(userFeedbackResponse)?.tinkjson;
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> http get- request.</summary>
|
|||
|
/// <param name="Url">Ulr to get info from.</param>
|
|||
|
/// <returns>response from server</returns>
|
|||
|
public static async Task<string> Get(string Url)
|
|||
|
{
|
|||
|
string result = string.Empty;
|
|||
|
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(Url);
|
|||
|
myRequest.Method = "GET";
|
|||
|
using (var myResponse = await myRequest.GetResponseAsync())
|
|||
|
{
|
|||
|
using (var sr = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8))
|
|||
|
{
|
|||
|
result = sr.ReadToEnd();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> http- post request.</summary>
|
|||
|
/// <param name="p_strCommand">Command to send.</param>
|
|||
|
/// <param name="p_oDisplayCommand">Command to display/ log used for error handling.</param>
|
|||
|
/// <param name="uRL">Address of server to communicate with.</param>
|
|||
|
/// <returns>Response as text.</returns>
|
|||
|
/// <changelog> An unused member PostAsyncHttpClient using HttpClient for posting was removed 2020-04-02.</changelog>
|
|||
|
private static async Task<string> PostAsync(
|
|||
|
string uRL,
|
|||
|
string p_strCommand,
|
|||
|
string userAgent = null,
|
|||
|
Func<string> p_oDisplayCommand = null)
|
|||
|
{
|
|||
|
if (string.IsNullOrEmpty(p_strCommand))
|
|||
|
{
|
|||
|
Log.ForContext<CopriCallsHttps>().Fatal("Can not post command. Command must not be null or empty.");
|
|||
|
|
|||
|
throw new ArgumentException("Can not post command. Command must not be null or empty.");
|
|||
|
}
|
|||
|
|
|||
|
if (string.IsNullOrEmpty(uRL))
|
|||
|
{
|
|||
|
Log.ForContext<CopriCallsHttps>().Fatal("Can not post command. Host must not be null or empty.");
|
|||
|
|
|||
|
throw new ArgumentException("Can not post command. Host must not be null or empty.");
|
|||
|
}
|
|||
|
|
|||
|
// Get display version of command to used for display/ logging (password should never be included in output)
|
|||
|
Func<string> displayCommandFunc = p_oDisplayCommand ?? delegate () { return p_strCommand; };
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
#if !WINDOWS_UWP
|
|||
|
var l_strHost = uRL;
|
|||
|
|
|||
|
// Returns a http request.
|
|||
|
var l_oRequest = WebRequest.CreateHttp(l_strHost);
|
|||
|
|
|||
|
l_oRequest.Method = "POST";
|
|||
|
l_oRequest.ContentType = "application/x-www-form-urlencoded";
|
|||
|
l_oRequest.UserAgent = userAgent;
|
|||
|
|
|||
|
// Workaround for issue https://bugzilla.xamarin.com/show_bug.cgi?id=57705
|
|||
|
// If not KeepAlive is set to true Stream.Write leads arbitrarily to an object disposed exception.
|
|||
|
l_oRequest.KeepAlive = true;
|
|||
|
|
|||
|
byte[] l_oPostData = Encoding.UTF8.GetBytes(p_strCommand);
|
|||
|
|
|||
|
l_oRequest.ContentLength = l_oPostData.Length;
|
|||
|
|
|||
|
// Get the request stream.
|
|||
|
using (Stream l_oDataStream = await l_oRequest.GetRequestStreamAsync())
|
|||
|
{
|
|||
|
// Write the data to the request stream.
|
|||
|
await l_oDataStream.WriteAsync(l_oPostData, 0, l_oPostData.Length);
|
|||
|
}
|
|||
|
|
|||
|
// Get the response.
|
|||
|
var l_oResponse = await l_oRequest.GetResponseAsync() as HttpWebResponse;
|
|||
|
|
|||
|
if (l_oResponse == null)
|
|||
|
{
|
|||
|
throw new System.Exception(string.Format("Reserve request failed. Response form from server was not of expected type."));
|
|||
|
}
|
|||
|
|
|||
|
if (l_oResponse.StatusCode != HttpStatusCode.OK)
|
|||
|
{
|
|||
|
throw new CommunicationException(string.Format(
|
|||
|
"Posting request {0} failed. Expected status code is {1} but was {2}.",
|
|||
|
displayCommandFunc(),
|
|||
|
HttpStatusCode.OK,
|
|||
|
l_oResponse.StatusCode));
|
|||
|
}
|
|||
|
|
|||
|
string response = string.Empty;
|
|||
|
|
|||
|
// Get the request stream.
|
|||
|
using (Stream l_oDataStream = l_oResponse.GetResponseStream())
|
|||
|
using (StreamReader l_oReader = new StreamReader(l_oDataStream))
|
|||
|
{
|
|||
|
// Read the content.
|
|||
|
response = l_oReader.ReadToEnd();
|
|||
|
|
|||
|
// Display the content.
|
|||
|
Console.WriteLine(response);
|
|||
|
|
|||
|
// Clean up the streams.
|
|||
|
l_oResponse.Close();
|
|||
|
}
|
|||
|
|
|||
|
Log.ForContext<CopriCallsHttps>().Verbose("Post command {DisplayCommand} to host {URL} received {ResponseText:j}.", displayCommandFunc(), uRL, response);
|
|||
|
|
|||
|
return response;
|
|||
|
#else
|
|||
|
return null;
|
|||
|
#endif
|
|||
|
}
|
|||
|
catch (System.Exception l_oException)
|
|||
|
{
|
|||
|
Log.ForContext<CopriCallsHttps>().InformationOrError("Posting command {DisplayCommand} to host {URL} failed. {Exception}.", displayCommandFunc(), uRL, l_oException);
|
|||
|
throw;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|