public async Task<int> AddVehicle(VehicleDetailsDto vehicle) { _logger.Trace("Adding Vehicle to local Cache - {0}", vehicle.CurrentRegistration); var mappedVehicle = Mapper.Map<VehicleDetail>(vehicle); mappedVehicle.UTCDateAdded = DateTime.UtcNow; _context.VehicleDetails.Add(mappedVehicle); await _context.SaveChangesAsync(); return mappedVehicle.VehicleId; }
public async Task<VehicleDetailsDto> FindVehicleByRegistrationNo(string regNo) { // check if we have a local reference to the vehicle (it has already been queried from the 3rd party paid service var vehicle = await _vehicleReader.GetVehicleByRegNo(regNo); if (vehicle != null) return vehicle; // didn't find anything. query the 3rd party service _logger.Trace("Querying Car Finder Service for reg {0}", regNo); var gateway = _restFactory.CreateGateway<VehicleMetaData>(EndPoint.CarFinder); var uri = string.Format("api/car/{0}", regNo); var response = await gateway.Get(uri); if (response == null) return null; var transformVehicle = new VehicleDetailsDto { CurrentRegistration = response.CurrentRegistration, Colour = response.Colour, IsImport = response.IsImport, ManufYear = response.ManufYear, BodyType = response.BodyType, FuelType = response.FuelType, ModelDesc = response.VehicleDesc, ModelName = string.Format("{0} {1}", response.Make, response.Model), Transmission = response.Transmission }; // add it to the local db to avoid further service querying. int vehicleId = await _vehicleWriter.AddVehicle(transformVehicle); transformVehicle.VehicleId = vehicleId; return transformVehicle; }
public async Task<int> AddQuotes(CarQuoteRequestDto request, VehicleDetailsDto vehicle) { int quoteId = await _carQuoteRequestWriter.AddQuote(request); // add it to the database var gateway = _restFactory.CreateGateway<ServiceCarInsuranceQuoteRequest>(EndPoint.InsuranceService); var tasksToCallService = new List<Task<HttpResponseMessage>>(); // task collection // create a task for each external service call foreach (var insurer in Enum.GetValues(typeof (Insurer))) { _logger.Trace("Sending Request for {0}", insurer); var serviceRequest = BuildServiceRequest((Insurer)insurer, quoteId, request, vehicle); Task<HttpResponseMessage> response = gateway.Post(serviceRequest, "api/carinsurancequote"); tasksToCallService.Add(response); } // add timeout handling for each service call TimeSpan timeOut = TimeSpan.FromSeconds(Timeout); var tasksToComplete = tasksToCallService.Select(serviceCall => Task.WhenAny(serviceCall, Task.Delay(timeOut))).ToList(); // wait for the tasks to complete or timeout await Task.WhenAll(tasksToComplete); // create a collection to hold all async responses IEnumerable<ServiceCarInsuranceQuoteResponse> allQuotes = new List<ServiceCarInsuranceQuoteResponse>(); // read and merge the results from successful tasks foreach (var response in tasksToCallService.Where(resp => resp.Status == TaskStatus.RanToCompletion && resp.Result.IsSuccessStatusCode)) { var quotes = await response.Result.Content.ReadAsAsync<IEnumerable<ServiceCarInsuranceQuoteResponse>>(); allQuotes = allQuotes.Concat(quotes); } // Valid but slower alternative (await after each call == sync approach) /* foreach (var insurer in Enum.GetValues(typeof(Insurer))) { // build the object to post var serviceRequest = new ServiceCarInsuranceQuoteRequest { QuoteRequestId = quoteId, NoClaimsDiscountYears = request.NoClaimsDiscountYears.HasValue ? request.NoClaimsDiscountYears.Value : 0, VehicleValue = request.VehicleValue.HasValue ? request.VehicleValue.Value : 0, CurrentRegistration = vehicle.CurrentRegistration, DriverAge = request.DriverAge.HasValue ? request.DriverAge.Value : 0, ModelDesc = vehicle.ModelDesc, IsImport = vehicle.IsImport, ManufYear = vehicle.ManufYear.HasValue ? vehicle.ManufYear.Value : 0, Insurer = (Insurer)insurer }; var response = await gateway.Post(serviceRequest, "api/carinsurancequote"); if (response != null) { _logger.Trace("Response from {0}", insurer.ToString()); var quotes = await response.Content.ReadAsAsync<IEnumerable<ServiceCarInsuranceQuoteResponse>>(); allQuotes = allQuotes.Concat(quotes); } } */ // determine which is the cheapest by quote type var responsesToSave = Mapper.Map<IEnumerable<CarQuoteResponseDto>>(allQuotes); var carQuoteResponseDtos = responsesToSave as CarQuoteResponseDto[] ?? responsesToSave.ToArray(); var cheapestQuotes = carQuoteResponseDtos .GroupBy(x => x.QuoteType) .SelectMany(y => y.OrderBy(x => x.QuoteValue) .Take(1)); // set ischeapest flag in the database foreach (var quote in carQuoteResponseDtos) { if (cheapestQuotes.Contains(quote)) { quote.IsCheapest = true; } } await _carQuoteResponseWriter.AddResponse(carQuoteResponseDtos); return quoteId; }
private ServiceCarInsuranceQuoteRequest BuildServiceRequest(Insurer insurer, int quoteId, CarQuoteRequestDto request, VehicleDetailsDto vehicle) { return new ServiceCarInsuranceQuoteRequest { QuoteRequestId = quoteId, NoClaimsDiscountYears = request.NoClaimsDiscountYears.HasValue ? request.NoClaimsDiscountYears.Value : 0, VehicleValue = request.VehicleValue.HasValue ? request.VehicleValue.Value : 0, CurrentRegistration = vehicle.CurrentRegistration, DriverAge = request.DriverAge.HasValue ? request.DriverAge.Value : 0, ModelDesc = vehicle.ModelDesc, IsImport = vehicle.IsImport, ManufYear = vehicle.ManufYear.HasValue ? vehicle.ManufYear.Value : 0, Insurer = insurer }; }
public SaveVehicleDetails(VehicleDetailsDto vehicle) { this.Vehicle = vehicle; }
/// <summary> /// the .PipeTo extention is the secret sauce here. The receive function must return a /// response and .PipeTo is the conduit to return the result from the task /// https://petabridge.com/blog/akkadotnet-async-actors-using-pipeto/ /// </summary> private void Ready() { Receive<FindCarFromLocalStorage>(req => { var senderClosure = Sender; IVehicleReader vehicleReader = new VehicleReader(_context); vehicleReader.GetVehicleByRegNo(req.CarRegNo).ContinueWith(s => s.Result).PipeTo(senderClosure); }); Receive<FindCarFromService>(req => { var senderClosure = Sender; var uri = string.Format("api/car/{0}", req.CarRegNo); var client = new HttpClient {BaseAddress = req.ServiceLocation}; // doesn't exist locally. go to external service client.GetAsync(uri).ContinueWith(httpRequest => { var response = httpRequest.Result; if (response.StatusCode == HttpStatusCode.OK) { var returnedVehicle = response.Content.ReadAsAsync<VehicleMetaData>(); var vehicle = new VehicleDetailsDto { BodyType = returnedVehicle.Result.BodyType, Colour = returnedVehicle.Result.Colour, CurrentRegistration = returnedVehicle.Result.CurrentRegistration, FuelType = returnedVehicle.Result.FuelType, IsImport = returnedVehicle.Result.IsImport, ManufYear = returnedVehicle.Result.ManufYear, ModelDesc = returnedVehicle.Result.VehicleDesc, ModelName = string.Format("{0} {1}", returnedVehicle.Result.Make, returnedVehicle.Result.Model), Transmission = returnedVehicle.Result.Transmission, VehicleRef = returnedVehicle.Result.VehicleRef }; return vehicle; } return null; }, TaskContinuationOptions.AttachedToParent & TaskContinuationOptions.ExecuteSynchronously) .PipeTo(senderClosure); }); Receive<SaveVehicleDetails>(req => { var senderClosure = Sender; IVehicleWriter vehicleWriter = new VehicleWriter(_context); vehicleWriter.AddVehicle(req.Vehicle).ContinueWith(s => s.Result).PipeTo(senderClosure); }); }