public async Task <IActionResult> Get([FromQuery] ExchangeRatesRequest request, CancellationToken cancellationToken) { try { if (request.currencyCodes.Values.Where(x => x != "EUR").Count() > 0) { return(BadRequest("Denominated currency has to be EUR!")); } DateTime endDate = request.endDate.GetValueOrDefault(request.startDate); if (request.startDate > DateTime.Now || request.endDate > DateTime.Now || request.startDate > request.endDate) { throw new InvalidDateTime("Startdate has to be earlier or equal to enddate " + "and earlier or equal to current date!"); } var response = await _currencyRatesService.GetExchangeRatesAsync(request.currencyCodes, request.startDate, endDate, cancellationToken); return(Ok(response)); } catch (InvalidDateTime ex) { return(NotFound(ex.Message)); } catch (Exception ex) { _logger.LogError(ex.Message); return(BadRequest(ex.Message)); } }
public ExchangeRatesResponse GetExchangeRatesFor(ExchangeRatesRequest request) { var req = CreateRestRequest("/", Method.POST); req.AddBody(request); return(RestClient.Execute <ExchangeRatesResponse>(req).Data); }
public async Task <ExchangeRatesResult> GetExchangeRates(ExchangeRatesRequest request) { ValidateCurrencies(request.BaseCurrency, request.TargetCurrency); ValidateDates(request.Dates); var tasks = request.Dates.Select(date => _connector.GetExchangeRate(date, request.BaseCurrency, request.TargetCurrency)); var exchangeRatesResponses = await Task.WhenAll(tasks); var dateRateList = exchangeRatesResponses.Select(x => new { x.Date, Rate = x.Rates.First().Value }) .OrderBy(x => x.Rate) .ToList(); var minRate = dateRateList.First(); var maxRate = dateRateList.Last(); var average = dateRateList.Average(x => x.Rate); var minRateDate = new RateOnDate { Rate = minRate.Rate, Date = minRate.Date }; var maxRateDate = new RateOnDate { Rate = maxRate.Rate, Date = maxRate.Date }; return(new ExchangeRatesResult(minRateDate, maxRateDate, average)); }
public async Task <ExchangeRateResponse> GetExchangeRatesAsync(ExchangeRatesRequest request) { ValidateCurrencies(request.BaseCurrency, request.TargetCurrency); var tasks = new List <Task <ExchangeRatesResult> >(); request.Dates.ForEach(date => { tasks.Add(GetExchangeRatesAsync(date, request.BaseCurrency, request.TargetCurrency)); }); var result = await Task.WhenAll(tasks); if (result == null || result.Length == 0) { throw new NotFoundException("There are no exchange rates for provided dates."); } var rateDates = result.Select(res => new DateRate(res.Date, res.Rates.Values.First())).OrderBy(r => r.Rate).ToList(); var minRate = rateDates.FirstOrDefault(); var maxRate = rateDates.LastOrDefault(); var average = rateDates.Average(rd => rd.Rate); return(new ExchangeRateResponse(minRate, maxRate, average)); }
public async Task <ExchangeRatesResponse> GetRates(ExchangeRatesRequest request) { if (request is null) { throw new ArgumentNullException(nameof(request)); } if (request.Date < _MinDate) { throw new ArgumentOutOfRangeException($"{nameof(request.Date)} must be greater than {_MinDate} but was {request.Date}"); } var uriBuilder = new UriBuilder(_EcbBaseUri) { Path = $"{request.Date.ToString("yyyy-MM-dd")}", Query = $"base={request.BaseCurrency}" }; var apiResponse = await _HttpClient.GetAsync(uriBuilder.Uri).ConfigureAwait(false); var apiContent = await apiResponse.Content.ReadAsStringAsync(); if (!apiResponse.IsSuccessStatusCode) { var error = _ResponseHandler.ParseError(apiContent); throw new HttpRequestException( $"{nameof(apiResponse.StatusCode)}: {apiResponse.StatusCode}. {error}"); } var exchangeRates = _ResponseHandler.ParseResponse(apiContent); return(exchangeRates); }
public IEnumerable <ExchangeRate> Fetch(ExchangeRatesRequest request) { ConfigurationContainer.EnsureAppSettingExists("OpenExchangeRates.ApiKey"); var exchangeRateData = Client.Get(); return(exchangeRateData.Rates.Select(r => new ExchangeRate(r.Key, r.Value, exchangeRateData.Base, DateTime.UtcNow))); }
private static HttpWebRequest CreateRequest(ExchangeRatesRequest request) { var apiUri = string.Format(ApiUriFormat, request.BaseCurrencyCode, request.CurrencyCode); var httpRequest = (HttpWebRequest)WebRequest.Create(apiUri); httpRequest.Method = "GET"; return(httpRequest); }
public IEnumerable <ExchangeRate> GetLatest(ExchangeRatesRequest request) { var dataFetchingStrategy = _configuration.DataFetchingStrategy; if (_strategies.Keys.All(x => !string.Equals(x, dataFetchingStrategy, StringComparison.InvariantCultureIgnoreCase))) { const string errMsgFormat = "Data fetching strategy not found: {0}."; var errMsg = string.Format(errMsgFormat, dataFetchingStrategy); throw new ConfigurationMissingException(errMsg); } return(_strategies[dataFetchingStrategy].Fetch(request)); }
public static Task <ExchangeRatesResponse> ExchangeRates(bool isshort = false, bool accepted = false) { var request = new ExchangeRatesRequest { Short = isshort ? 1 : 0, Accepted = accepted ? 1 : 0 }; var req = new HttpUrlRequest(request); return(process <ExchangeRatesResponse>(req)); }
public IEnumerable <ExchangeRate> Fetch(ExchangeRatesRequest request) { var httpRequest = CreateRequest(request); var httpResponse = ExecuteHttpRequest(httpRequest); var rate = ScrapeExchangeRate(httpResponse); var exchangeRate = new ExchangeRate(request.CurrencyCode, rate, request.BaseCurrencyCode, DateTime.UtcNow); return(new List <ExchangeRate> { exchangeRate }); }
public void WhenDefaultRequestIsRetrieved_ThenItIsTheDefaultOfTheInjectedAccess() { var expectedRequest = new ExchangeRatesRequest("BASEBASE", DateTime.UtcNow); var injectedAccess = new Mock <IExchangeRatesAccess>(); injectedAccess.SetupGet(m => m.DefaultRequest).Returns(expectedRequest); var cachingAccess = new CachingExchangeRatesAccess( new MemoryCache("name"), injectedAccess.Object); var defaultRequest = cachingAccess.DefaultRequest; defaultRequest.Should().BeEquivalentTo(expectedRequest); }
public async Task WhenCacheDoesNotContainItem_ThenAccessIsInvoked() { var expectedRequest = new ExchangeRatesRequest("BASE", DateTime.UtcNow); var accessMock = new Mock <IExchangeRatesAccess>(); ExchangeRatesRequest actualRequest = null; accessMock.Setup(m => m.GetRates(It.IsAny <ExchangeRatesRequest>())) .Callback <ExchangeRatesRequest>(request => actualRequest = request) .ReturnsAsync(new ExchangeRatesResponse( expectedRequest.BaseCurrency, expectedRequest.Date, new Dictionary <string, decimal>())); var cachingAccess = new CachingExchangeRatesAccess(new MemoryCache("rates"), accessMock.Object); await cachingAccess.GetRates(expectedRequest); actualRequest.Should().BeEquivalentTo(expectedRequest); }
public async Task WhenLatestRatesAreRetrieved_ThenAccessDefaultRequestIsUsed() { var expectedRequest = new ExchangeRatesRequest("DEFAULTBase", DateTime.MaxValue); var accessMock = new Mock <IExchangeRatesAccess>(); accessMock.SetupGet(m => m.DefaultRequest).Returns(expectedRequest); ExchangeRatesRequest actualRequest = null; accessMock.Setup(m => m.GetRates(It.IsAny <ExchangeRatesRequest>())) .Callback <ExchangeRatesRequest>(request => actualRequest = request) .ReturnsAsync(new ExchangeRatesResponse( "blah", DateTime.UtcNow, new Dictionary <string, decimal>())); var manager = new ExchangeRatesManager(accessMock.Object, Mock.Of <IExchangeRatesEngine>()); await manager.GetLatestRates(); actualRequest.Should().Be(expectedRequest); }
public ExchangeRate Get(ExchangeRatesRequest request) { var cacheKey = GetCacheKey(request); return(MemCache.Get(cacheKey) as ExchangeRate); }
private static string GetCacheKey(ExchangeRatesRequest request) { return(GetCacheKey(request.BaseCurrencyCode, request.CurrencyCode)); }
public ExchangeRatesResponse GetExchangeRatesFor(ExchangeRatesRequest request) { Contract.Ensures(Contract.Result <ExchangeRatesResponse>() != null); // Check if there is a valid cached response to this request. var cached = _cache.Get(request); if (cached != null) { // If yes, return that result return(new ExchangeRatesResponse(cached)); } //TODO: We're making the assumption here that our API fetches USD as the default base rate. // It's kinda bad, but I can't think of a better solution right now. var cachedBaseRate = _cache.Get(new ExchangeRatesRequest { BaseCurrencyCode = "USD", CurrencyCode = request.BaseCurrencyCode }); var cachedCurrRate = _cache.Get(new ExchangeRatesRequest { BaseCurrencyCode = "USD", CurrencyCode = request.CurrencyCode }); if (cachedBaseRate != null && cachedCurrRate != null) { var rate = cachedCurrRate.ConversionRate / cachedBaseRate.ConversionRate; var exRate = new ExchangeRate(request.CurrencyCode, rate, request.BaseCurrencyCode, DateTime.UtcNow); _cache.Add(exRate); _historicalStorage.Store(new List <ExchangeRate> { exRate }); return(new ExchangeRatesResponse(exRate)); } // If no, check when we last pulled from the API. var lastFetch = _cache.GetLastFetch(); var cacheExpiryTime = DateTime.UtcNow.AddMinutes(_config.CacheExpiryTime); // It isn't in the cache, and we've made a request recently, so no dice. if (lastFetch.HasValue && lastFetch.Value > cacheExpiryTime) { return(new ExchangeRatesResponse(null)); } // We've not made a request recently, so go get 'em. var fetchedRates = _fetch.GetLatest(request); // If there was data, store this data in the historical storage & cache. var latestRates = fetchedRates as IList <ExchangeRate> ?? fetchedRates.ToList(); _cache.Add(latestRates); _historicalStorage.Store(latestRates); // Save when we last did a fetch, so we don't spam an API somewhere. _cache.AddLastFetch(DateTime.UtcNow); // If we have the rate we are looking for, return it. If not, we end up with an empty result. var requestedRate = latestRates.SingleOrDefault(x => x.BaseCurrencyCode == request.BaseCurrencyCode && x.CurrencyCode == request.CurrencyCode); // If it doesn't exist, but we can figure it out, figure it out and cache that too. if (requestedRate == null && latestRates.Any(x => x.CurrencyCode == request.BaseCurrencyCode) && latestRates.Any(x => x.CurrencyCode == request.CurrencyCode)) { var baseRate = latestRates.Single(x => x.CurrencyCode == request.BaseCurrencyCode); var currRate = latestRates.Single(x => x.CurrencyCode == request.CurrencyCode); var rate = currRate.ConversionRate / baseRate.ConversionRate; var exRate = new ExchangeRate(request.CurrencyCode, rate, request.BaseCurrencyCode, DateTime.UtcNow); _cache.Add(exRate); _historicalStorage.Store(new List <ExchangeRate> { exRate }); requestedRate = exRate; } return(new ExchangeRatesResponse(requestedRate)); }