Beispiel #1
0
        public async Task HandleAsync(StartDelivery command)
        {
            if (command.Parcels is null)
            {
                throw new Exception("Parcels to be delivered were not specified.");
            }

            var parcels = new HashSet <Parcel>();

            foreach (var parcelId in command.Parcels)
            {
                var parcel = await _parcelsRepository.GetAsync(parcelId);

                if (parcel is null)
                {
                    throw new Exception($"Parcel with id: {parcelId} to be delivered was not found.");
                }

                if (await _deliveriesRepository.IsParcelInDeliveryAsync(parcelId))
                {
                    throw new Exception($"Parcel with id: {parcelId} is unavailable.");
                }

                parcels.Add(parcel);
            }

            if (!parcels.Any())
            {
                throw new Exception($"Delivery cannot be started without the parcels.");
            }

            _logger.LogInformation("Calculating the route...");
            var route = await _routingServiceClient.GetAsync(parcels.Select(p => p.Address));

            if (route is null)
            {
                throw new Exception("Route was not found.");
            }

            _logger.LogInformation("Route was calculated.");
            await _deliveriesRepository.AddAsync(new Delivery(command.DeliveryId, parcels,
                                                              new Route(route.Addresses, route.TotalDistance)));

            var eventsToPublish = parcels.Select(p => _messageBroker.PublishAsync(
                                                     new DeliveryStarted(command.DeliveryId, p.Id)));
            await Task.WhenAll(eventsToPublish);

            _logger.LogInformation($"Started a delivery with id: {command.DeliveryId}");
        }