Skip to content

Commit

Permalink
Merge pull request #144 from Energinet-DataHub/kft/add_support_for_ci…
Browse files Browse the repository at this point in the history
…m_json

Refactor: Include desired document format in peek request
  • Loading branch information
Kristian F. Thomsen authored Mar 28, 2023
2 parents 5477be7 + 148f915 commit 0ccba2b
Show file tree
Hide file tree
Showing 33 changed files with 128 additions and 86 deletions.
29 changes: 29 additions & 0 deletions source/Api/Common/HttpHeadersExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2020 Energinet DataHub A/S
//
// Licensed under the Apache License, Version 2.0 (the "License2");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Linq;
using System.Net.Http.Headers;

namespace Api.Common;

internal static class HttpHeadersExtensions
{
internal static string GetContentType(this HttpHeaders headers)
{
var contentHeader = headers.GetValues("Content-Type").FirstOrDefault();
if (contentHeader == null) throw new InvalidOperationException("No Content-Type found in request headers");
return contentHeader;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@
// limitations under the License.

using System;
using System.Linq;
using System.Net;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Api.Common;
using Application.Configuration;
using CimMessageAdapter.Messages.RequestChangeOfSupplier;
using CimMessageAdapter.Response;
Expand Down Expand Up @@ -59,7 +58,7 @@ public async Task<HttpResponseData> RunAsync(

if (request == null) throw new ArgumentNullException(nameof(request));

var contentType = GetContentType(request.Headers);
var contentType = request.Headers.GetContentType();
var cimFormat = CimFormatParser.ParseFromContentTypeHeaderValue(contentType);
if (cimFormat is null)
{
Expand All @@ -75,13 +74,6 @@ public async Task<HttpResponseData> RunAsync(
return CreateResponse(request, httpStatusCode, _responseFactory.From(result, cimFormat));
}

private static string GetContentType(HttpHeaders headers)
{
var contentHeader = headers.GetValues("Content-Type").FirstOrDefault();
if (contentHeader == null) throw new InvalidOperationException("No Content-Type found in request headers");
return contentHeader;
}

private HttpResponseData CreateResponse(HttpRequestData request, HttpStatusCode statusCode, ResponseMessage responseMessage)
{
var response = request.CreateResponse(statusCode);
Expand Down
23 changes: 21 additions & 2 deletions source/Api/OutgoingMessages/PeekRequestListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,34 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Linq;
using System.Net;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Api.Common;
using Application.Configuration.Authentication;
using Application.OutgoingMessages.Peek;
using Domain.OutgoingMessages.Peek;
using Domain.SeedWork;
using Infrastructure.IncomingMessages;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;

namespace Api.OutgoingMessages;

public class PeekRequestListener
{
private readonly MessagePeeker _messagePeeker;
private readonly IMarketActorAuthenticator _authenticator;
private readonly ILogger<PeekRequestListener> _logger;

public PeekRequestListener(MessagePeeker messagePeeker, IMarketActorAuthenticator authenticator)
public PeekRequestListener(MessagePeeker messagePeeker, IMarketActorAuthenticator authenticator, ILogger<PeekRequestListener> logger)
{
_messagePeeker = messagePeeker;
_authenticator = authenticator;
_logger = logger;
}

[Function("PeekRequestListener")]
Expand All @@ -44,9 +52,20 @@ public async Task<HttpResponseData> RunAsync(
FunctionContext executionContext,
string messageCategory)
{
ArgumentNullException.ThrowIfNull(request);

var contentType = request.Headers.GetContentType();
var desiredDocumentFormat = CimFormatParser.ParseFromContentTypeHeaderValue(contentType);
if (desiredDocumentFormat is null)
{
_logger.LogInformation($"Could not parse desired CIM format from Content-Type header value: {contentType}");
return request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
}

var result = await _messagePeeker.PeekAsync(
_authenticator.CurrentIdentity.Number,
EnumerationType.FromName<MessageCategory>(messageCategory))
EnumerationType.FromName<MessageCategory>(messageCategory),
desiredDocumentFormat)
.ConfigureAwait(false);

var response = HttpResponseData.CreateResponse(request);
Expand Down
2 changes: 1 addition & 1 deletion source/Application/OutgoingMessages/DocumentFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public DocumentFactory(IEnumerable<IMessageWriter> documentWriters)
_documentWriters = documentWriters.ToList();
}

public Task<Stream> CreateFromAsync(BundledMessageId bundledMessageId, MessageRecords messageRecords, MessageFormat documentFormat, Instant timestamp)
public Task<Stream> CreateFromAsync(BundledMessageId bundledMessageId, MessageRecords messageRecords, DocumentFormat documentFormat, Instant timestamp)
{
ArgumentNullException.ThrowIfNull(bundledMessageId);
ArgumentNullException.ThrowIfNull(messageRecords);
Expand Down
5 changes: 3 additions & 2 deletions source/Application/OutgoingMessages/Peek/MessagePeeker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

using System.Threading.Tasks;
using Domain.Actors;
using Domain.OutgoingMessages;
using Domain.OutgoingMessages.Peek;
using MediatR;
using Microsoft.EntityFrameworkCore;
Expand All @@ -29,11 +30,11 @@ public MessagePeeker(IMediator mediator)
_mediator = mediator;
}

public async Task<PeekResult> PeekAsync(ActorNumber actorNumber, MessageCategory messageCategory)
public async Task<PeekResult> PeekAsync(ActorNumber actorNumber, MessageCategory messageCategory, DocumentFormat desiredDocumentFormat)
{
try
{
return await _mediator.Send(new PeekRequest(actorNumber, messageCategory)).ConfigureAwait(false);
return await _mediator.Send(new PeekRequest(actorNumber, messageCategory, desiredDocumentFormat)).ConfigureAwait(false);
}
catch (DbUpdateException)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,21 @@ public async Task<PeekResult> Handle(PeekRequest request, CancellationToken canc
return new PeekResult(null);
}

bundledMessage = await CreateBundledMessageAsync(messageRecords).ConfigureAwait(false);
bundledMessage = await CreateBundledMessageAsync(messageRecords, request.DesiredDocumentFormat).ConfigureAwait(false);
await _bundledMessages.AddAsync(bundledMessage).ConfigureAwait(false);

return new PeekResult(bundledMessage.GeneratedDocument, bundledMessage.Id.Value);
}

private async Task<BundledMessage> CreateBundledMessageAsync(MessageRecords messageRecords)
private async Task<BundledMessage> CreateBundledMessageAsync(MessageRecords messageRecords, DocumentFormat desiredDocumentFormat)
{
var id = BundledMessageId.New();
var document = await _documentFactory.CreateFromAsync(id, messageRecords, MessageFormat.Xml, _systemDateTimeProvider.Now())
var document = await _documentFactory.CreateFromAsync(id, messageRecords, desiredDocumentFormat, _systemDateTimeProvider.Now())
.ConfigureAwait(false);
return BundledMessage.CreateFrom(id, messageRecords, document);
}
}

public record PeekRequest(ActorNumber ActorNumber, MessageCategory MessageCategory) : ICommand<PeekResult>;
public record PeekRequest(ActorNumber ActorNumber, MessageCategory MessageCategory, DocumentFormat DesiredDocumentFormat) : ICommand<PeekResult>;

public record PeekResult(Stream? Bundle, Guid? MessageId = default);
2 changes: 1 addition & 1 deletion source/CimMessageAdapter/Messages/IMessageParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public interface IMessageParser<TMarketActivityRecordType, TMarketTransactionTyp
/// <summary>
/// The CIM format handled
/// </summary>
MessageFormat HandledFormat { get; }
DocumentFormat HandledFormat { get; }

/// <summary>
/// Parse from stream
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ public MessageParser(IEnumerable<IMessageParser<MarketActivityRecord, RequestCha
_parsers = parsers;
}

public Task<MessageParserResult<MarketActivityRecord, RequestChangeAccountingPointCharacteristicsTransaction>> ParseAsync(Stream message, MessageFormat messageFormat)
public Task<MessageParserResult<MarketActivityRecord, RequestChangeAccountingPointCharacteristicsTransaction>> ParseAsync(Stream message, DocumentFormat documentFormat)
{
var parser = _parsers.FirstOrDefault(parser => parser.HandledFormat.Equals(messageFormat));
if (parser is null) throw new InvalidOperationException($"No message parser found for message format '{messageFormat}'");
var parser = _parsers.FirstOrDefault(parser => parser.HandledFormat.Equals(documentFormat));
if (parser is null) throw new InvalidOperationException($"No message parser found for message format '{documentFormat}'");
return parser.ParseAsync(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ public MessageParser(IEnumerable<IMessageParser<MarketActivityRecord, RequestCha
_parsers = parsers;
}

public Task<MessageParserResult<MarketActivityRecord, RequestChangeCustomerCharacteristicsTransaction>> ParseAsync(Stream message, MessageFormat messageFormat)
public Task<MessageParserResult<MarketActivityRecord, RequestChangeCustomerCharacteristicsTransaction>> ParseAsync(Stream message, DocumentFormat documentFormat)
{
var parser = _parsers.FirstOrDefault(parser => parser.HandledFormat.Equals(messageFormat));
if (parser is null) throw new InvalidOperationException($"No message parser found for message format '{messageFormat}'");
var parser = _parsers.FirstOrDefault(parser => parser.HandledFormat.Equals(documentFormat));
if (parser is null) throw new InvalidOperationException($"No message parser found for message format '{documentFormat}'");
return parser.ParseAsync(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ public MessageParser(IEnumerable<IMessageParser<MarketActivityRecord, RequestCha
_parsers = parsers;
}

public Task<MessageParserResult<MarketActivityRecord, RequestChangeOfSupplierTransaction>> ParseAsync(Stream message, MessageFormat messageFormat)
public Task<MessageParserResult<MarketActivityRecord, RequestChangeOfSupplierTransaction>> ParseAsync(Stream message, DocumentFormat documentFormat)
{
var parser = _parsers.FirstOrDefault(parser => parser.HandledFormat.Equals(messageFormat));
if (parser is null) throw new InvalidOperationException($"No message parser found for message format '{messageFormat}'");
var parser = _parsers.FirstOrDefault(parser => parser.HandledFormat.Equals(documentFormat));
if (parser is null) throw new InvalidOperationException($"No message parser found for message format '{documentFormat}'");
return parser.ParseAsync(message);
}
}
2 changes: 1 addition & 1 deletion source/CimMessageAdapter/Response/IResponseFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public interface IResponseFactory
/// <summary>
/// Specifies the handled CIM format
/// </summary>
public MessageFormat HandledFormat { get; }
public DocumentFormat HandledFormat { get; }

/// <summary>
/// Create response message
Expand Down
2 changes: 1 addition & 1 deletion source/CimMessageAdapter/Response/ResponseFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public ResponseFactory(IEnumerable<IResponseFactory> factories)
_factories = factories;
}

public ResponseMessage From(Result result, MessageFormat format)
public ResponseMessage From(Result result, DocumentFormat format)
{
if (result == null) throw new ArgumentNullException(nameof(result));
if (format == null) throw new ArgumentNullException(nameof(format));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@

namespace Domain.OutgoingMessages;

public class MessageFormat : EnumerationType
public class DocumentFormat : EnumerationType
{
public static readonly MessageFormat Xml = new(0, nameof(Xml));
public static readonly MessageFormat Json = new(1, nameof(Json));
public static readonly DocumentFormat Xml = new(0, nameof(Xml));
public static readonly DocumentFormat Json = new(1, nameof(Json));

private MessageFormat(int id, string name)
private DocumentFormat(int id, string name)
: base(id, name)
{
}
Expand Down
2 changes: 1 addition & 1 deletion source/Domain/OutgoingMessages/IMessageWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public interface IMessageWriter
/// Determine if specified format can be handled by message writer
/// </summary>
/// <param name="format"></param>
bool HandlesFormat(MessageFormat format);
bool HandlesFormat(DocumentFormat format);

/// <summary>
/// Determine if specified message type can be handles by the writer
Expand Down
4 changes: 2 additions & 2 deletions source/Infrastructure/IncomingMessages/CimFormatParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ namespace Infrastructure.IncomingMessages;

public static class CimFormatParser
{
public static MessageFormat? ParseFromContentTypeHeaderValue(string value)
public static DocumentFormat? ParseFromContentTypeHeaderValue(string value)
{
if (value == null) throw new ArgumentNullException(nameof(value));
var contentType = ParseContentTypeName(value);

return EnumerationType.GetAll
<MessageFormat>()
<DocumentFormat>()
.FirstOrDefault(v => v.Name.Equals(contentType, StringComparison.OrdinalIgnoreCase));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using DocumentValidation;
using DocumentValidation.CimXml;
using Domain.OutgoingMessages;
using DocumentFormat = Domain.OutgoingMessages.DocumentFormat;
using MarketActivityRecord = Application.IncomingMessages.RequestChangeAccountPointCharacteristics.MarketActivityRecord;

namespace Infrastructure.IncomingMessages.RequestChangeAccountingPointCharacteristics;
Expand All @@ -40,7 +41,7 @@ public XmlMessageParser()
_schemaProvider = new CimXmlSchemaProvider();
}

public MessageFormat HandledFormat => MessageFormat.Xml;
public DocumentFormat HandledFormat => DocumentFormat.Xml;

public async Task<MessageParserResult<MarketActivityRecord, RequestChangeAccountingPointCharacteristicsTransaction>>
ParseAsync(Stream message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using DocumentValidation;
using DocumentValidation.CimXml;
using Domain.OutgoingMessages;
using DocumentFormat = Domain.OutgoingMessages.DocumentFormat;
using MarketActivityRecord = Application.IncomingMessages.RequestChangeCustomerCharacteristics.MarketActivityRecord;

namespace Infrastructure.IncomingMessages.RequestChangeCustomerCharacteristics;
Expand All @@ -40,7 +41,7 @@ public XmlMessageParser()
_schemaProvider = new CimXmlSchemaProvider();
}

public MessageFormat HandledFormat => MessageFormat.Xml;
public DocumentFormat HandledFormat => DocumentFormat.Xml;

public async Task<MessageParserResult<MarketActivityRecord, RequestChangeCustomerCharacteristicsTransaction>> ParseAsync(Stream message)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
using DocumentValidation;
using Domain.OutgoingMessages;
using Json.Schema;
using DocumentFormat = Domain.OutgoingMessages.DocumentFormat;
using MessageHeader = Application.IncomingMessages.MessageHeader;

namespace Infrastructure.IncomingMessages.RequestChangeOfSupplier;
Expand All @@ -44,7 +45,7 @@ public JsonMessageParser(JsonSchemaProvider schemaProvider)
_schemaProvider = schemaProvider;
}

public MessageFormat HandledFormat => MessageFormat.Json;
public DocumentFormat HandledFormat => DocumentFormat.Json;

public async Task<MessageParserResult<MarketActivityRecord, RequestChangeOfSupplierTransaction>> ParseAsync(Stream message)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using DocumentValidation;
using DocumentValidation.CimXml;
using Domain.OutgoingMessages;
using DocumentFormat = Domain.OutgoingMessages.DocumentFormat;

namespace Infrastructure.IncomingMessages.RequestChangeOfSupplier;

Expand All @@ -39,7 +40,7 @@ public XmlMessageParser()
_schemaProvider = new CimXmlSchemaProvider();
}

public MessageFormat HandledFormat => MessageFormat.Xml;
public DocumentFormat HandledFormat => DocumentFormat.Xml;

public async Task<MessageParserResult<MarketActivityRecord, RequestChangeOfSupplierTransaction>> ParseAsync(Stream message)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace Infrastructure.IncomingMessages.Response;

public class JsonResponseFactory : IResponseFactory
{
public MessageFormat HandledFormat => MessageFormat.Json;
public DocumentFormat HandledFormat => DocumentFormat.Json;

public ResponseMessage From(Result result)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace Infrastructure.IncomingMessages.Response
{
public class XmlResponseFactory : IResponseFactory
{
public MessageFormat HandledFormat => MessageFormat.Xml;
public DocumentFormat HandledFormat => DocumentFormat.Xml;

public ResponseMessage From(Result result)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ public bool HandlesType(MessageType messageType)
return messageType.Name.Equals(_documentDetails.Type.Split("_")[0], StringComparison.OrdinalIgnoreCase);
}

public bool HandlesFormat(MessageFormat format)
public bool HandlesFormat(DocumentFormat format)
{
return format == MessageFormat.Xml;
return format == DocumentFormat.Xml;
}

protected abstract Task WriteMarketActivityRecordsAsync(IReadOnlyCollection<string> marketActivityPayloads, XmlWriter writer);
Expand Down
Loading

0 comments on commit 0ccba2b

Please sign in to comment.