diff --git a/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Controllers/ChoreographyController.cs b/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Controllers/ChoreographyController.cs index cb188442..608a09aa 100644 --- a/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Controllers/ChoreographyController.cs +++ b/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Controllers/ChoreographyController.cs @@ -10,8 +10,8 @@ using Fabrikam.Choreography.ChoreographyService.Services; using Fabrikam.Communicator.Service.Operations; using Microsoft.AspNetCore.Mvc; -using Microsoft.Azure.EventGrid; -using Microsoft.Azure.EventGrid.Models; +using Azure.Messaging.EventGrid; +using Azure.Messaging.EventGrid.SystemEvents; using Microsoft.Extensions.Logging; @@ -28,11 +28,12 @@ public class ChoreographyController : ControllerBase private readonly IDeliveryServiceCaller deliveryServiceCaller; private readonly IEventRepository eventRepository; - public ChoreographyController(IPackageServiceCaller packageServiceCaller, - IDroneSchedulerServiceCaller droneSchedulerServiceCaller, - IDeliveryServiceCaller deliveryServiceCaller, - IEventRepository eventRepository, - ILogger logger) + public ChoreographyController( + IPackageServiceCaller packageServiceCaller, + IDroneSchedulerServiceCaller droneSchedulerServiceCaller, + IDeliveryServiceCaller deliveryServiceCaller, + IEventRepository eventRepository, + ILogger logger) { this.packageServiceCaller = packageServiceCaller; this.droneSchedulerServiceCaller = droneSchedulerServiceCaller; @@ -52,17 +53,25 @@ public async Task Operation([FromBody] EventGridEvent[] events) if (events == null) { - logger.LogError("event is Null"); + logger.LogError("event is Null"); return BadRequest("No Event for Choreography"); } - if (events[0].EventType is EventTypes.EventGridSubscriptionValidationEvent) + if (events[0].EventType is SystemEventNames.EventGridSubscriptionValidation) { try { - var data = Operations.ConvertDataEventToType(events[0].Data); - var response = new SubscriptionValidationResponse(data.ValidationCode); - return Ok(response); + events[0].TryGetSystemEventData(out object systemEvent); + switch (systemEvent) + { + case SubscriptionValidationEventData subscriptionValidation: + return new OkObjectResult(new SubscriptionValidationResponse() + { + ValidationResponse = subscriptionValidation.ValidationCode + }); + default: + break; + } } catch (NullReferenceException ex) { @@ -114,13 +123,22 @@ public async Task Operation([FromBody] EventGridEvent[] events) await eventRepository.SendEventAsync(listEvents); return Ok("Created Package Completed"); } - catch (Exception ex) when (ex is BackendServiceCallFailedException || - ex is EventException || ex is Exception) + catch (EventException ex) { logger.LogError(ex.Message, ex); return BadRequest(ex); } + catch (BackendServiceCallFailedException ex) + { + logger.LogError(ex.Message, ex); + return StatusCode(500); + } + catch (Exception ex) + { + logger.LogError(ex.Message, ex); + return BadRequest(ex); + } } case Operations.ChoreographyOperation.CreatePackage: @@ -140,12 +158,16 @@ public async Task Operation([FromBody] EventGridEvent[] events) return Ok("Drone Completed"); } - catch (Exception ex) when (ex is BackendServiceCallFailedException || - ex is EventException) + catch (EventException ex) { logger.LogError(ex.Message, ex); return BadRequest(ex); } + catch (BackendServiceCallFailedException ex) + { + logger.LogError(ex.Message, ex); + return StatusCode(500); + } } case Operations.ChoreographyOperation.GetDrone: { @@ -154,7 +176,7 @@ public async Task Operation([FromBody] EventGridEvent[] events) var deliverySchedule = await deliveryServiceCaller.ScheduleDeliveryAsync(delivery, e.Subject); return Ok("Delivery Completed"); } - catch (Exception ex) when (ex is BackendServiceCallFailedException) + catch (BackendServiceCallFailedException ex) { logger.LogError(ex.Message, ex); return BadRequest(ex); diff --git a/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Fabrikam.Choreography.ChoreographyService.csproj b/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Fabrikam.Choreography.ChoreographyService.csproj index 28aa2738..dc9bd378 100644 --- a/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Fabrikam.Choreography.ChoreographyService.csproj +++ b/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Fabrikam.Choreography.ChoreographyService.csproj @@ -7,14 +7,15 @@ + - + diff --git a/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Services/EventRepository.cs b/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Services/EventRepository.cs index c48bcc04..a8df9848 100644 --- a/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Services/EventRepository.cs +++ b/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Services/EventRepository.cs @@ -3,48 +3,44 @@ using System.Linq; using System.Net.Http; using System.Threading.Tasks; -using Microsoft.Azure.EventGrid; -using Microsoft.Azure.EventGrid.Models; +using Azure; +using Azure.Messaging.EventGrid; using Microsoft.Extensions.Logging; namespace Fabrikam.Choreography.ChoreographyService.Services { public class EventRepository : IEventRepository { - private readonly TopicCredentials topicCredentials; - private readonly EventGridClient eventGridClient; - private readonly string eventGridHost; - private readonly string[] Topics; + private readonly AzureKeyCredential topicCredentials; + private readonly EventGridPublisherClient eventGridClient; + private readonly string[] topics; private readonly Random random; - public EventRepository(string eventGridHost,string eventKey, string Topics) + public EventRepository(string eventGridHost,string eventKey, string topics) { - topicCredentials = new TopicCredentials(eventKey); - eventGridClient = new EventGridClient(topicCredentials); - this.eventGridHost = eventGridHost; - this.Topics = Topics.Split(","); + topicCredentials = new AzureKeyCredential(eventKey); + eventGridClient = new EventGridPublisherClient(new Uri(eventGridHost), topicCredentials); + this.topics = topics.Split(","); random = new Random(); } public string GetTopic() { - return Topics[random.Next(0, Topics.Length)]; + return topics[random.Next(0, topics.Length)]; } public async Task SendEventAsync(List listEvents) { try - { - var response = await eventGridClient.PublishEventsWithHttpMessagesAsync(eventGridHost, listEvents); - response.Response.EnsureSuccessStatusCode(); + { + await eventGridClient.SendEventsAsync(listEvents); } catch (Exception ex) when (ex is ArgumentNullException || ex is InvalidOperationException || ex is HttpRequestException) { - throw new EventException("Exception sending event to eventGrid", ex); - + throw new RequestFailedException("Exception sending event to eventGrid", ex); } diff --git a/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Services/IEventRepository.cs b/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Services/IEventRepository.cs index fe55798c..0a187f70 100644 --- a/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Services/IEventRepository.cs +++ b/choreography/src/choreography/Fabrikam.Choreography.ChoreographyService/Services/IEventRepository.cs @@ -1,4 +1,4 @@ -using Microsoft.Azure.EventGrid.Models; +using Azure.Messaging.EventGrid; using System; using System.Collections.Generic; using System.Linq; diff --git a/choreography/src/choreography/Frabrikam.Choreography.ChoreographyService.Tests/ChoreographyControllerFixture.cs b/choreography/src/choreography/Frabrikam.Choreography.ChoreographyService.Tests/ChoreographyControllerFixture.cs index 7532fb81..971480ac 100644 --- a/choreography/src/choreography/Frabrikam.Choreography.ChoreographyService.Tests/ChoreographyControllerFixture.cs +++ b/choreography/src/choreography/Frabrikam.Choreography.ChoreographyService.Tests/ChoreographyControllerFixture.cs @@ -10,37 +10,41 @@ using Fabrikam.Choreography.ChoreographyService.Models; using Fabrikam.Choreography.ChoreographyService.Services; using Microsoft.AspNetCore.Mvc; -using Microsoft.Azure.EventGrid; -using Microsoft.Azure.EventGrid.Models; +using Azure.Messaging.EventGrid; +using Azure.Messaging.EventGrid.SystemEvents; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Internal; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; - namespace Fabrikam.Choreography.ChoreographyService.Tests { [TestClass] public class ChoreographyControllerFixture { private static Delivery delivery = new Delivery(); - SubscriptionValidationEventData eventValidationData = new SubscriptionValidationEventData(Guid.NewGuid().ToString(), "http://url"); - + SubscriptionValidationEventData eventValidationData = EventGridModelFactory.SubscriptionValidationEventData(Guid.NewGuid().ToString(), "http://url"); + [TestMethod] public async Task Post_Returns200_ForSubscriptionValidationData() - { - var eventOp = new EventGridEvent(); - eventOp.EventType = EventTypes.EventGridSubscriptionValidationEvent; - eventOp.Data = eventValidationData; - var target = new ChoreographyController(new Mock().Object, - new Mock().Object, - new Mock().Object, - new Mock().Object, - new Mock>().Object); - EventGridEvent[] events = new EventGridEvent[1]; + { + var eventOp = new EventGridEvent( + "EventSubject", + "EventType", + "1.0", + "This is the event data"); + eventOp.EventType = SystemEventNames.EventGridSubscriptionValidation; + eventOp.Data = new BinaryData(eventValidationData); + + var target = new ChoreographyController( + new Mock().Object, + new Mock().Object, + new Mock().Object, + new Mock().Object, + new Mock>().Object); + EventGridEvent[] events = new EventGridEvent[1]; events[0] = eventOp; - var result = await target.Operation(events) as OkObjectResult; Assert.IsNotNull(result); Assert.AreEqual(200, result.StatusCode); @@ -50,17 +54,23 @@ public async Task Post_Returns200_ForSubscriptionValidationData() public async Task Post_Returns400_ForInvalidSubscriptionValidationData() { var loggerMock = new Mock>(); - var eventOp = new EventGridEvent(); - eventOp.EventType = EventTypes.EventGridSubscriptionValidationEvent; + + var eventOp = new EventGridEvent( + "EventSubject", + "EventType", + "1.0", + "This is the event data"); + eventOp.EventType = SystemEventNames.EventGridSubscriptionValidation; eventOp.Data = null; - var target = new ChoreographyController(new Mock().Object, - new Mock().Object, - new Mock().Object, - new Mock().Object, - loggerMock.Object); - EventGridEvent[] events = new EventGridEvent[1]; + var target = new ChoreographyController( + new Mock().Object, + new Mock().Object, + new Mock().Object, + new Mock().Object, + loggerMock.Object); + EventGridEvent[] events = new EventGridEvent[1]; events[0] = eventOp; var result = await target.Operation(events) as BadRequestObjectResult; Assert.IsNotNull(result); @@ -71,19 +81,26 @@ public async Task Post_Returns400_ForInvalidSubscriptionValidationData() [TestMethod] public async Task Post_Returns200_ForValidDeliveryService() { - var deliveryCallerMock = new Mock(); deliveryCallerMock.Setup(r => r.ScheduleDeliveryAsync(It.IsAny(), It.IsAny())) - .ReturnsAsync(new DeliverySchedule { Id = "deliveryid" }).Verifiable(); + .ReturnsAsync(new DeliverySchedule { Id = "deliveryid" }).Verifiable(); - var eventOp = new EventGridEvent(); + var eventOp = new EventGridEvent( + "EventSubject", + "EventType", + "1.0", + "This is the event data"); eventOp.EventType = "GetDrone"; - eventOp.Data = new Delivery(); - var target = new ChoreographyController(new Mock().Object, - new Mock().Object, - deliveryCallerMock.Object, - new Mock().Object, - new Mock>().Object); + + Delivery delivery = new Delivery(); + eventOp.Data = new BinaryData(delivery); + + var target = new ChoreographyController( + new Mock().Object, + new Mock().Object, + deliveryCallerMock.Object, + new Mock().Object, + new Mock>().Object); EventGridEvent[] events = new EventGridEvent[1]; events[0] = eventOp; @@ -91,30 +108,36 @@ public async Task Post_Returns200_ForValidDeliveryService() Assert.IsNotNull(result); Assert.AreEqual(200, result.StatusCode); deliveryCallerMock.Verify(); - } [TestMethod] public async Task Post_Returns200_ForValidPackageService() { - var packageServiceCallerMock = new Mock(); packageServiceCallerMock.Setup(r => r.UpsertPackageAsync(It.IsAny())) - .ReturnsAsync(new PackageGen { Id = "someid" }).Verifiable(); + .ReturnsAsync(new PackageGen { Id = "someid" }).Verifiable(); + var eventRepositoryMock = new Mock(); eventRepositoryMock.Setup(e => e.SendEventAsync(It.IsAny>())) .Returns(Task.CompletedTask).Verifiable(); - - var eventOp = new EventGridEvent(); + + var eventOp = new EventGridEvent( + "EventSubject", + "EventType", + "1.0", + "This is the event data"); eventOp.EventType = "ScheduleDelivery"; - eventOp.Data = new Delivery(); - var target = new ChoreographyController(packageServiceCallerMock.Object, - new Mock().Object, - new Mock().Object, - eventRepositoryMock.Object, - new Mock>().Object); - EventGridEvent[] events = new EventGridEvent[1]; + Delivery delivery = new Delivery(); + eventOp.Data = new BinaryData(delivery); + + var target = new ChoreographyController( + packageServiceCallerMock.Object, + new Mock().Object, + new Mock().Object, + eventRepositoryMock.Object, + new Mock>().Object); + EventGridEvent[] events = new EventGridEvent[1]; events[0] = eventOp; var result = await target.Operation(events) as OkObjectResult; Assert.IsNotNull(result); @@ -126,22 +149,30 @@ public async Task Post_Returns200_ForValidPackageService() [TestMethod] public async Task Post_Returns200_ForValidDroneService() { - var droneServiceCallerMock = new Mock(); droneServiceCallerMock.Setup(r => r.GetDroneIdAsync(It.IsAny())) - .ReturnsAsync("droneId").Verifiable(); + .ReturnsAsync("droneId").Verifiable(); + var eventRepositoryMock = new Mock(); eventRepositoryMock.Setup(e => e.SendEventAsync(It.IsAny>())) .Returns(Task.CompletedTask).Verifiable(); - var eventOp = new EventGridEvent(); + var eventOp = new EventGridEvent( + "EventSubject", + "EventType", + "1.0", + "This is the event data"); eventOp.EventType = "CreatePackage"; - eventOp.Data = new Delivery(); - var target = new ChoreographyController(new Mock().Object, - droneServiceCallerMock.Object, - new Mock().Object, - eventRepositoryMock.Object, - new Mock>().Object); + + Delivery delivery = new Delivery(); + eventOp.Data = new BinaryData(delivery); + + var target = new ChoreographyController( + new Mock().Object, + droneServiceCallerMock.Object, + new Mock().Object, + eventRepositoryMock.Object, + new Mock>().Object); EventGridEvent[] events = new EventGridEvent[1]; events[0] = eventOp; @@ -156,58 +187,69 @@ public async Task Post_Returns200_ForValidDroneService() [TestMethod] public async Task Post_Returns400_ForNoEvent_AndIslogged() { - var loggerMock = new Mock>(); - var target = new ChoreographyController(new Mock().Object, - new Mock().Object, - new Mock().Object, - new Mock().Object, - loggerMock.Object); + var target = new ChoreographyController( + new Mock().Object, + new Mock().Object, + new Mock().Object, + new Mock().Object, + loggerMock.Object); var result = await target.Operation(null) as BadRequestObjectResult; Assert.IsNotNull(result); Assert.AreEqual(400, result.StatusCode); loggerMock.Verify(x => x.Log(LogLevel.Error, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>()), Times.Once); - - } [TestMethod] public async Task Post_Returns400_ForNullDelivery() { var loggerMock = new Mock>(); - var eventOp = new EventGridEvent(); + + var eventOp = new EventGridEvent( + "EventSubject", + "EventType", + "1.0", + "This is the event data"); eventOp.EventType = "GetDrone"; eventOp.Data = null; - var target = new ChoreographyController(new Mock().Object, - new Mock().Object, - new Mock().Object, - new Mock().Object, - loggerMock.Object); + + var target = new ChoreographyController( + new Mock().Object, + new Mock().Object, + new Mock().Object, + new Mock().Object, + loggerMock.Object); + EventGridEvent[] events = new EventGridEvent[1]; events[0] = eventOp; var result = await target.Operation(events) as BadRequestObjectResult; Assert.IsNotNull(result); Assert.AreEqual(400, result.StatusCode); loggerMock.Verify(x => x.Log(LogLevel.Error, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>()), Times.Once); - - } [TestMethod] public async Task Post_Returns400_ForInvalidDelivery() { var loggerMock = new Mock>(); - var eventOp = new EventGridEvent(); + + var eventOp = new EventGridEvent( + "EventSubject", + "EventType", + "1.0", + "This is the event data"); eventOp.EventType = "GetDrone"; - eventOp.Data = new { invalidId=10, InvalidName="invalid" }; + var content = new { invalidId = 10, InvalidName = "invalid" }; + eventOp.Data = new BinaryData(content); - var target = new ChoreographyController(new Mock().Object, - new Mock().Object, - new Mock().Object, - new Mock().Object, - loggerMock.Object); + var target = new ChoreographyController( + new Mock().Object, + new Mock().Object, + new Mock().Object, + new Mock().Object, + loggerMock.Object); EventGridEvent[] events = new EventGridEvent[1]; events[0] = eventOp; @@ -215,33 +257,40 @@ public async Task Post_Returns400_ForInvalidDelivery() Assert.IsNotNull(result); Assert.AreEqual(400, result.StatusCode); loggerMock.Verify(x => x.Log(LogLevel.Error, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>()), Times.Once); - - } [TestMethod] public async Task Post_Returns400_WhenPackageServiceFailswithEventException() { - var loggerMock = new Mock>(); var packageServiceCallerMock = new Mock(); + packageServiceCallerMock.Setup(r => r.UpsertPackageAsync(It.IsAny())) - .ReturnsAsync(new PackageGen { Id = "someid" }).Verifiable(); + .ReturnsAsync(new PackageGen { Id = "someid" }).Verifiable(); + var eventRepositoryMock = new Mock(); + eventRepositoryMock.Setup(e => e.SendEventAsync(It.IsAny>())) - .ThrowsAsync(new EventException()).Verifiable(); + .ThrowsAsync(new EventException()).Verifiable(); - var eventOp = new EventGridEvent(); + var eventOp = new EventGridEvent( + "EventSubject", + "EventType", + "1.0", + "This is the event data"); eventOp.EventType = "ScheduleDelivery"; - eventOp.Data = new Delivery(); - var target = new ChoreographyController(packageServiceCallerMock.Object, - new Mock().Object, - new Mock().Object, - eventRepositoryMock.Object, - loggerMock.Object); - EventGridEvent[] events = new EventGridEvent[1]; + Delivery delivery = new Delivery(); + eventOp.Data = new BinaryData(delivery); + var target = new ChoreographyController( + packageServiceCallerMock.Object, + new Mock().Object, + new Mock().Object, + eventRepositoryMock.Object, + loggerMock.Object); + + EventGridEvent[] events = new EventGridEvent[1]; events[0] = eventOp; var result = await target.Operation(events) as BadRequestObjectResult; Assert.IsNotNull(result); @@ -249,7 +298,6 @@ public async Task Post_Returns400_WhenPackageServiceFailswithEventException() packageServiceCallerMock.Verify(); eventRepositoryMock.Verify(); loggerMock.Verify(x => x.Log(LogLevel.Error, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>()), Times.Once); - } [TestMethod] @@ -257,20 +305,31 @@ public async Task Post_Returns400_WhenDroneServiceFailsToSendEvent() { var loggerMock = new Mock>(); var droneServiceCallerMock = new Mock(); + droneServiceCallerMock.Setup(r => r.GetDroneIdAsync(It.IsAny())) - .ReturnsAsync("droneId").Verifiable(); + .ReturnsAsync("droneId").Verifiable(); + var eventRepositoryMock = new Mock(); + eventRepositoryMock.Setup(e => e.SendEventAsync(It.IsAny>())) - .ThrowsAsync(new EventException()).Verifiable(); + .ThrowsAsync(new EventException()).Verifiable(); - var eventOp = new EventGridEvent(); + var eventOp = new EventGridEvent( + "EventSubject", + "EventType", + "1.0", + "This is the event data"); eventOp.EventType = "CreatePackage"; - eventOp.Data = new Delivery(); - var target = new ChoreographyController(new Mock().Object, - droneServiceCallerMock.Object, - new Mock().Object, - eventRepositoryMock.Object, - loggerMock.Object); + + Delivery delivery = new Delivery(); + eventOp.Data = new BinaryData(delivery); + + var target = new ChoreographyController( + new Mock().Object, + droneServiceCallerMock.Object, + new Mock().Object, + eventRepositoryMock.Object, + loggerMock.Object); EventGridEvent[] events = new EventGridEvent[1]; events[0] = eventOp; diff --git a/choreography/src/choreography/Frabrikam.Choreography.ChoreographyService.Tests/Fabrikam.Choreography.ChoreographyService.Tests.csproj b/choreography/src/choreography/Frabrikam.Choreography.ChoreographyService.Tests/Fabrikam.Choreography.ChoreographyService.Tests.csproj index 232b9172..fa98c21f 100644 --- a/choreography/src/choreography/Frabrikam.Choreography.ChoreographyService.Tests/Fabrikam.Choreography.ChoreographyService.Tests.csproj +++ b/choreography/src/choreography/Frabrikam.Choreography.ChoreographyService.Tests/Fabrikam.Choreography.ChoreographyService.Tests.csproj @@ -7,6 +7,7 @@ +