diff --git a/src/Controllers/Events/AppController.cs b/src/Controllers/Events/AppController.cs new file mode 100644 index 00000000..17039942 --- /dev/null +++ b/src/Controllers/Events/AppController.cs @@ -0,0 +1,65 @@ +using Altinn.Platform.Events.Models; +using Altinn.Platform.Events.Repository; + +using Microsoft.AspNetCore.Mvc; + +namespace Altinn.Platform.Events.Controllers +{ + /// + /// Provides operations for handling app events + /// + [Route("events/api/v1/app")] + [ApiController] + public class AppController : ControllerBase + { + private readonly IEventsRepository _repository; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class + /// + /// the events repository handler + /// dependency injection of logger + public AppController(IEventsRepository repository, ILogger logger) + { + _repository = repository; + _logger = logger; + } + + /// + /// Inserts a new event. + /// + /// The event to store. + /// The application metadata object. + [HttpPost] + [Consumes("application/json")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [Produces("application/json")] + public async Task> Post([FromBody] CloudEvent cloudEvent) + { + if (string.IsNullOrEmpty(cloudEvent.Source.OriginalString) || string.IsNullOrEmpty(cloudEvent.Specversion) || + string.IsNullOrEmpty(cloudEvent.Type) || string.IsNullOrEmpty(cloudEvent.Subject)) + { + return BadRequest("Missing parameter values: source, subject, type, id or time cannot be null"); + } + + try + { + // Force cosmos to create id + cloudEvent.Id = null; + + string cloudEventId = await _repository.Create(cloudEvent); + + _logger.LogInformation("Cloud Event successfully stored with id: {0}", cloudEventId); + + return Created(cloudEvent.Subject, cloudEventId); + } + catch (Exception e) + { + _logger.LogError($"Unable to store cloud event in database. {e}"); + return StatusCode(500, $"Unable to store cloud event in database. {e}"); + } + } + } +} diff --git a/src/Controllers/Events/EventsController.cs b/src/Controllers/Events/EventsController.cs index 2afb1ed8..0a0e993e 100644 --- a/src/Controllers/Events/EventsController.cs +++ b/src/Controllers/Events/EventsController.cs @@ -1,19 +1,14 @@ -using System; -using System.Threading.Tasks; - using Altinn.Platform.Events.Models; using Altinn.Platform.Events.Repository; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; namespace Altinn.Platform.Events.Controllers { /// - /// Provides operations for handling events + /// Provides operations for handling generic events /// - [Route("events/api/v1/app")] + [Route("events/api/v1/events")] [ApiController] public class EventsController : ControllerBase { @@ -40,31 +35,41 @@ public EventsController(IEventsRepository repository, ILogger [Consumes("application/json")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] - [Produces("application/json")] + [Produces("application/cloudevents+json")] public async Task> Post([FromBody] CloudEvent cloudEvent) { - if (string.IsNullOrEmpty(cloudEvent.Source.OriginalString) || string.IsNullOrEmpty(cloudEvent.Specversion) || - string.IsNullOrEmpty(cloudEvent.Type) || string.IsNullOrEmpty(cloudEvent.Subject)) + var (isValid, errorMessages) = ValidateCloudEvent(cloudEvent); + if (!isValid) { - return BadRequest("Missing parameter values: source, subject, type, id or time cannot be null"); + return Problem(errorMessages, null, 400); } - + try { - // Force cosmos to create id - cloudEvent.Id = null; - - string cloudEventId = await _repository.Create(cloudEvent); - + var cloudEventId = await _repository.Create(cloudEvent); _logger.LogInformation("Cloud Event successfully stored with id: {0}", cloudEventId); - - return Created(cloudEvent.Subject, cloudEventId); + return Ok(); } - catch (Exception e) + catch (Exception exception) { - _logger.LogError($"Unable to store cloud event in database. {e}"); - return StatusCode(500, $"Unable to store cloud event in database. {e}"); + _logger.LogError(exception, "Unable to register cloud event."); + return StatusCode(500, $"Unable to register cloud event."); } } + + private static (bool IsValid, string ErrorMessage) ValidateCloudEvent(CloudEvent cloudEvent) + { + if (string.IsNullOrEmpty(cloudEvent.Resource)) + { + return (false, "A 'resource' property must be defined."); + } + + if (!Uri.IsWellFormedUriString(cloudEvent.Resource, UriKind.Absolute)) + { + return (false, "'Resource' must be a valid urn."); + } + + return (true, null); + } } } diff --git a/src/Models/Events/CloudEvent.cs b/src/Models/Events/CloudEvent.cs index 17c7b038..ba8010a4 100644 --- a/src/Models/Events/CloudEvent.cs +++ b/src/Models/Events/CloudEvent.cs @@ -1,4 +1,3 @@ -using System; using Newtonsoft.Json; namespace Altinn.Platform.Events.Models @@ -50,5 +49,11 @@ public class CloudEvent /// [JsonProperty(PropertyName = "alternativesubject")] public string Alternativesubject { get; set; } + + /// + /// Gets or sets the resource of the event + /// + [JsonProperty(PropertyName = "resource")] + public string Resource { get; set; } } }