diff --git a/source/ApplyDBMigrationsApp/ApplyDBMigrationsApp.csproj b/source/ApplyDBMigrationsApp/ApplyDBMigrationsApp.csproj
index 5cd19f75f0..621269594e 100644
--- a/source/ApplyDBMigrationsApp/ApplyDBMigrationsApp.csproj
+++ b/source/ApplyDBMigrationsApp/ApplyDBMigrationsApp.csproj
@@ -25,7 +25,7 @@ limitations under the License.
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/ArchitectureTests/ArchitectureTests.csproj b/source/ArchitectureTests/ArchitectureTests.csproj
index 5e0cedfb02..8b297e8862 100644
--- a/source/ArchitectureTests/ArchitectureTests.csproj
+++ b/source/ArchitectureTests/ArchitectureTests.csproj
@@ -22,14 +22,14 @@ limitations under the License.
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/ArchivedMessages.Application/ArchivedMessages.Application.csproj b/source/ArchivedMessages.Application/ArchivedMessages.Application.csproj
index 235c70fde8..7cc7c8fa91 100644
--- a/source/ArchivedMessages.Application/ArchivedMessages.Application.csproj
+++ b/source/ArchivedMessages.Application/ArchivedMessages.Application.csproj
@@ -4,7 +4,7 @@
Energinet.DataHub.EDI.ArchivedMessages.Application
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/ArchivedMessages.Domain/ArchivedMessages.Domain.csproj b/source/ArchivedMessages.Domain/ArchivedMessages.Domain.csproj
index e056c42ed9..42cb27ced7 100644
--- a/source/ArchivedMessages.Domain/ArchivedMessages.Domain.csproj
+++ b/source/ArchivedMessages.Domain/ArchivedMessages.Domain.csproj
@@ -4,7 +4,7 @@
Energinet.DataHub.EDI.ArchivedMessages.Domain
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/ArchivedMessages.Infrastructure/ArchivedMessages.Infrastructure.csproj b/source/ArchivedMessages.Infrastructure/ArchivedMessages.Infrastructure.csproj
index d483cb6030..03e8272252 100644
--- a/source/ArchivedMessages.Infrastructure/ArchivedMessages.Infrastructure.csproj
+++ b/source/ArchivedMessages.Infrastructure/ArchivedMessages.Infrastructure.csproj
@@ -8,7 +8,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/ArchivedMessages.IntegrationTests/ArchivedMessages.IntegrationTests.csproj b/source/ArchivedMessages.IntegrationTests/ArchivedMessages.IntegrationTests.csproj
index fc37da3b3e..07346d50cf 100644
--- a/source/ArchivedMessages.IntegrationTests/ArchivedMessages.IntegrationTests.csproj
+++ b/source/ArchivedMessages.IntegrationTests/ArchivedMessages.IntegrationTests.csproj
@@ -24,7 +24,7 @@ limitations under the License.
-
+
diff --git a/source/ArchivedMessages.Interfaces/ArchivedMessages.Interfaces.csproj b/source/ArchivedMessages.Interfaces/ArchivedMessages.Interfaces.csproj
index 1a5c7949be..cd9db23b79 100644
--- a/source/ArchivedMessages.Interfaces/ArchivedMessages.Interfaces.csproj
+++ b/source/ArchivedMessages.Interfaces/ArchivedMessages.Interfaces.csproj
@@ -4,7 +4,7 @@
Energinet.DataHub.EDI.ArchivedMessages.Interfaces
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/AuditLog/AuditLog.csproj b/source/AuditLog/AuditLog.csproj
index eb57d2b93b..b9332595e3 100644
--- a/source/AuditLog/AuditLog.csproj
+++ b/source/AuditLog/AuditLog.csproj
@@ -8,7 +8,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/B2BApi.AppTests/B2BApi.AppTests.csproj b/source/B2BApi.AppTests/B2BApi.AppTests.csproj
index 65311d82ce..b14930657c 100644
--- a/source/B2BApi.AppTests/B2BApi.AppTests.csproj
+++ b/source/B2BApi.AppTests/B2BApi.AppTests.csproj
@@ -14,7 +14,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
@@ -22,7 +22,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/B2BApi/B2BApi.csproj b/source/B2BApi/B2BApi.csproj
index 2d6f0eb24c..a39770dfe8 100644
--- a/source/B2BApi/B2BApi.csproj
+++ b/source/B2BApi/B2BApi.csproj
@@ -42,7 +42,7 @@ limitations under the License.
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/B2CWebApi.AppTests/B2CWebApi.AppTests.csproj b/source/B2CWebApi.AppTests/B2CWebApi.AppTests.csproj
index bb23e5fd1d..ddf870af6b 100644
--- a/source/B2CWebApi.AppTests/B2CWebApi.AppTests.csproj
+++ b/source/B2CWebApi.AppTests/B2CWebApi.AppTests.csproj
@@ -20,7 +20,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/B2CWebApi/B2CWebApi.csproj b/source/B2CWebApi/B2CWebApi.csproj
index 0cc450c567..1aff022e8f 100644
--- a/source/B2CWebApi/B2CWebApi.csproj
+++ b/source/B2CWebApi/B2CWebApi.csproj
@@ -11,10 +11,10 @@
-
+
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/BuildingBlocks.Application/BuildingBlocks.Application.csproj b/source/BuildingBlocks.Application/BuildingBlocks.Application.csproj
index 99f17c252e..eb788b27ca 100644
--- a/source/BuildingBlocks.Application/BuildingBlocks.Application.csproj
+++ b/source/BuildingBlocks.Application/BuildingBlocks.Application.csproj
@@ -11,16 +11,16 @@
-
+
-
+
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/BuildingBlocks.Application/FeatureFlag/FeatureFlagName.cs b/source/BuildingBlocks.Application/FeatureFlag/FeatureFlagName.cs
index c2280bf4ed..dba0a41b63 100644
--- a/source/BuildingBlocks.Application/FeatureFlag/FeatureFlagName.cs
+++ b/source/BuildingBlocks.Application/FeatureFlag/FeatureFlagName.cs
@@ -39,4 +39,9 @@ public enum FeatureFlagName
/// Whether to use orchestration for handling RequestWholesaleServices processes.
///
UseRequestWholesaleServicesProcessOrchestration,
+
+ ///
+ /// Whether to use the new incoming message parser.
+ ///
+ UseNewIncomingMessageParser,
}
diff --git a/source/BuildingBlocks.Application/FeatureFlag/IFeatureFlagManager.cs b/source/BuildingBlocks.Application/FeatureFlag/IFeatureFlagManager.cs
index 996552ba72..53cfb689ea 100644
--- a/source/BuildingBlocks.Application/FeatureFlag/IFeatureFlagManager.cs
+++ b/source/BuildingBlocks.Application/FeatureFlag/IFeatureFlagManager.cs
@@ -43,4 +43,9 @@ public interface IFeatureFlagManager
/// Whether to use the RequestWholesaleServices process orchestration.
///
Task UseRequestWholesaleServicesProcessOrchestrationAsync();
+
+ ///
+ /// Whether to use the new incoming message parser.
+ ///
+ Task UseNewIncomingMessageParserAsync();
}
diff --git a/source/BuildingBlocks.Application/FeatureFlag/MicrosoftFeatureFlagManager.cs b/source/BuildingBlocks.Application/FeatureFlag/MicrosoftFeatureFlagManager.cs
index 96fe0ba4f6..4dcd3ad912 100644
--- a/source/BuildingBlocks.Application/FeatureFlag/MicrosoftFeatureFlagManager.cs
+++ b/source/BuildingBlocks.Application/FeatureFlag/MicrosoftFeatureFlagManager.cs
@@ -37,5 +37,7 @@ public MicrosoftFeatureFlagManager(IFeatureManager featureManager)
public Task UseRequestWholesaleServicesProcessOrchestrationAsync() =>
IsEnabledAsync(FeatureFlagName.UseRequestWholesaleServicesProcessOrchestration);
+ public Task UseNewIncomingMessageParserAsync() => IsEnabledAsync(FeatureFlagName.UseNewIncomingMessageParser);
+
private Task IsEnabledAsync(FeatureFlagName featureFlagName) => _featureManager.IsEnabledAsync(featureFlagName.ToString());
}
diff --git a/source/BuildingBlocks.Domain/BuildingBlocks.Domain.csproj b/source/BuildingBlocks.Domain/BuildingBlocks.Domain.csproj
index 12ff23a8d6..666ee793bf 100644
--- a/source/BuildingBlocks.Domain/BuildingBlocks.Domain.csproj
+++ b/source/BuildingBlocks.Domain/BuildingBlocks.Domain.csproj
@@ -4,7 +4,7 @@
Energinet.DataHub.EDI.BuildingBlocks.Domain
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/BuildingBlocks.Infrastructure/BuildingBlocks.Infrastructure.csproj b/source/BuildingBlocks.Infrastructure/BuildingBlocks.Infrastructure.csproj
index 372330b0fa..9c6a1ad166 100644
--- a/source/BuildingBlocks.Infrastructure/BuildingBlocks.Infrastructure.csproj
+++ b/source/BuildingBlocks.Infrastructure/BuildingBlocks.Infrastructure.csproj
@@ -13,7 +13,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/BuildingBlocks.Interfaces/BuildingBlocks.Interfaces.csproj b/source/BuildingBlocks.Interfaces/BuildingBlocks.Interfaces.csproj
index 2d2f9d1c24..88930e467d 100644
--- a/source/BuildingBlocks.Interfaces/BuildingBlocks.Interfaces.csproj
+++ b/source/BuildingBlocks.Interfaces/BuildingBlocks.Interfaces.csproj
@@ -5,7 +5,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/BuildingBlocks.Tests/BuildingBlocks.Tests.csproj b/source/BuildingBlocks.Tests/BuildingBlocks.Tests.csproj
index 90eb93ef26..70fa4faf16 100644
--- a/source/BuildingBlocks.Tests/BuildingBlocks.Tests.csproj
+++ b/source/BuildingBlocks.Tests/BuildingBlocks.Tests.csproj
@@ -25,8 +25,8 @@ limitations under the License.
-
-
+
+
diff --git a/source/BuildingBlocks.Tests/TestDoubles/FeatureFlagManagerStub.cs b/source/BuildingBlocks.Tests/TestDoubles/FeatureFlagManagerStub.cs
index e1069c098a..e63b1b7cb6 100644
--- a/source/BuildingBlocks.Tests/TestDoubles/FeatureFlagManagerStub.cs
+++ b/source/BuildingBlocks.Tests/TestDoubles/FeatureFlagManagerStub.cs
@@ -30,4 +30,6 @@ public class FeatureFlagManagerStub : IFeatureFlagManager
public Task ReceiveMeteredDataForMeasurementPointsAsync() => Task.FromResult(true);
public Task UseRequestWholesaleServicesProcessOrchestrationAsync() => Task.FromResult(false);
+
+ public Task UseNewIncomingMessageParserAsync() => Task.FromResult(true);
}
diff --git a/source/CalculationResults/CalculationResults.Infrastructure/CalculationResults.Infrastructure.csproj b/source/CalculationResults/CalculationResults.Infrastructure/CalculationResults.Infrastructure.csproj
index 58f7486e98..0855de7b82 100644
--- a/source/CalculationResults/CalculationResults.Infrastructure/CalculationResults.Infrastructure.csproj
+++ b/source/CalculationResults/CalculationResults.Infrastructure/CalculationResults.Infrastructure.csproj
@@ -7,7 +7,7 @@
-
+
@@ -17,7 +17,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/CalculationResults/CalculationResults.Interfaces/CalculationResults.Interfaces.csproj b/source/CalculationResults/CalculationResults.Interfaces/CalculationResults.Interfaces.csproj
index fb772402f6..6500ac5a19 100644
--- a/source/CalculationResults/CalculationResults.Interfaces/CalculationResults.Interfaces.csproj
+++ b/source/CalculationResults/CalculationResults.Interfaces/CalculationResults.Interfaces.csproj
@@ -5,7 +5,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/Contracts/Contracts.csproj b/source/Contracts/Contracts.csproj
index 81b1ef5ca5..2e783491bc 100644
--- a/source/Contracts/Contracts.csproj
+++ b/source/Contracts/Contracts.csproj
@@ -29,7 +29,7 @@ limitations under the License.
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/DataAccess.UnitOfWork/DataAccess.UnitOfWork.csproj b/source/DataAccess.UnitOfWork/DataAccess.UnitOfWork.csproj
index d8a563211a..2f095b2a80 100644
--- a/source/DataAccess.UnitOfWork/DataAccess.UnitOfWork.csproj
+++ b/source/DataAccess.UnitOfWork/DataAccess.UnitOfWork.csproj
@@ -4,7 +4,7 @@
Energinet.DataHub.EDI.DataAccess.UnitOfWork
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/DataAccess/DataAccess.csproj b/source/DataAccess/DataAccess.csproj
index a800026547..3619f0e594 100644
--- a/source/DataAccess/DataAccess.csproj
+++ b/source/DataAccess/DataAccess.csproj
@@ -10,9 +10,9 @@
-
+
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/Edi.UnitTests/Edi.UnitTests.csproj b/source/Edi.UnitTests/Edi.UnitTests.csproj
index 5d84e9e907..1249203571 100644
--- a/source/Edi.UnitTests/Edi.UnitTests.csproj
+++ b/source/Edi.UnitTests/Edi.UnitTests.csproj
@@ -6,9 +6,9 @@
true
-
+
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -26,7 +26,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/Edi/Edi.csproj b/source/Edi/Edi.csproj
index 51b915e800..38dc347044 100644
--- a/source/Edi/Edi.csproj
+++ b/source/Edi/Edi.csproj
@@ -6,12 +6,12 @@
-
+
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/IncomingMessages.Application/Extensions/DependencyInjection/IncomingMessagesExtensions.cs b/source/IncomingMessages.Application/Extensions/DependencyInjection/IncomingMessagesExtensions.cs
index dcb1bcb0a4..7cb0ab755d 100644
--- a/source/IncomingMessages.Application/Extensions/DependencyInjection/IncomingMessagesExtensions.cs
+++ b/source/IncomingMessages.Application/Extensions/DependencyInjection/IncomingMessagesExtensions.cs
@@ -19,6 +19,7 @@
using Energinet.DataHub.Core.Messaging.Communication.Extensions.Builder;
using Energinet.DataHub.Core.Messaging.Communication.Extensions.DependencyInjection;
using Energinet.DataHub.Core.Messaging.Communication.Extensions.Options;
+using Energinet.DataHub.EDI.BuildingBlocks.Domain.Models;
using Energinet.DataHub.EDI.DataAccess.Extensions.DependencyInjection;
using Energinet.DataHub.EDI.IncomingMessages.Application.UseCases;
using Energinet.DataHub.EDI.IncomingMessages.Domain.Validation;
@@ -27,6 +28,7 @@
using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.Configuration.Options;
using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers;
using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.AggregatedMeasureDataRequestMessageParsers;
+using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.MeteredDateForMeasurementPointParsers;
using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.MeteredDateForMeasurementPointParsers.Ebix;
using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.WholesaleSettlementMessageParsers;
using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.Repositories.MessageId;
@@ -133,6 +135,15 @@ public static IServiceCollection AddIncomingMessagesModule(this IServiceCollecti
.AddSingleton()
.AddSingleton()
.AddSingleton();
+
+ services
+ .AddTransient();
+
+ services.AddTransient>(provider => new Dictionary<(IncomingDocumentType, DocumentFormat), IMessageParser>
+ {
+ { (IncomingDocumentType.MeteredDataForMeasurementPoint, DocumentFormat.Ebix), provider.GetRequiredService() },
+ });
+
return services;
}
}
diff --git a/source/IncomingMessages.Application/IncomingMessages.Application.csproj b/source/IncomingMessages.Application/IncomingMessages.Application.csproj
index e33509c6f0..92eceb8c34 100644
--- a/source/IncomingMessages.Application/IncomingMessages.Application.csproj
+++ b/source/IncomingMessages.Application/IncomingMessages.Application.csproj
@@ -15,7 +15,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/IncomingMessages.Application/UseCases/ReceiveIncomingMarketMessage.cs b/source/IncomingMessages.Application/UseCases/ReceiveIncomingMarketMessage.cs
index b6b3853f93..b35f3b6932 100644
--- a/source/IncomingMessages.Application/UseCases/ReceiveIncomingMarketMessage.cs
+++ b/source/IncomingMessages.Application/UseCases/ReceiveIncomingMarketMessage.cs
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+using BuildingBlocks.Application.FeatureFlag;
using Energinet.DataHub.EDI.ArchivedMessages.Interfaces;
using Energinet.DataHub.EDI.ArchivedMessages.Interfaces.Models;
using Energinet.DataHub.EDI.BuildingBlocks.Domain.Authentication;
@@ -31,6 +32,8 @@ namespace Energinet.DataHub.EDI.IncomingMessages.Application.UseCases;
public class ReceiveIncomingMarketMessage
{
private readonly MarketMessageParser _marketMessageParser;
+ private readonly IDictionary<(IncomingDocumentType, DocumentFormat), IMessageParser> _messageParsers;
+ private readonly IFeatureFlagManager _featureFlagManager;
private readonly ValidateIncomingMessage _validateIncomingMessage;
private readonly ResponseFactory _responseFactory;
private readonly IArchivedMessagesClient _archivedMessagesClient;
@@ -42,6 +45,8 @@ public class ReceiveIncomingMarketMessage
public ReceiveIncomingMarketMessage(
MarketMessageParser marketMessageParser,
+ IDictionary<(IncomingDocumentType DocumentType, DocumentFormat DocumentFormat), IMessageParser> messageParsers,
+ IFeatureFlagManager featureFlagManager,
ValidateIncomingMessage validateIncomingMessage,
ResponseFactory responseFactory,
IArchivedMessagesClient archivedMessagesClient,
@@ -52,6 +57,8 @@ public ReceiveIncomingMarketMessage(
AuthenticatedActor actorAuthenticator)
{
_marketMessageParser = marketMessageParser;
+ _messageParsers = messageParsers;
+ _featureFlagManager = featureFlagManager;
_validateIncomingMessage = validateIncomingMessage;
_responseFactory = responseFactory;
_archivedMessagesClient = archivedMessagesClient;
@@ -71,11 +78,12 @@ public async Task ReceiveIncomingMarketMessageAsync(
{
ArgumentNullException.ThrowIfNull(documentType);
ArgumentNullException.ThrowIfNull(incomingMarketMessageStream);
-
- var incomingMarketMessageParserResult =
- await _marketMessageParser.ParseAsync(incomingMarketMessageStream, incomingDocumentFormat, documentType, cancellationToken)
- .ConfigureAwait(false);
-
+ var incomingMarketMessageParserResult = await ParseIncomingMessageAsync(
+ incomingMarketMessageStream,
+ incomingDocumentFormat,
+ documentType,
+ cancellationToken)
+ .ConfigureAwait(false);
if (incomingMarketMessageParserResult.Errors.Count != 0
|| incomingMarketMessageParserResult.IncomingMessage == null)
{
@@ -139,6 +147,24 @@ private static bool ShouldArchive(IncomingDocumentType documentType)
return documentType != IncomingDocumentType.MeteredDataForMeasurementPoint;
}
+ private async Task ParseIncomingMessageAsync(
+ IIncomingMarketMessageStream incomingMarketMessageStream,
+ DocumentFormat documentFormat,
+ IncomingDocumentType documentType,
+ CancellationToken cancellationToken)
+ {
+ if (await _featureFlagManager.UseNewIncomingMessageParserAsync().ConfigureAwait(false))
+ {
+ if (_messageParsers.TryGetValue((documentType, documentFormat), out var messageParser))
+ {
+ return await messageParser.ParseAsync(incomingMarketMessageStream, cancellationToken).ConfigureAwait(false);
+ }
+ }
+
+ return await _marketMessageParser.ParseAsync(incomingMarketMessageStream, documentFormat, documentType, cancellationToken)
+ .ConfigureAwait(false);
+ }
+
private async Task ArchiveIncomingMessageAsync(
IIncomingMarketMessageStream incomingMarketMessageStream,
IIncomingMessage incomingMessage,
diff --git a/source/IncomingMessages.Domain/IncomingMessages.Domain.csproj b/source/IncomingMessages.Domain/IncomingMessages.Domain.csproj
index 5723948fcf..184f7e8bff 100644
--- a/source/IncomingMessages.Domain/IncomingMessages.Domain.csproj
+++ b/source/IncomingMessages.Domain/IncomingMessages.Domain.csproj
@@ -10,7 +10,7 @@
enable
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/IncomingMessages.Infrastructure/IncomingMessages.Infrastructure.csproj b/source/IncomingMessages.Infrastructure/IncomingMessages.Infrastructure.csproj
index cd36ca747d..25eb422742 100644
--- a/source/IncomingMessages.Infrastructure/IncomingMessages.Infrastructure.csproj
+++ b/source/IncomingMessages.Infrastructure/IncomingMessages.Infrastructure.csproj
@@ -20,9 +20,9 @@
-
+
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/IncomingMessages.Infrastructure/MessageParsers/BaseParsers/Ebix/MessageHeaderExtractor.cs b/source/IncomingMessages.Infrastructure/MessageParsers/BaseParsers/Ebix/MessageHeaderExtractor.cs
deleted file mode 100644
index a833f42aab..0000000000
--- a/source/IncomingMessages.Infrastructure/MessageParsers/BaseParsers/Ebix/MessageHeaderExtractor.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-// 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.Xml.Linq;
-using Energinet.DataHub.EDI.BuildingBlocks.Domain.Models;
-
-namespace Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.BaseParsers.Ebix;
-
-internal static class MessageHeaderExtractor
-{
- private const string HeaderElementName = "HeaderEnergyDocument";
- private const string EnergyContextElementName = "ProcessEnergyContext";
- private const string Identification = "Identification";
- private const string DocumentType = "DocumentType";
- private const string Creation = "Creation";
- private const string SenderEnergyParty = "SenderEnergyParty";
- private const string RecipientEnergyParty = "RecipientEnergyParty";
- private const string EnergyBusinessProcess = "EnergyBusinessProcess";
- private const string EnergyBusinessProcessRole = "EnergyBusinessProcessRole";
- private const string EnergyIndustryClassification = "EnergyIndustryClassification";
-
- public static MessageHeader Extract(
- XDocument document,
- XNamespace ns)
- {
- var headerElement = document.Descendants(ns + HeaderElementName).SingleOrDefault();
- if (headerElement == null) throw new InvalidOperationException("Header element not found");
-
- var messageId = headerElement.Element(ns + Identification)?.Value ?? string.Empty;
- var messageType = headerElement.Element(ns + DocumentType)?.Value ?? string.Empty;
- var createdAt = headerElement.Element(ns + Creation)?.Value ?? string.Empty;
- var senderId = headerElement.Element(ns + SenderEnergyParty)?.Element(ns + Identification)?.Value ?? string.Empty;
- var receiverId = headerElement.Element(ns + RecipientEnergyParty)?.Element(ns + Identification)?.Value ?? string.Empty;
-
- var energyContextElement = document.Descendants(ns + EnergyContextElementName).FirstOrDefault();
- if (energyContextElement == null) throw new InvalidOperationException("Energy Context element not found");
-
- var businessReason = energyContextElement.Element(ns + EnergyBusinessProcess)?.Value ?? string.Empty;
- var senderRole = energyContextElement.Element(ns + EnergyBusinessProcessRole)?.Value ?? string.Empty;
- var businessType = energyContextElement.Element(ns + EnergyIndustryClassification)?.Value;
-
- return new MessageHeader(
- messageId,
- messageType,
- businessReason,
- senderId,
- senderRole,
- receiverId,
- // ReceiverRole is not specified in incoming Ebix documents
- ActorRole.MeteredDataAdministrator.Code,
- createdAt,
- businessType);
- }
-}
diff --git a/source/IncomingMessages.Infrastructure/MessageParsers/EbixMessageParserBase.cs b/source/IncomingMessages.Infrastructure/MessageParsers/EbixMessageParserBase.cs
new file mode 100644
index 0000000000..d7a2509ddb
--- /dev/null
+++ b/source/IncomingMessages.Infrastructure/MessageParsers/EbixMessageParserBase.cs
@@ -0,0 +1,215 @@
+// 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.Xml;
+using System.Xml.Linq;
+using System.Xml.Schema;
+using Energinet.DataHub.EDI.BuildingBlocks.Domain.Models;
+using Energinet.DataHub.EDI.IncomingMessages.Domain.Abstractions;
+using Energinet.DataHub.EDI.IncomingMessages.Domain.Validation.ValidationErrors;
+using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.BaseParsers;
+using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.Schemas.Ebix;
+
+namespace Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers;
+
+public abstract class EbixMessageParserBase(EbixSchemaProvider schemaProvider) : MessageParserBase()
+{
+ private const string HeaderElementName = "HeaderEnergyDocument";
+ private const string EnergyContextElementName = "ProcessEnergyContext";
+ private const string Identification = "Identification";
+ private const string DocumentType = "DocumentType";
+ private const string Creation = "Creation";
+ private const string SenderEnergyParty = "SenderEnergyParty";
+ private const string RecipientEnergyParty = "RecipientEnergyParty";
+ private const string EnergyBusinessProcess = "EnergyBusinessProcess";
+ private const string EnergyBusinessProcessRole = "EnergyBusinessProcessRole";
+ private const string EnergyIndustryClassification = "EnergyIndustryClassification";
+ private readonly EbixSchemaProvider _schemaProvider = schemaProvider;
+
+ protected abstract string RootPayloadElementName { get; }
+
+ protected override async Task ParseMessageAsync(
+ IIncomingMarketMessageStream marketMessage,
+ XmlSchema schemaResult,
+ CancellationToken cancellationToken)
+ {
+ using var reader = XmlReader.Create(marketMessage.Stream, CreateXmlReaderSettings(schemaResult));
+ if (Errors.Count > 0)
+ {
+ return new IncomingMarketMessageParserResult(Errors.ToArray());
+ }
+
+ var document = await XDocument.LoadAsync(reader, LoadOptions.None, cancellationToken).ConfigureAwait(false);
+ var @namespace = GetNamespace(marketMessage);
+ var ns = XNamespace.Get(@namespace);
+
+ var header = ParseHeader(document, ns);
+ var transactions = ParseTransactions(document, ns, header.SenderId);
+
+ if (Errors.Count != 0)
+ {
+ return new IncomingMarketMessageParserResult(Errors.ToArray());
+ }
+
+ return CreateResult(header, transactions);
+ }
+
+ protected override async Task<(XmlSchema? Schema, IncomingMarketMessageParserResult? Result)> GetSchemaAsync(IIncomingMarketMessageStream marketMessage, CancellationToken cancellationToken)
+ {
+ string? @namespace = null;
+ IncomingMarketMessageParserResult? parserResult = null;
+ XmlSchema? xmlSchema = default;
+ try
+ {
+ @namespace = GetNamespace(marketMessage);
+ var version = GetVersion(@namespace);
+ var businessProcessType = BusinessProcessType(@namespace);
+ xmlSchema = await _schemaProvider.GetSchemaAsync(businessProcessType, version, cancellationToken)
+ .ConfigureAwait(true);
+
+ if (xmlSchema is null)
+ {
+ parserResult = new IncomingMarketMessageParserResult(
+ new InvalidBusinessReasonOrVersion(businessProcessType, version));
+ }
+ }
+ catch (XmlException exception)
+ {
+ parserResult = Invalid(exception);
+ }
+ catch (ObjectDisposedException objectDisposedException)
+ {
+ parserResult = Invalid(objectDisposedException);
+ }
+ catch (IndexOutOfRangeException indexOutOfRangeException)
+ {
+ parserResult = Invalid(indexOutOfRangeException);
+ }
+
+ return (xmlSchema, parserResult);
+ }
+
+ protected abstract IReadOnlyCollection ParseTransactions(XDocument document, XNamespace ns, string senderNumber);
+
+ protected abstract IncomingMarketMessageParserResult CreateResult(MessageHeader header, IReadOnlyCollection transactions);
+
+ private static string[] SplitNamespace(string @namespace)
+ {
+ ArgumentNullException.ThrowIfNull(@namespace);
+ return @namespace.Split(':');
+ }
+
+ private string GetNamespace(IIncomingMarketMessageStream marketMessage)
+ {
+ ArgumentNullException.ThrowIfNull(marketMessage);
+
+ var settings = new XmlReaderSettings
+ {
+ Async = true,
+ IgnoreWhitespace = true,
+ IgnoreComments = true,
+ };
+
+ using var reader = XmlReader.Create(marketMessage.Stream, settings);
+ while (reader.Read())
+ {
+ if (reader.NodeType == XmlNodeType.Element && reader.Name.Contains(RootPayloadElementName))
+ {
+ return reader.NamespaceURI;
+ }
+ }
+
+ throw new XmlException($"Namespace for element '{RootPayloadElementName}' not found.");
+ }
+
+ private string BusinessProcessType(string @namespace)
+ {
+ ArgumentNullException.ThrowIfNull(@namespace);
+ var split = SplitNamespace(@namespace);
+ if (split.Length < 5)
+ {
+ throw new XmlException($"Invalid namespace format");
+ }
+
+ var businessReason = split[4];
+ var parts = businessReason.Split('-');
+ return parts.Last();
+ }
+
+ private string GetVersion(string @namespace)
+ {
+ ArgumentNullException.ThrowIfNull(@namespace);
+ var split = SplitNamespace(@namespace);
+ if (split.Length < 6)
+ {
+ throw new XmlException($"Invalid namespace format");
+ }
+
+ var version = split[5];
+ return version.StartsWith('v') ? version[1..] : version;
+ }
+
+ private MessageHeader ParseHeader(XDocument document, XNamespace ns)
+ {
+ var headerElement = document.Descendants(ns + HeaderElementName).SingleOrDefault();
+ if (headerElement == null) throw new InvalidOperationException("Header element not found");
+
+ var messageId = headerElement.Element(ns + Identification)?.Value ?? string.Empty;
+ var messageType = headerElement.Element(ns + DocumentType)?.Value ?? string.Empty;
+ var createdAt = headerElement.Element(ns + Creation)?.Value ?? string.Empty;
+ var senderId = headerElement.Element(ns + SenderEnergyParty)?.Element(ns + Identification)?.Value ?? string.Empty;
+ var receiverId = headerElement.Element(ns + RecipientEnergyParty)?.Element(ns + Identification)?.Value ?? string.Empty;
+
+ var energyContextElement = document.Descendants(ns + EnergyContextElementName).FirstOrDefault();
+ if (energyContextElement == null) throw new InvalidOperationException("Energy Context element not found");
+
+ var businessReason = energyContextElement.Element(ns + EnergyBusinessProcess)?.Value ?? string.Empty;
+ var senderRole = energyContextElement.Element(ns + EnergyBusinessProcessRole)?.Value ?? string.Empty;
+ var businessType = energyContextElement.Element(ns + EnergyIndustryClassification)?.Value;
+
+ return new MessageHeader(
+ messageId,
+ messageType,
+ businessReason,
+ senderId,
+ senderRole,
+ receiverId,
+ // ReceiverRole is not specified in incoming Ebix documents
+ ActorRole.MeteredDataAdministrator.Code,
+ createdAt,
+ businessType);
+ }
+
+ private XmlReaderSettings CreateXmlReaderSettings(XmlSchema xmlSchema)
+ {
+ var settings = new XmlReaderSettings
+ {
+ Async = true,
+ ValidationType = ValidationType.Schema,
+ ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema |
+ XmlSchemaValidationFlags.ReportValidationWarnings,
+ };
+
+ settings.Schemas.Add(xmlSchema);
+ settings.ValidationEventHandler += OnValidationError;
+ return settings;
+ }
+
+ private void OnValidationError(object? sender, ValidationEventArgs arguments)
+ {
+ var message =
+ $"XML schema validation error at line {arguments.Exception.LineNumber}, position {arguments.Exception.LinePosition}: {arguments.Message}.";
+ Errors.Add(InvalidMessageStructure.From(message));
+ }
+}
diff --git a/source/ProcessManager.Core/Infrastructure/Database/UnitOfWork.cs b/source/IncomingMessages.Infrastructure/MessageParsers/IMessageParser.cs
similarity index 58%
rename from source/ProcessManager.Core/Infrastructure/Database/UnitOfWork.cs
rename to source/IncomingMessages.Infrastructure/MessageParsers/IMessageParser.cs
index 6cf2941491..8ae2eb732e 100644
--- a/source/ProcessManager.Core/Infrastructure/Database/UnitOfWork.cs
+++ b/source/IncomingMessages.Infrastructure/MessageParsers/IMessageParser.cs
@@ -12,21 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.EDI.BuildingBlocks.Domain.Models;
-namespace Energinet.DataHub.ProcessManagement.Core.Infrastructure.Database;
+namespace Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers;
-public class UnitOfWork : IUnitOfWork
+public interface IMessageParser
{
- private readonly ProcessManagerContext _context;
-
- public UnitOfWork(ProcessManagerContext context)
- {
- _context = context;
- }
-
- public async Task CommitAsync()
- {
- await _context.SaveChangesAsync().ConfigureAwait(false);
- }
+ Task ParseAsync(
+ IIncomingMarketMessageStream marketMessage,
+ CancellationToken cancellationToken);
}
diff --git a/source/IncomingMessages.Infrastructure/MessageParsers/MarketMessageParser.cs b/source/IncomingMessages.Infrastructure/MessageParsers/MarketMessageParser.cs
index 623d1df1e0..cf3d14a0dc 100644
--- a/source/IncomingMessages.Infrastructure/MessageParsers/MarketMessageParser.cs
+++ b/source/IncomingMessages.Infrastructure/MessageParsers/MarketMessageParser.cs
@@ -34,7 +34,7 @@ public Task ParseAsync(
var parser = _parsers.FirstOrDefault(parser =>
parser.HandledFormat.Equals(documentFormat) && parser.DocumentType.Equals(documentType));
if (parser is null)
- throw new InvalidOperationException($"No message parser found for message format '{documentFormat}' and document type '{documentType}'");
+ throw new NotSupportedException($"No message parser found for message format '{documentFormat}' and document type '{documentType}'");
return parser.ParseAsync(marketMessage, cancellationToken);
}
}
diff --git a/source/IncomingMessages.Infrastructure/MessageParsers/MessageParserBase.cs b/source/IncomingMessages.Infrastructure/MessageParsers/MessageParserBase.cs
new file mode 100644
index 0000000000..2eb594349d
--- /dev/null
+++ b/source/IncomingMessages.Infrastructure/MessageParsers/MessageParserBase.cs
@@ -0,0 +1,55 @@
+// 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.Collections.ObjectModel;
+using System.Xml;
+using Energinet.DataHub.EDI.BuildingBlocks.Domain.Models;
+using Energinet.DataHub.EDI.IncomingMessages.Domain.Validation.ValidationErrors;
+using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.Schemas;
+
+namespace Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers;
+
+public abstract class MessageParserBase() : IMessageParser
+{
+ protected Collection Errors { get; } = [];
+
+ public async Task ParseAsync(
+ IIncomingMarketMessageStream marketMessage,
+ CancellationToken cancellationToken)
+ {
+ var schemaResult = await GetSchemaAsync(marketMessage, cancellationToken).ConfigureAwait(false);
+ if (schemaResult.Schema == null)
+ {
+ return schemaResult.Result ?? new IncomingMarketMessageParserResult(new InvalidSchemaOrNamespace());
+ }
+
+ return await ParseMessageAsync(marketMessage, schemaResult.Schema, cancellationToken)
+ .ConfigureAwait(false);
+ }
+
+ protected static IncomingMarketMessageParserResult Invalid(
+ Exception exception)
+ {
+ return new IncomingMarketMessageParserResult(
+ InvalidMessageStructure.From(exception));
+ }
+
+ protected abstract Task<(TSchema? Schema, IncomingMarketMessageParserResult? Result)>
+ GetSchemaAsync(IIncomingMarketMessageStream marketMessage, CancellationToken cancellationToken);
+
+ protected abstract Task ParseMessageAsync(
+ IIncomingMarketMessageStream marketMessage,
+ TSchema schemaResult,
+ CancellationToken cancellationToken);
+}
diff --git a/source/IncomingMessages.Infrastructure/MessageParsers/MeteredDateForMeasurementPointParsers/Ebix/MeteredDataForMeasurementPointEbixMessageParser.cs b/source/IncomingMessages.Infrastructure/MessageParsers/MeteredDateForMeasurementPointParsers/Ebix/MeteredDataForMeasurementPointEbixMessageParser.cs
index 638d7606dd..6eea4b4dcf 100644
--- a/source/IncomingMessages.Infrastructure/MessageParsers/MeteredDateForMeasurementPointParsers/Ebix/MeteredDataForMeasurementPointEbixMessageParser.cs
+++ b/source/IncomingMessages.Infrastructure/MessageParsers/MeteredDateForMeasurementPointParsers/Ebix/MeteredDataForMeasurementPointEbixMessageParser.cs
@@ -12,220 +12,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using System.Collections.ObjectModel;
-using System.Xml;
-using System.Xml.Linq;
-using System.Xml.Schema;
using Energinet.DataHub.EDI.BuildingBlocks.Domain.Models;
-using Energinet.DataHub.EDI.IncomingMessages.Domain;
-using Energinet.DataHub.EDI.IncomingMessages.Domain.Validation.ValidationErrors;
-using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.Schemas.Ebix;
-using Microsoft.Extensions.Logging;
-using MessageHeaderExtractor = Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.BaseParsers.Ebix.MessageHeaderExtractor;
namespace Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.MeteredDateForMeasurementPointParsers.Ebix;
-public class MeteredDataForMeasurementPointEbixMessageParser(EbixSchemaProvider schemaProvider, ILogger logger) : IMarketMessageParser
+public class MeteredDataForMeasurementPointEbixMessageParser(EbixMessageParser messageParser) : IMarketMessageParser
{
- private const string RootPayloadElementName = "DK_MeteredDataTimeSeries";
- private readonly EbixSchemaProvider _schemaProvider = schemaProvider;
- private readonly ILogger _logger = logger;
+ private readonly EbixMessageParser _messageParser = messageParser;
public DocumentFormat HandledFormat => DocumentFormat.Ebix;
public IncomingDocumentType DocumentType => IncomingDocumentType.MeteredDataForMeasurementPoint;
- private Collection Errors { get; } = [];
-
public async Task ParseAsync(
IIncomingMarketMessageStream incomingMarketMessageStream,
CancellationToken cancellationToken)
{
- var xmlSchemaResult = await GetSchemaAsync(incomingMarketMessageStream, cancellationToken).ConfigureAwait(false);
- if (xmlSchemaResult.Schema == null || xmlSchemaResult.Namespace == null)
- {
- return xmlSchemaResult.ParserResult ?? new IncomingMarketMessageParserResult(new InvalidSchemaOrNamespace());
- }
-
- using var reader = XmlReader.Create(incomingMarketMessageStream.Stream, CreateXmlReaderSettings(xmlSchemaResult.Schema));
- if (Errors.Count > 0)
- {
- return new IncomingMarketMessageParserResult(Errors.ToArray());
- }
-
- try
- {
- var parsedXmlData = await ParseXmlDataAsync(reader, xmlSchemaResult.Namespace, cancellationToken).ConfigureAwait(false);
-
- if (Errors.Count != 0)
- {
- _logger.LogError("Errors found after parsing XML data: {Errors}", Errors);
- return new IncomingMarketMessageParserResult(Errors.ToArray());
- }
-
- return parsedXmlData;
- }
- catch (XmlException exception)
- {
- _logger.LogError(exception, "Ebix parsing error during data extraction");
- return InvalidEbixFailure(exception);
- }
- catch (ObjectDisposedException objectDisposedException)
- {
- _logger.LogError(objectDisposedException, "Stream was disposed during data extraction");
- return InvalidEbixFailure(objectDisposedException);
- }
- }
-
- private static IncomingMarketMessageParserResult InvalidEbixFailure(
- Exception exception)
- {
- return new IncomingMarketMessageParserResult(
- InvalidMessageStructure.From(exception));
- }
-
- private static string BusinessProcessType(string @namespace)
- {
- ArgumentNullException.ThrowIfNull(@namespace);
- var split = SplitNamespace(@namespace);
- if (split.Length < 5)
- {
- throw new XmlException($"Invalid namespace format");
- }
-
- var businessReason = split[4];
- var parts = businessReason.Split('-');
- return parts.Last();
- }
-
- private static string GetVersion(string @namespace)
- {
- ArgumentNullException.ThrowIfNull(@namespace);
- var split = SplitNamespace(@namespace);
- if (split.Length < 6)
- {
- throw new XmlException($"Invalid namespace format");
- }
-
- var version = split[5];
- return version.StartsWith('v') ? version[1..] : version;
- }
-
- private static string[] SplitNamespace(string @namespace)
- {
- ArgumentNullException.ThrowIfNull(@namespace);
- return @namespace.Split(':');
- }
-
- private static string GetNamespace(IIncomingMarketMessageStream marketMessage)
- {
- ArgumentNullException.ThrowIfNull(marketMessage);
-
- var settings = new XmlReaderSettings
- {
- Async = true,
- IgnoreWhitespace = true,
- IgnoreComments = true,
- };
-
- using var reader = XmlReader.Create(marketMessage.Stream, settings);
- while (reader.Read())
- {
- if (reader.NodeType == XmlNodeType.Element && reader.Name.Contains(RootPayloadElementName))
- {
- return reader.NamespaceURI;
- }
- }
-
- throw new XmlException($"Namespace for element '{RootPayloadElementName}' not found.");
- }
-
- private async Task ParseXmlDataAsync(
- XmlReader reader,
- string @namespace,
- CancellationToken cancellationToken)
- {
- var document = await XDocument.LoadAsync(reader, LoadOptions.None, cancellationToken).ConfigureAwait(false);
- var ns = XNamespace.Get(@namespace);
-
- var header = MessageHeaderExtractor.Extract(document, ns);
- var listOfSeries = MeteredDataForMeasurementPointSeriesExtractor
- .ParseSeries(document, ns, header.SenderId)
- .ToList();
-
- return new IncomingMarketMessageParserResult(new MeteredDataForMeasurementPointMessage(
- header.MessageId,
- header.MessageType,
- header.CreatedAt,
- header.SenderId,
- header.ReceiverId,
- header.SenderRole,
- header.BusinessReason,
- header.ReceiverRole,
- header.BusinessType,
- listOfSeries.AsReadOnly()));
- }
-
- private async Task<(XmlSchema? Schema, string? Namespace, IncomingMarketMessageParserResult? ParserResult)> GetSchemaAsync(
- IIncomingMarketMessageStream incomingMarketMessageStream,
- CancellationToken cancellationToken)
- {
- string? @namespace = null;
- IncomingMarketMessageParserResult? parserResult = null;
- XmlSchema? xmlSchema = null;
- try
- {
- @namespace = GetNamespace(incomingMarketMessageStream);
- var version = GetVersion(@namespace);
- var businessProcessType = BusinessProcessType(@namespace);
- xmlSchema = await _schemaProvider.GetSchemaAsync(businessProcessType, version, cancellationToken)
- .ConfigureAwait(true);
-
- if (xmlSchema is null)
- {
- _logger.LogError("Schema not found for business process type {BusinessProcessType} and version {Version}", businessProcessType, version);
- parserResult = new IncomingMarketMessageParserResult(
- new InvalidBusinessReasonOrVersion(businessProcessType, version));
- }
- }
- catch (XmlException exception)
- {
- _logger.LogWarning(exception, "Ebix parsing error");
- parserResult = InvalidEbixFailure(exception);
- }
- catch (ObjectDisposedException objectDisposedException)
- {
- _logger.LogWarning(objectDisposedException, "Stream was disposed");
- parserResult = InvalidEbixFailure(objectDisposedException);
- }
- catch (IndexOutOfRangeException indexOutOfRangeException)
- {
- _logger.LogWarning(indexOutOfRangeException, "Namespace format is invalid");
- parserResult = InvalidEbixFailure(indexOutOfRangeException);
- }
-
- return (xmlSchema, @namespace, parserResult);
- }
-
- private XmlReaderSettings CreateXmlReaderSettings(XmlSchema xmlSchema)
- {
- var settings = new XmlReaderSettings
- {
- Async = true,
- ValidationType = ValidationType.Schema,
- ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema |
- XmlSchemaValidationFlags.ReportValidationWarnings,
- };
-
- settings.Schemas.Add(xmlSchema);
- settings.ValidationEventHandler += OnValidationError;
- return settings;
- }
-
- private void OnValidationError(object? sender, ValidationEventArgs arguments)
- {
- var message =
- $"XML schema validation error at line {arguments.Exception.LineNumber}, position {arguments.Exception.LinePosition}: {arguments.Message}.";
- Errors.Add(InvalidMessageStructure.From(message));
+ return await _messageParser.ParseAsync(incomingMarketMessageStream, cancellationToken).ConfigureAwait(false);
}
}
diff --git a/source/IncomingMessages.Infrastructure/MessageParsers/MeteredDateForMeasurementPointParsers/Ebix/MeteredDataForMeasurementPointSeriesExtractor.cs b/source/IncomingMessages.Infrastructure/MessageParsers/MeteredDateForMeasurementPointParsers/Ebix/MeteredDataForMeasurementPointSeriesExtractor.cs
deleted file mode 100644
index 5e1356b0e1..0000000000
--- a/source/IncomingMessages.Infrastructure/MessageParsers/MeteredDateForMeasurementPointParsers/Ebix/MeteredDataForMeasurementPointSeriesExtractor.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-// 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.Xml.Linq;
-using Energinet.DataHub.EDI.IncomingMessages.Domain;
-
-namespace Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.MeteredDateForMeasurementPointParsers.Ebix;
-
-public static class MeteredDataForMeasurementPointSeriesExtractor
-{
- private const string SeriesElementName = "PayloadEnergyTimeSeries";
- private const string Identification = "Identification";
- private const string ResolutionDuration = "ResolutionDuration";
- private const string ObservationTimeSeriesPeriod = "ObservationTimeSeriesPeriod";
- private const string Start = "Start";
- private const string End = "End";
- private const string IncludedProductCharacteristic = "IncludedProductCharacteristic";
- private const string UnitType = "UnitType";
- private const string DetailMeasurementMeteringPointCharacteristic = "DetailMeasurementMeteringPointCharacteristic";
- private const string TypeOfMeteringPoint = "TypeOfMeteringPoint";
- private const string MeteringPointDomainLocation = "MeteringPointDomainLocation";
- private const string Position = "Position";
- private const string EnergyQuantity = "EnergyQuantity";
- private const string QuantityQuality = "QuantityQuality";
- private const string IntervalEnergyObservation = "IntervalEnergyObservation";
-
- internal static IEnumerable ParseSeries(
- XDocument document,
- XNamespace ns,
- string senderNumber)
- {
- var seriesElements = document.Descendants(ns + SeriesElementName);
-
- foreach (var seriesElement in seriesElements)
- {
- var id = seriesElement.Element(ns + Identification)?.Value ?? string.Empty;
- var resolution = seriesElement.Element(ns + ObservationTimeSeriesPeriod)?.Element(ns + ResolutionDuration)?.Value;
- var startDateAndOrTimeDateTime = seriesElement.Element(ns + ObservationTimeSeriesPeriod)?.Element(ns + Start)?.Value ?? string.Empty;
- var endDateAndOrTimeDateTime = seriesElement.Element(ns + ObservationTimeSeriesPeriod)?.Element(ns + End)?.Value;
- var productNumber = seriesElement.Element(ns + IncludedProductCharacteristic)?.Element(ns + Identification)?.Value;
- var productUnitType = seriesElement.Element(ns + IncludedProductCharacteristic)?.Element(ns + UnitType)?.Value;
- var meteringPointType = seriesElement.Element(ns + DetailMeasurementMeteringPointCharacteristic)?.Element(ns + TypeOfMeteringPoint)?.Value;
- var meteringPointLocationId = seriesElement.Element(ns + MeteringPointDomainLocation)?.Element(ns + Identification)?.Value;
-
- var energyObservations = seriesElement
- .Descendants(ns + IntervalEnergyObservation)
- .Select(e => new EnergyObservation(
- e.Element(ns + Position)?.Value,
- e.Element(ns + EnergyQuantity)?.Value,
- e.Element(ns + QuantityQuality)?.Value))
- .ToList();
-
- yield return new MeteredDataForMeasurementPointSeries(
- id,
- resolution,
- startDateAndOrTimeDateTime,
- endDateAndOrTimeDateTime,
- productNumber,
- productUnitType,
- meteringPointType,
- meteringPointLocationId,
- senderNumber,
- energyObservations);
- }
- }
-}
diff --git a/source/IncomingMessages.Infrastructure/MessageParsers/MeteredDateForMeasurementPointParsers/EbixMessageParser.cs b/source/IncomingMessages.Infrastructure/MessageParsers/MeteredDateForMeasurementPointParsers/EbixMessageParser.cs
new file mode 100644
index 0000000000..c49bf01843
--- /dev/null
+++ b/source/IncomingMessages.Infrastructure/MessageParsers/MeteredDateForMeasurementPointParsers/EbixMessageParser.cs
@@ -0,0 +1,96 @@
+// 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.Xml.Linq;
+using Energinet.DataHub.EDI.IncomingMessages.Domain;
+using Energinet.DataHub.EDI.IncomingMessages.Domain.Abstractions;
+using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.BaseParsers;
+using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.Schemas.Ebix;
+
+namespace Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.MeteredDateForMeasurementPointParsers;
+
+public class EbixMessageParser(EbixSchemaProvider schemaProvider) : EbixMessageParserBase(schemaProvider)
+{
+ private const string SeriesElementName = "PayloadEnergyTimeSeries";
+ private const string Identification = "Identification";
+ private const string ResolutionDuration = "ResolutionDuration";
+ private const string ObservationTimeSeriesPeriod = "ObservationTimeSeriesPeriod";
+ private const string Start = "Start";
+ private const string End = "End";
+ private const string IncludedProductCharacteristic = "IncludedProductCharacteristic";
+ private const string UnitType = "UnitType";
+ private const string DetailMeasurementMeteringPointCharacteristic = "DetailMeasurementMeteringPointCharacteristic";
+ private const string MeteringPointType = "TypeOfMeteringPoint";
+ private const string MeteringPointDomainLocation = "MeteringPointDomainLocation";
+ private const string Position = "Position";
+ private const string EnergyQuantity = "EnergyQuantity";
+ private const string QuantityQuality = "QuantityQuality";
+ private const string IntervalEnergyObservation = "IntervalEnergyObservation";
+
+ protected override string RootPayloadElementName => "DK_MeteredDataTimeSeries";
+
+ protected override IReadOnlyCollection ParseTransactions(XDocument document, XNamespace ns, string senderNumber)
+ {
+ var transactionElements = document.Descendants(ns + SeriesElementName);
+ var result = new List();
+ foreach (var transactionElement in transactionElements)
+ {
+ var id = transactionElement.Element(ns + Identification)?.Value ?? string.Empty;
+ var resolution = transactionElement.Element(ns + ObservationTimeSeriesPeriod)?.Element(ns + ResolutionDuration)?.Value;
+ var startDateAndOrTimeDateTime = transactionElement.Element(ns + ObservationTimeSeriesPeriod)?.Element(ns + Start)?.Value ?? string.Empty;
+ var endDateAndOrTimeDateTime = transactionElement.Element(ns + ObservationTimeSeriesPeriod)?.Element(ns + End)?.Value;
+ var productNumber = transactionElement.Element(ns + IncludedProductCharacteristic)?.Element(ns + Identification)?.Value;
+ var productUnitType = transactionElement.Element(ns + IncludedProductCharacteristic)?.Element(ns + UnitType)?.Value;
+ var meteringPointType = transactionElement.Element(ns + DetailMeasurementMeteringPointCharacteristic)?.Element(ns + MeteringPointType)?.Value;
+ var meteringPointLocationId = transactionElement.Element(ns + MeteringPointDomainLocation)?.Element(ns + Identification)?.Value;
+
+ var energyObservations = transactionElement
+ .Descendants(ns + IntervalEnergyObservation)
+ .Select(e => new EnergyObservation(
+ e.Element(ns + Position)?.Value,
+ e.Element(ns + EnergyQuantity)?.Value,
+ e.Element(ns + QuantityQuality)?.Value))
+ .ToList();
+
+ result.Add(new MeteredDataForMeasurementPointSeries(
+ id,
+ resolution,
+ startDateAndOrTimeDateTime,
+ endDateAndOrTimeDateTime,
+ productNumber,
+ productUnitType,
+ meteringPointType,
+ meteringPointLocationId,
+ senderNumber,
+ energyObservations));
+ }
+
+ return result.AsReadOnly();
+ }
+
+ protected override IncomingMarketMessageParserResult CreateResult(MessageHeader header, IReadOnlyCollection transactions)
+ {
+ return new IncomingMarketMessageParserResult(new MeteredDataForMeasurementPointMessage(
+ header.MessageId,
+ header.MessageType,
+ header.CreatedAt,
+ header.SenderId,
+ header.ReceiverId,
+ header.SenderRole,
+ header.BusinessReason,
+ header.ReceiverRole,
+ header.BusinessType,
+ transactions));
+ }
+}
diff --git a/source/IncomingMessages.IntegrationTests/IncomingMessages.IntegrationTests.csproj b/source/IncomingMessages.IntegrationTests/IncomingMessages.IntegrationTests.csproj
index 649564f1bf..c115a18ab2 100644
--- a/source/IncomingMessages.IntegrationTests/IncomingMessages.IntegrationTests.csproj
+++ b/source/IncomingMessages.IntegrationTests/IncomingMessages.IntegrationTests.csproj
@@ -28,7 +28,7 @@ limitations under the License.
-
+
diff --git a/source/IncomingMessages.IntegrationTests/MessageParsers/GivenNewDocumentTypeTests.cs b/source/IncomingMessages.IntegrationTests/MessageParsers/GivenNewDocumentTypeTests.cs
index 4eade98878..48f250d1fe 100644
--- a/source/IncomingMessages.IntegrationTests/MessageParsers/GivenNewDocumentTypeTests.cs
+++ b/source/IncomingMessages.IntegrationTests/MessageParsers/GivenNewDocumentTypeTests.cs
@@ -84,11 +84,11 @@ public async Task When_ParsingMessageOfDocumentTypeAndFormat_Then_ExpectedMessag
// Assert
if (_unsupportedCombinationsOfIncomingDocumentTypeAndDocumentFormat.Contains((incomingDocumentType, documentFormat)))
{
- await act.Should().ThrowAsync("because this combination is not supported");
+ await act.Should().ThrowAsync("because this combination is not supported");
}
else
{
- await act.Should().NotThrowAsync("because this combination is valid, but no parser was found");
+ await act.Should().NotThrowAsync("because this combination is valid, but no parser was found");
}
}
}
diff --git a/source/IncomingMessages.Interfaces/IncomingMessages.Interfaces.csproj b/source/IncomingMessages.Interfaces/IncomingMessages.Interfaces.csproj
index 792ee9d670..88f8d27a6b 100644
--- a/source/IncomingMessages.Interfaces/IncomingMessages.Interfaces.csproj
+++ b/source/IncomingMessages.Interfaces/IncomingMessages.Interfaces.csproj
@@ -6,7 +6,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/IntegrationEvents.Application/IntegrationEvents.Application.csproj b/source/IntegrationEvents.Application/IntegrationEvents.Application.csproj
index 9ff8aebb37..cd92422459 100644
--- a/source/IntegrationEvents.Application/IntegrationEvents.Application.csproj
+++ b/source/IntegrationEvents.Application/IntegrationEvents.Application.csproj
@@ -18,7 +18,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/IntegrationEvents.Infrastructure/IntegrationEvents.Infrastructure.csproj b/source/IntegrationEvents.Infrastructure/IntegrationEvents.Infrastructure.csproj
index d5e0dac893..e02ee80bc2 100644
--- a/source/IntegrationEvents.Infrastructure/IntegrationEvents.Infrastructure.csproj
+++ b/source/IntegrationEvents.Infrastructure/IntegrationEvents.Infrastructure.csproj
@@ -13,12 +13,12 @@
-
+
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/IntegrationEvents.IntegrationTests/IntegrationEvents.IntegrationTests.csproj b/source/IntegrationEvents.IntegrationTests/IntegrationEvents.IntegrationTests.csproj
index d808312b52..5ef75177ab 100644
--- a/source/IntegrationEvents.IntegrationTests/IntegrationEvents.IntegrationTests.csproj
+++ b/source/IntegrationEvents.IntegrationTests/IntegrationEvents.IntegrationTests.csproj
@@ -9,7 +9,7 @@
-
+
@@ -21,7 +21,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
diff --git a/source/IntegrationTests/IntegrationTests.csproj b/source/IntegrationTests/IntegrationTests.csproj
index 57ad4c7d94..30ab46c50c 100644
--- a/source/IntegrationTests/IntegrationTests.csproj
+++ b/source/IntegrationTests/IntegrationTests.csproj
@@ -24,7 +24,7 @@ limitations under the License.
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -32,7 +32,7 @@ limitations under the License.
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/MasterData.Application/MasterData.Application.csproj b/source/MasterData.Application/MasterData.Application.csproj
index da2ffd7f2c..4894870f99 100644
--- a/source/MasterData.Application/MasterData.Application.csproj
+++ b/source/MasterData.Application/MasterData.Application.csproj
@@ -5,7 +5,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/MasterData.Domain/MasterData.Domain.csproj b/source/MasterData.Domain/MasterData.Domain.csproj
index dd6ad4878e..16c894fed8 100644
--- a/source/MasterData.Domain/MasterData.Domain.csproj
+++ b/source/MasterData.Domain/MasterData.Domain.csproj
@@ -4,7 +4,7 @@
Energinet.DataHub.EDI.MasterData.Domain
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/MasterData.Infrastructure/MasterData.Infrastructure.csproj b/source/MasterData.Infrastructure/MasterData.Infrastructure.csproj
index c46b87689b..223b216d88 100644
--- a/source/MasterData.Infrastructure/MasterData.Infrastructure.csproj
+++ b/source/MasterData.Infrastructure/MasterData.Infrastructure.csproj
@@ -15,7 +15,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/MasterData.IntegrationTests/MasterData.IntegrationTests.csproj b/source/MasterData.IntegrationTests/MasterData.IntegrationTests.csproj
index 170d420741..8a9a7c1369 100644
--- a/source/MasterData.IntegrationTests/MasterData.IntegrationTests.csproj
+++ b/source/MasterData.IntegrationTests/MasterData.IntegrationTests.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/source/MasterData.Interfaces/MasterData.Interfaces.csproj b/source/MasterData.Interfaces/MasterData.Interfaces.csproj
index b9076e2257..748901237a 100644
--- a/source/MasterData.Interfaces/MasterData.Interfaces.csproj
+++ b/source/MasterData.Interfaces/MasterData.Interfaces.csproj
@@ -4,7 +4,7 @@
Energinet.DataHub.EDI.MasterData.Interfaces
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/Outbox.Infrastructure/Outbox.Infrastructure.csproj b/source/Outbox.Infrastructure/Outbox.Infrastructure.csproj
index f1bb380831..b80660de46 100644
--- a/source/Outbox.Infrastructure/Outbox.Infrastructure.csproj
+++ b/source/Outbox.Infrastructure/Outbox.Infrastructure.csproj
@@ -7,7 +7,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/OutgoingMessages.Application/OutgoingMessages.Application.csproj b/source/OutgoingMessages.Application/OutgoingMessages.Application.csproj
index 460383e390..d7ec12b623 100644
--- a/source/OutgoingMessages.Application/OutgoingMessages.Application.csproj
+++ b/source/OutgoingMessages.Application/OutgoingMessages.Application.csproj
@@ -8,7 +8,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/OutgoingMessages.Domain/OutgoingMessages.Domain.csproj b/source/OutgoingMessages.Domain/OutgoingMessages.Domain.csproj
index 8ded45efd3..21f6b7c576 100644
--- a/source/OutgoingMessages.Domain/OutgoingMessages.Domain.csproj
+++ b/source/OutgoingMessages.Domain/OutgoingMessages.Domain.csproj
@@ -11,7 +11,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/OutgoingMessages.Infrastructure/OutgoingMessages.Infrastructure.csproj b/source/OutgoingMessages.Infrastructure/OutgoingMessages.Infrastructure.csproj
index bcd33d3b5f..47aa234f2f 100644
--- a/source/OutgoingMessages.Infrastructure/OutgoingMessages.Infrastructure.csproj
+++ b/source/OutgoingMessages.Infrastructure/OutgoingMessages.Infrastructure.csproj
@@ -10,7 +10,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/OutgoingMessages.IntegrationTests/OutgoingMessages.IntegrationTests.csproj b/source/OutgoingMessages.IntegrationTests/OutgoingMessages.IntegrationTests.csproj
index be6dd187ea..4aeb0f5cb6 100644
--- a/source/OutgoingMessages.IntegrationTests/OutgoingMessages.IntegrationTests.csproj
+++ b/source/OutgoingMessages.IntegrationTests/OutgoingMessages.IntegrationTests.csproj
@@ -13,7 +13,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/source/OutgoingMessages.Interfaces/OutgoingMessages.Interfaces.csproj b/source/OutgoingMessages.Interfaces/OutgoingMessages.Interfaces.csproj
index f96e2370e1..1d5d687e11 100644
--- a/source/OutgoingMessages.Interfaces/OutgoingMessages.Interfaces.csproj
+++ b/source/OutgoingMessages.Interfaces/OutgoingMessages.Interfaces.csproj
@@ -6,7 +6,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/Process.Application/Process.Application.csproj b/source/Process.Application/Process.Application.csproj
index 48d54dd076..23b9644ef7 100644
--- a/source/Process.Application/Process.Application.csproj
+++ b/source/Process.Application/Process.Application.csproj
@@ -10,7 +10,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/Process.Domain/Process.Domain.csproj b/source/Process.Domain/Process.Domain.csproj
index b2e37ff5f4..fa51d88c3b 100644
--- a/source/Process.Domain/Process.Domain.csproj
+++ b/source/Process.Domain/Process.Domain.csproj
@@ -13,7 +13,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/Process.Infrastructure/Process.Infrastructure.csproj b/source/Process.Infrastructure/Process.Infrastructure.csproj
index d67b0d6cdd..4328f016b6 100644
--- a/source/Process.Infrastructure/Process.Infrastructure.csproj
+++ b/source/Process.Infrastructure/Process.Infrastructure.csproj
@@ -8,16 +8,16 @@
-
+
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/source/Process.Interfaces/Process.Interfaces.csproj b/source/Process.Interfaces/Process.Interfaces.csproj
index 3278ac04b3..af6a5536f4 100644
--- a/source/Process.Interfaces/Process.Interfaces.csproj
+++ b/source/Process.Interfaces/Process.Interfaces.csproj
@@ -6,7 +6,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/ProcessManager.Core.Tests/Integration/Infrastructure/Orchestration/OrchestrationInstanceRepositoryTests.cs b/source/ProcessManager.Core.Tests/Integration/Infrastructure/Orchestration/OrchestrationInstanceRepositoryTests.cs
index 1af38a6e38..5e6c215460 100644
--- a/source/ProcessManager.Core.Tests/Integration/Infrastructure/Orchestration/OrchestrationInstanceRepositoryTests.cs
+++ b/source/ProcessManager.Core.Tests/Integration/Infrastructure/Orchestration/OrchestrationInstanceRepositoryTests.cs
@@ -32,14 +32,12 @@ public class OrchestrationInstanceRepositoryTests : IAsyncLifetime
private readonly ProcessManagerCoreFixture _fixture;
private readonly ProcessManagerContext _dbContext;
private readonly OrchestrationInstanceRepository _sut;
- private readonly UnitOfWork _unitOfWork;
public OrchestrationInstanceRepositoryTests(ProcessManagerCoreFixture fixture)
{
_fixture = fixture;
_dbContext = _fixture.DatabaseManager.CreateDbContext();
_sut = new OrchestrationInstanceRepository(_dbContext);
- _unitOfWork = new UnitOfWork(_dbContext);
}
public Task InitializeAsync()
@@ -98,7 +96,7 @@ public async Task GivenOrchestrationDescriptionNotInDatabase_WhenAddOrchestratio
// Act
await _sut.AddAsync(newOrchestrationInstance);
- var act = _unitOfWork.CommitAsync;
+ var act = () => _sut.UnitOfWork.CommitAsync();
// Assert
await act.Should()
@@ -118,7 +116,7 @@ public async Task GivenOrchestrationDescriptionInDatabase_WhenAddOrchestrationIn
// Act
await _sut.AddAsync(newOrchestrationInstance);
- await _unitOfWork.CommitAsync();
+ await _sut.UnitOfWork.CommitAsync();
// Assert
var actual = await _sut.GetAsync(newOrchestrationInstance.Id);
@@ -146,7 +144,7 @@ public async Task GivenScheduledOrchestrationInstancesInDatabase_WhenGetSchedule
runAt: SystemClock.Instance.GetCurrentInstant().PlusDays(5));
await _sut.AddAsync(scheduledIntoTheFarFuture);
- await _unitOfWork.CommitAsync();
+ await _sut.UnitOfWork.CommitAsync();
// Act
var actual = await _sut.FindAsync(
@@ -177,7 +175,7 @@ public async Task GivenOrchestrationInstancesInDatabase_WhenSearchByName_ThenExp
var basedOn02 = CreateOrchestrationInstance(existingOrchestrationDescription02);
await _sut.AddAsync(basedOn02);
- await _unitOfWork.CommitAsync();
+ await _sut.UnitOfWork.CommitAsync();
// Act
var actual = await _sut.SearchAsync(existingOrchestrationDescription01.Name);
@@ -204,7 +202,7 @@ public async Task GivenOrchestrationInstancesInDatabase_WhenSearchByNameAndVersi
var basedOnV2 = CreateOrchestrationInstance(existingOrchestrationDescriptionV2);
await _sut.AddAsync(basedOnV2);
- await _unitOfWork.CommitAsync();
+ await _sut.UnitOfWork.CommitAsync();
// Act
var actual = await _sut.SearchAsync(existingOrchestrationDescriptionV1.Name, existingOrchestrationDescriptionV1.Version);
@@ -241,7 +239,7 @@ public async Task GivenOrchestrationInstancesInDatabase_WhenSearchByNameAndLifec
isRunningV2.Lifecycle.TransitionToRunning(SystemClock.Instance);
await _sut.AddAsync(isRunningV2);
- await _unitOfWork.CommitAsync();
+ await _sut.UnitOfWork.CommitAsync();
// Act
var actual = await _sut.SearchAsync(existingOrchestrationDescriptionV1.Name, lifecycleState: OrchestrationInstanceLifecycleStates.Running);
@@ -280,7 +278,7 @@ public async Task GivenOrchestrationInstancesInDatabase_WhenSearchByNameAndTermi
isTerminatedAsFailedV2.Lifecycle.TransitionToTerminated(SystemClock.Instance, OrchestrationInstanceTerminationStates.Failed);
await _sut.AddAsync(isTerminatedAsFailedV2);
- await _unitOfWork.CommitAsync();
+ await _sut.UnitOfWork.CommitAsync();
// Act
var actual = await _sut.SearchAsync(
@@ -319,7 +317,7 @@ public async Task GivenOrchestrationInstancesInDatabase_WhenSearchByNameAndStart
isRunning02.Lifecycle.TransitionToRunning(SystemClock.Instance);
await _sut.AddAsync(isRunning02);
- await _unitOfWork.CommitAsync();
+ await _sut.UnitOfWork.CommitAsync();
// Act
var actual = await _sut.SearchAsync(
@@ -364,7 +362,7 @@ public async Task GivenOrchestrationInstancesInDatabase_WhenSearchByNameAndTermi
isTerminated02.Lifecycle.TransitionToTerminated(SystemClock.Instance, OrchestrationInstanceTerminationStates.Succeeded);
await _sut.AddAsync(isTerminated02);
- await _unitOfWork.CommitAsync();
+ await _sut.UnitOfWork.CommitAsync();
// Act
var actual = await _sut.SearchAsync(
diff --git a/source/ProcessManager.Core.Tests/ProcessManager.Core.Tests.csproj b/source/ProcessManager.Core.Tests/ProcessManager.Core.Tests.csproj
index 7bb7170cc9..7eb59953a1 100644
--- a/source/ProcessManager.Core.Tests/ProcessManager.Core.Tests.csproj
+++ b/source/ProcessManager.Core.Tests/ProcessManager.Core.Tests.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/source/ProcessManager.Core/Application/Orchestration/ICancelScheduledOrchestrationInstanceCommand.cs b/source/ProcessManager.Core/Application/Orchestration/ICancelScheduledOrchestrationInstanceCommand.cs
new file mode 100644
index 0000000000..43a958e9eb
--- /dev/null
+++ b/source/ProcessManager.Core/Application/Orchestration/ICancelScheduledOrchestrationInstanceCommand.cs
@@ -0,0 +1,25 @@
+// 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 Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
+
+namespace Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
+
+public interface ICancelScheduledOrchestrationInstanceCommand
+{
+ ///
+ /// Cancel a scheduled orchestration instance.
+ ///
+ Task CancelScheduledOrchestrationInstanceAsync(OrchestrationInstanceId id);
+}
diff --git a/source/ProcessManager.Core/Application/Orchestration/IOrchestrationInstanceExecutor.cs b/source/ProcessManager.Core/Application/Orchestration/IOrchestrationInstanceExecutor.cs
new file mode 100644
index 0000000000..f47712f925
--- /dev/null
+++ b/source/ProcessManager.Core/Application/Orchestration/IOrchestrationInstanceExecutor.cs
@@ -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 Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationDescription;
+using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
+
+namespace Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
+
+///
+/// Abstracts the execution of orchestration instances from technology specific implementations.
+///
+internal interface IOrchestrationInstanceExecutor
+{
+ ///
+ /// Start a new orchestration instance.
+ ///
+ Task StartNewOrchestrationInstanceAsync(OrchestrationDescription orchestrationDescription, OrchestrationInstance orchestrationInstance);
+}
diff --git a/source/ProcessManager.Core/Application/IOrchestrationInstanceProgressRepository.cs b/source/ProcessManager.Core/Application/Orchestration/IOrchestrationInstanceProgressRepository.cs
similarity index 77%
rename from source/ProcessManager.Core/Application/IOrchestrationInstanceProgressRepository.cs
rename to source/ProcessManager.Core/Application/Orchestration/IOrchestrationInstanceProgressRepository.cs
index 82bbb5a32b..f843f2f4ec 100644
--- a/source/ProcessManager.Core/Application/IOrchestrationInstanceProgressRepository.cs
+++ b/source/ProcessManager.Core/Application/Orchestration/IOrchestrationInstanceProgressRepository.cs
@@ -14,17 +14,22 @@
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
-namespace Energinet.DataHub.ProcessManagement.Core.Application;
+namespace Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
///
/// Use this from Durable Functions activities to get the orchestration instance and then
-/// update its progress, before commiting changes back by using .
+/// update its progress, before commiting changes back by using .
///
public interface IOrchestrationInstanceProgressRepository
{
+ ///
+ /// Use to save changes.
+ ///
+ public IUnitOfWork UnitOfWork { get; }
+
///
/// Get existing orchestration instance.
- /// To commit changes use .
+ /// To commit changes use .
///
Task GetAsync(OrchestrationInstanceId id);
}
diff --git a/source/ProcessManager.Core/Application/IOrchestrationInstanceRepository.cs b/source/ProcessManager.Core/Application/Orchestration/IOrchestrationInstanceQueries.cs
similarity index 79%
rename from source/ProcessManager.Core/Application/IOrchestrationInstanceRepository.cs
rename to source/ProcessManager.Core/Application/Orchestration/IOrchestrationInstanceQueries.cs
index 53c24150c8..f795ea1869 100644
--- a/source/ProcessManager.Core/Application/IOrchestrationInstanceRepository.cs
+++ b/source/ProcessManager.Core/Application/Orchestration/IOrchestrationInstanceQueries.cs
@@ -15,15 +15,14 @@
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using NodaTime;
-namespace Energinet.DataHub.ProcessManagement.Core.Application;
+namespace Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
-public interface IOrchestrationInstanceRepository : IOrchestrationInstanceProgressRepository
+public interface IOrchestrationInstanceQueries
{
///
- /// Add the orchestration instance.
- /// To commit changes use .
+ /// Get existing orchestration instance.
///
- Task AddAsync(OrchestrationInstance orchestrationInstance);
+ Task GetAsync(OrchestrationInstanceId id);
///
/// Get all orchestration instances filtered by their related orchestration definition name and version,
diff --git a/source/ProcessManager.Core/Application/Orchestration/IOrchestrationInstanceRepository.cs b/source/ProcessManager.Core/Application/Orchestration/IOrchestrationInstanceRepository.cs
new file mode 100644
index 0000000000..b9358e1b53
--- /dev/null
+++ b/source/ProcessManager.Core/Application/Orchestration/IOrchestrationInstanceRepository.cs
@@ -0,0 +1,50 @@
+// 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 Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
+using NodaTime;
+
+namespace Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
+
+internal interface IOrchestrationInstanceRepository
+{
+ ///
+ /// Use to save changes.
+ ///
+ public IUnitOfWork UnitOfWork { get; }
+
+ ///
+ /// Add the orchestration instance.
+ /// To commit changes use .
+ ///
+ Task AddAsync(OrchestrationInstance orchestrationInstance);
+
+ ///
+ /// Get existing orchestration instance.
+ /// To commit changes use .
+ ///
+ Task GetAsync(OrchestrationInstanceId id);
+
+ ///
+ /// Get all orchestration instances filtered by their related orchestration definition name and version,
+ /// and their lifecycle / termination states.
+ ///
+ Task> SearchAsync(
+ string name,
+ int? version,
+ OrchestrationInstanceLifecycleStates? lifecycleState,
+ OrchestrationInstanceTerminationStates? terminationState,
+ Instant? startedAtOrLater,
+ Instant? terminatedAtOrEarlier);
+}
diff --git a/source/ProcessManager.Core/Application/IOrchestrationRegisterQueries.cs b/source/ProcessManager.Core/Application/Orchestration/IOrchestrationRegisterQueries.cs
similarity index 88%
rename from source/ProcessManager.Core/Application/IOrchestrationRegisterQueries.cs
rename to source/ProcessManager.Core/Application/Orchestration/IOrchestrationRegisterQueries.cs
index ad277f65a4..bad6cf7c80 100644
--- a/source/ProcessManager.Core/Application/IOrchestrationRegisterQueries.cs
+++ b/source/ProcessManager.Core/Application/Orchestration/IOrchestrationRegisterQueries.cs
@@ -14,12 +14,12 @@
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationDescription;
-namespace Energinet.DataHub.ProcessManagement.Core.Application;
+namespace Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
///
/// Readonly access to the orchestration register.
///
-public interface IOrchestrationRegisterQueries
+internal interface IOrchestrationRegisterQueries
{
Task GetAsync(OrchestrationDescriptionId id);
diff --git a/source/ProcessManager.Core/Application/IOrchestrationInstanceManager.cs b/source/ProcessManager.Core/Application/Orchestration/IStartOrchestrationInstanceCommands.cs
similarity index 83%
rename from source/ProcessManager.Core/Application/IOrchestrationInstanceManager.cs
rename to source/ProcessManager.Core/Application/Orchestration/IStartOrchestrationInstanceCommands.cs
index 5ed179cd92..e3d842ea86 100644
--- a/source/ProcessManager.Core/Application/IOrchestrationInstanceManager.cs
+++ b/source/ProcessManager.Core/Application/Orchestration/IStartOrchestrationInstanceCommands.cs
@@ -15,9 +15,9 @@
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using NodaTime;
-namespace Energinet.DataHub.ProcessManagement.Core.Application;
+namespace Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
-public interface IOrchestrationInstanceManager
+public interface IStartOrchestrationInstanceCommands
{
///
/// Start a new instance of an orchestration.
@@ -39,9 +39,4 @@ Task ScheduleNewOrchestrationInstanceAsync(
Instant runAt,
IReadOnlyCollection skipStepsBySequence)
where TParameter : class;
-
- ///
- /// Cancel a scheduled orchestration instance.
- ///
- Task CancelScheduledOrchestrationInstanceAsync(OrchestrationInstanceId id);
}
diff --git a/source/ProcessManager.Core/Application/IUnitOfWork.cs b/source/ProcessManager.Core/Application/Orchestration/IUnitOfWork.cs
similarity index 81%
rename from source/ProcessManager.Core/Application/IUnitOfWork.cs
rename to source/ProcessManager.Core/Application/Orchestration/IUnitOfWork.cs
index 1a51ba1ad7..9c644a7356 100644
--- a/source/ProcessManager.Core/Application/IUnitOfWork.cs
+++ b/source/ProcessManager.Core/Application/Orchestration/IUnitOfWork.cs
@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-namespace Energinet.DataHub.ProcessManagement.Core.Application;
+namespace Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
public interface IUnitOfWork
{
- Task CommitAsync();
+ Task CommitAsync(CancellationToken cancellationToken = default);
}
diff --git a/source/ProcessManager.Core/Infrastructure/Orchestration/OrchestrationInstanceManager.cs b/source/ProcessManager.Core/Application/Orchestration/OrchestrationInstanceManager.cs
similarity index 71%
rename from source/ProcessManager.Core/Infrastructure/Orchestration/OrchestrationInstanceManager.cs
rename to source/ProcessManager.Core/Application/Orchestration/OrchestrationInstanceManager.cs
index cbf994fcd8..ea974f2a52 100644
--- a/source/ProcessManager.Core/Infrastructure/Orchestration/OrchestrationInstanceManager.cs
+++ b/source/ProcessManager.Core/Application/Orchestration/OrchestrationInstanceManager.cs
@@ -12,48 +12,30 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Scheduling;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationDescription;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
-using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using NodaTime;
-namespace Energinet.DataHub.ProcessManagement.Core.Infrastructure.Orchestration;
+namespace Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
///
-/// An encapsulation of that allows us to
-/// provide a "framework" for managing Durable Functions orchestration instances using custom domain types.
+/// An manager that allows us to provide a framework for managing orchestration instances
+/// using custom domain types.
///
-public class OrchestrationInstanceManager : IOrchestrationInstanceManager, IOrchestrationInstanceScheduleManager
+internal class OrchestrationInstanceManager(
+ IClock clock,
+ IOrchestrationInstanceExecutor executor,
+ IOrchestrationRegisterQueries orchestrationRegister,
+ IOrchestrationInstanceRepository repository) :
+ IStartOrchestrationInstanceCommands,
+ IStartScheduledOrchestrationInstanceCommand,
+ ICancelScheduledOrchestrationInstanceCommand
{
- private readonly IClock _clock;
- private readonly IDurableClient _durableClient;
- private readonly IOrchestrationRegisterQueries _orchestrationRegister;
- private readonly IOrchestrationInstanceRepository _orchestrationInstanceRepository;
- private readonly IUnitOfWork _unitOfWork;
-
- ///
- /// Construct manager.
- ///
- ///
- /// Must be a Durable Task Client that is connected to
- /// the same Task Hub as the Durable Functions host containing orchestrations.
- ///
- ///
- ///
- public OrchestrationInstanceManager(
- IClock clock,
- IDurableClient durableClient,
- IOrchestrationRegisterQueries orchestrationRegister,
- IOrchestrationInstanceRepository orchestrationInstanceRepository,
- IUnitOfWork unitOfWork)
- {
- _clock = clock;
- _durableClient = durableClient;
- _orchestrationRegister = orchestrationRegister;
- _orchestrationInstanceRepository = orchestrationInstanceRepository;
- _unitOfWork = unitOfWork;
- }
+ private readonly IClock _clock = clock;
+ private readonly IOrchestrationInstanceExecutor _executor = executor;
+ private readonly IOrchestrationRegisterQueries _orchestrationRegister = orchestrationRegister;
+ private readonly IOrchestrationInstanceRepository _repository = repository;
///
public async Task StartNewOrchestrationInstanceAsync(
@@ -92,7 +74,7 @@ public async Task ScheduleNewOrchestrationInstanceAsync
///
public async Task StartScheduledOrchestrationInstanceAsync(OrchestrationInstanceId id)
{
- var orchestrationInstance = await _orchestrationInstanceRepository.GetAsync(id).ConfigureAwait(false);
+ var orchestrationInstance = await _repository.GetAsync(id).ConfigureAwait(false);
if (!orchestrationInstance.Lifecycle.IsPendingForScheduledStart())
throw new InvalidOperationException("Orchestration instance cannot be started.");
@@ -106,13 +88,13 @@ public async Task StartScheduledOrchestrationInstanceAsync(OrchestrationInstance
///
public async Task CancelScheduledOrchestrationInstanceAsync(OrchestrationInstanceId id)
{
- var orchestrationInstance = await _orchestrationInstanceRepository.GetAsync(id).ConfigureAwait(false);
+ var orchestrationInstance = await _repository.GetAsync(id).ConfigureAwait(false);
if (!orchestrationInstance.Lifecycle.IsPendingForScheduledStart())
throw new InvalidOperationException("Orchestration instance cannot be canceled.");
// Transition lifecycle
orchestrationInstance.Lifecycle.TransitionToTerminated(_clock, OrchestrationInstanceTerminationStates.UserCanceled);
- await _unitOfWork.CommitAsync().ConfigureAwait(false);
+ await _repository.UnitOfWork.CommitAsync().ConfigureAwait(false);
}
///
@@ -160,8 +142,8 @@ private async Task CreateOrchestrationInstanceAsync
/// Read/write access to the orchestration register.
///
-public interface IOrchestrationRegister
+internal interface IOrchestrationRegister
{
Task> GetAllByHostNameAsync(string hostName);
diff --git a/source/ProcessManager.Core/Application/OrchestrationRegisterExtensions.cs b/source/ProcessManager.Core/Application/Registration/OrchestrationRegisterExtensions.cs
similarity index 95%
rename from source/ProcessManager.Core/Application/OrchestrationRegisterExtensions.cs
rename to source/ProcessManager.Core/Application/Registration/OrchestrationRegisterExtensions.cs
index e5aac16bd0..5f138c9958 100644
--- a/source/ProcessManager.Core/Application/OrchestrationRegisterExtensions.cs
+++ b/source/ProcessManager.Core/Application/Registration/OrchestrationRegisterExtensions.cs
@@ -14,9 +14,9 @@
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationDescription;
-namespace Energinet.DataHub.ProcessManagement.Core.Application;
+namespace Energinet.DataHub.ProcessManagement.Core.Application.Registration;
-public static class OrchestrationRegisterExtensions
+internal static class OrchestrationRegisterExtensions
{
///
/// Synchronize the orchestration register with the Durable Functions orchestrations for an application host.
@@ -58,9 +58,7 @@ public static async Task SynchronizeAsync(
&& x.Version == hostDescription.Version);
if (registerDescription == null || registerDescription.IsEnabled == false)
- {
await register.RegisterAsync(hostDescription, hostName).ConfigureAwait(false);
- }
}
}
}
diff --git a/source/ProcessManager.Core/Application/IQueryScheduledOrchestrationInstancesByInstant.cs b/source/ProcessManager.Core/Application/Scheduling/IScheduledOrchestrationInstancesByInstantQuery.cs
similarity index 87%
rename from source/ProcessManager.Core/Application/IQueryScheduledOrchestrationInstancesByInstant.cs
rename to source/ProcessManager.Core/Application/Scheduling/IScheduledOrchestrationInstancesByInstantQuery.cs
index ed3d51f24b..b8962637fd 100644
--- a/source/ProcessManager.Core/Application/IQueryScheduledOrchestrationInstancesByInstant.cs
+++ b/source/ProcessManager.Core/Application/Scheduling/IScheduledOrchestrationInstancesByInstantQuery.cs
@@ -15,9 +15,9 @@
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using NodaTime;
-namespace Energinet.DataHub.ProcessManagement.Core.Application;
+namespace Energinet.DataHub.ProcessManagement.Core.Application.Scheduling;
-public interface IQueryScheduledOrchestrationInstancesByInstant
+public interface IScheduledOrchestrationInstancesByInstantQuery
{
///
/// Find scheduled orchestration instances that should be started when comparing to given .
diff --git a/source/ProcessManager.Core/Application/IOrchestrationInstanceScheduleManager.cs b/source/ProcessManager.Core/Application/Scheduling/IStartScheduledOrchestrationInstanceCommand.cs
similarity index 86%
rename from source/ProcessManager.Core/Application/IOrchestrationInstanceScheduleManager.cs
rename to source/ProcessManager.Core/Application/Scheduling/IStartScheduledOrchestrationInstanceCommand.cs
index c1be747be2..6ec08dbab6 100644
--- a/source/ProcessManager.Core/Application/IOrchestrationInstanceScheduleManager.cs
+++ b/source/ProcessManager.Core/Application/Scheduling/IStartScheduledOrchestrationInstanceCommand.cs
@@ -14,9 +14,9 @@
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
-namespace Energinet.DataHub.ProcessManagement.Core.Application;
+namespace Energinet.DataHub.ProcessManagement.Core.Application.Scheduling;
-public interface IOrchestrationInstanceScheduleManager
+public interface IStartScheduledOrchestrationInstanceCommand
{
///
/// Start a scheduled orchestration instance.
diff --git a/source/ProcessManager.Core/Infrastructure/Database/OrchestrationDescriptionEntityConfiguration.cs b/source/ProcessManager.Core/Infrastructure/Database/OrchestrationDescriptionEntityConfiguration.cs
index 61bf4683a2..1c47413acf 100644
--- a/source/ProcessManager.Core/Infrastructure/Database/OrchestrationDescriptionEntityConfiguration.cs
+++ b/source/ProcessManager.Core/Infrastructure/Database/OrchestrationDescriptionEntityConfiguration.cs
@@ -18,7 +18,7 @@
namespace Energinet.DataHub.ProcessManagement.Core.Infrastructure.Database;
-public class OrchestrationDescriptionEntityConfiguration : IEntityTypeConfiguration
+internal class OrchestrationDescriptionEntityConfiguration : IEntityTypeConfiguration
{
public void Configure(EntityTypeBuilder builder)
{
diff --git a/source/ProcessManager.Core/Infrastructure/Database/OrchestrationInstanceEntityConfiguration.cs b/source/ProcessManager.Core/Infrastructure/Database/OrchestrationInstanceEntityConfiguration.cs
index 4d7b4e8dbd..f50b1562d0 100644
--- a/source/ProcessManager.Core/Infrastructure/Database/OrchestrationInstanceEntityConfiguration.cs
+++ b/source/ProcessManager.Core/Infrastructure/Database/OrchestrationInstanceEntityConfiguration.cs
@@ -19,7 +19,7 @@
namespace Energinet.DataHub.ProcessManagement.Core.Infrastructure.Database;
-public class OrchestrationInstanceEntityConfiguration : IEntityTypeConfiguration
+internal class OrchestrationInstanceEntityConfiguration : IEntityTypeConfiguration
{
public void Configure(EntityTypeBuilder builder)
{
diff --git a/source/ProcessManager.Core/Infrastructure/Database/ProcessManagerContext.cs b/source/ProcessManager.Core/Infrastructure/Database/ProcessManagerContext.cs
index 7f9bc9e783..7f362fa17c 100644
--- a/source/ProcessManager.Core/Infrastructure/Database/ProcessManagerContext.cs
+++ b/source/ProcessManager.Core/Infrastructure/Database/ProcessManagerContext.cs
@@ -12,23 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationDescription;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using Microsoft.EntityFrameworkCore;
namespace Energinet.DataHub.ProcessManagement.Core.Infrastructure.Database;
-public class ProcessManagerContext : DbContext
+public class ProcessManagerContext(
+ DbContextOptions options) :
+ DbContext(options), IUnitOfWork
{
- public ProcessManagerContext(DbContextOptions options)
- : base(options)
- {
- }
-
public DbSet OrchestrationDescriptions { get; private set; }
public DbSet OrchestrationInstances { get; private set; }
+ public Task CommitAsync(CancellationToken cancellationToken = default)
+ {
+ return SaveChangesAsync(cancellationToken);
+ }
+
public override int SaveChanges()
{
throw new NotSupportedException("Use the async version instead");
diff --git a/source/ProcessManager.Core/Infrastructure/Extensions/DependencyInjection/ProcessManagerExtensions.cs b/source/ProcessManager.Core/Infrastructure/Extensions/DependencyInjection/ProcessManagerExtensions.cs
index 5487a0d205..b72236fde2 100644
--- a/source/ProcessManager.Core/Infrastructure/Extensions/DependencyInjection/ProcessManagerExtensions.cs
+++ b/source/ProcessManager.Core/Infrastructure/Extensions/DependencyInjection/ProcessManagerExtensions.cs
@@ -12,11 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
+using Energinet.DataHub.ProcessManagement.Core.Application.Registration;
+using Energinet.DataHub.ProcessManagement.Core.Application.Scheduling;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationDescription;
using Energinet.DataHub.ProcessManagement.Core.Infrastructure.Database;
using Energinet.DataHub.ProcessManagement.Core.Infrastructure.Extensions.Options;
using Energinet.DataHub.ProcessManagement.Core.Infrastructure.Orchestration;
+using Energinet.DataHub.ProcessManagement.Core.Infrastructure.Registration;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.DurableTask.ContextImplementations;
using Microsoft.Azure.WebJobs.Extensions.DurableTask.Options;
@@ -66,13 +69,18 @@ public static IServiceCollection AddProcessManagerCore(this IServiceCollection s
});
// ProcessManager components using interfaces to restrict access to functionality
- // => Scheduler
- services.TryAddScoped();
- services.TryAddScoped();
- // => Manager
+ // => Scheduling
+ services.TryAddScoped();
+ services.TryAddScoped();
+ // => Cancellation (manager)
+ services.TryAddScoped();
+ // => Start instance (manager)
+ services.TryAddScoped();
services.TryAddScoped();
services.TryAddScoped();
- services.TryAddScoped();
+ services.TryAddScoped();
+ // => Public queries
+ services.TryAddScoped();
return services;
}
@@ -122,12 +130,13 @@ public static IServiceCollection AddProcessManagerForOrchestrations(
// => Orchestration Descriptions registration during startup
services.TryAddTransient>(sp => enabledDescriptionsFactory());
services.TryAddTransient();
- // => Orchestration instances progress
- services.TryAddScoped();
- // => Manager
+ // => Start instance (manager)
+ services.TryAddScoped();
services.TryAddScoped();
services.TryAddScoped();
- services.TryAddScoped();
+ services.TryAddScoped();
+ // => Public progress repository
+ services.TryAddScoped();
return services;
}
@@ -161,8 +170,9 @@ private static IServiceCollection AddProcessManagerDatabase(this IServiceCollect
providerOptionsBuilder.UseNodaTime();
providerOptionsBuilder.EnableRetryOnFailure();
});
- })
- .AddScoped()
+ });
+
+ services
.AddHealthChecks()
.AddDbContextCheck(name: "ProcesManagerDatabase");
diff --git a/source/ProcessManager.Core/Infrastructure/Extensions/Startup/HostExtensions.cs b/source/ProcessManager.Core/Infrastructure/Extensions/Startup/HostExtensions.cs
index 69aa92a553..d6523f9a47 100644
--- a/source/ProcessManager.Core/Infrastructure/Extensions/Startup/HostExtensions.cs
+++ b/source/ProcessManager.Core/Infrastructure/Extensions/Startup/HostExtensions.cs
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Registration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationDescription;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@@ -29,7 +29,7 @@ public static class HostExtensions
///
/// Register and deregister orchestrations during application startup.
///
- public static async Task SynchronizeWithOrchestrationRegisterAsync(this IHost host)
+ public static async Task SynchronizeWithOrchestrationRegisterAsync(this IHost host, string hostName)
{
var loggerFactory = host.Services.GetRequiredService();
var logger = loggerFactory.CreateLogger(nameof(SynchronizeWithOrchestrationRegisterAsync));
@@ -40,7 +40,7 @@ public static async Task SynchronizeWithOrchestrationRegisterAsync(this IHost ho
var register = host.Services.GetRequiredService();
await register
.SynchronizeAsync(
- hostName: "ProcessManager.Orchestrations",
+ hostName: hostName,
enabledDescriptions)
.ConfigureAwait(false);
}
diff --git a/source/ProcessManager.Core/Infrastructure/Orchestration/DurableOrchestrationInstanceExecutor.cs b/source/ProcessManager.Core/Infrastructure/Orchestration/DurableOrchestrationInstanceExecutor.cs
new file mode 100644
index 0000000000..cb32ba9aa8
--- /dev/null
+++ b/source/ProcessManager.Core/Infrastructure/Orchestration/DurableOrchestrationInstanceExecutor.cs
@@ -0,0 +1,44 @@
+// 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 Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
+using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationDescription;
+using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
+using Microsoft.Azure.WebJobs.Extensions.DurableTask;
+
+namespace Energinet.DataHub.ProcessManagement.Core.Infrastructure.Orchestration;
+
+///
+/// An executor implementation that uses to start
+/// Durable Functions orchestration instances.
+///
+/// Must be a Durable Task Client that is connected to
+/// the same Task Hub as the Durable Functions host containing orchestrations.
+internal class DurableOrchestrationInstanceExecutor(
+ IDurableClient durableClient) :
+ IOrchestrationInstanceExecutor
+{
+ private readonly IDurableClient _durableClient = durableClient;
+
+ ///
+ public Task StartNewOrchestrationInstanceAsync(
+ OrchestrationDescription orchestrationDescription,
+ OrchestrationInstance orchestrationInstance)
+ {
+ return _durableClient.StartNewAsync(
+ orchestratorFunctionName: orchestrationDescription.FunctionName,
+ orchestrationInstance.Id.Value.ToString(),
+ input: orchestrationInstance.ParameterValue.SerializedParameterValue);
+ }
+}
diff --git a/source/ProcessManager.Core/Infrastructure/Orchestration/OrchestrationInstanceRepository.cs b/source/ProcessManager.Core/Infrastructure/Orchestration/OrchestrationInstanceRepository.cs
index 72f24e0d5f..f558fc1f4f 100644
--- a/source/ProcessManager.Core/Infrastructure/Orchestration/OrchestrationInstanceRepository.cs
+++ b/source/ProcessManager.Core/Infrastructure/Orchestration/OrchestrationInstanceRepository.cs
@@ -12,7 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
+using Energinet.DataHub.ProcessManagement.Core.Application.Scheduling;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using Energinet.DataHub.ProcessManagement.Core.Infrastructure.Database;
using Microsoft.EntityFrameworkCore;
@@ -20,14 +21,20 @@
namespace Energinet.DataHub.ProcessManagement.Core.Infrastructure.Orchestration;
-public class OrchestrationInstanceRepository : IOrchestrationInstanceRepository, IQueryScheduledOrchestrationInstancesByInstant
+///
+/// Read/write access to the orchestration instance repository.
+///
+internal class OrchestrationInstanceRepository(
+ ProcessManagerContext context) :
+ IOrchestrationInstanceRepository,
+ IOrchestrationInstanceProgressRepository,
+ IOrchestrationInstanceQueries,
+ IScheduledOrchestrationInstancesByInstantQuery
{
- private readonly ProcessManagerContext _context;
+ private readonly ProcessManagerContext _context = context;
- public OrchestrationInstanceRepository(ProcessManagerContext context)
- {
- _context = context;
- }
+ ///
+ public IUnitOfWork UnitOfWork => _context;
///
public Task GetAsync(OrchestrationInstanceId id)
@@ -45,7 +52,7 @@ public async Task AddAsync(OrchestrationInstance orchestrationInstance)
await _context.OrchestrationInstances.AddAsync(orchestrationInstance).ConfigureAwait(false);
}
- ///
+ ///
public async Task> FindAsync(Instant scheduledToRunBefore)
{
var query = _context.OrchestrationInstances
diff --git a/source/ProcessManager.Core/Infrastructure/Orchestration/OrchestrationRegister.cs b/source/ProcessManager.Core/Infrastructure/Registration/OrchestrationRegister.cs
similarity index 90%
rename from source/ProcessManager.Core/Infrastructure/Orchestration/OrchestrationRegister.cs
rename to source/ProcessManager.Core/Infrastructure/Registration/OrchestrationRegister.cs
index 3f2d32b43d..c6fd6e1d89 100644
--- a/source/ProcessManager.Core/Infrastructure/Orchestration/OrchestrationRegister.cs
+++ b/source/ProcessManager.Core/Infrastructure/Registration/OrchestrationRegister.cs
@@ -12,26 +12,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
+using Energinet.DataHub.ProcessManagement.Core.Application.Registration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationDescription;
using Energinet.DataHub.ProcessManagement.Core.Infrastructure.Database;
using Microsoft.EntityFrameworkCore;
-namespace Energinet.DataHub.ProcessManagement.Core.Infrastructure.Orchestration;
+namespace Energinet.DataHub.ProcessManagement.Core.Infrastructure.Registration;
///
/// Keep a register of known Durable Functions orchestrations.
/// Each orchestration is registered with information by which it is possible
/// to communicate with Durable Functions and start a new orchestration instance.
///
-public class OrchestrationRegister : IOrchestrationRegister, IOrchestrationRegisterQueries
+internal class OrchestrationRegister(
+ ProcessManagerContext context) :
+ IOrchestrationRegister,
+ IOrchestrationRegisterQueries
{
- private readonly ProcessManagerContext _context;
-
- public OrchestrationRegister(ProcessManagerContext context)
- {
- _context = context;
- }
+ private readonly ProcessManagerContext _context = context;
///
public Task GetAsync(OrchestrationDescriptionId id)
diff --git a/source/ProcessManager.Core/ProcessManager.Core.csproj b/source/ProcessManager.Core/ProcessManager.Core.csproj
index 1d50cedd86..9edffe4a78 100644
--- a/source/ProcessManager.Core/ProcessManager.Core.csproj
+++ b/source/ProcessManager.Core/ProcessManager.Core.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023CalculationStepStartActivityV1.cs b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023CalculationStepStartActivityV1.cs
index de9e884457..29a6d892be 100644
--- a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023CalculationStepStartActivityV1.cs
+++ b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023CalculationStepStartActivityV1.cs
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using Microsoft.Azure.Functions.Worker;
using NodaTime;
@@ -21,12 +21,10 @@ namespace Energinet.DataHub.ProcessManager.Orchestrations.Processes.BRS_023_027.
internal class Brs023CalculationStepStartActivityV1(
IClock clock,
- IOrchestrationInstanceProgressRepository progressRepository,
- IUnitOfWork unitOfWork)
+ IOrchestrationInstanceProgressRepository progressRepository)
: ProgressActivityBase(
clock,
- progressRepository,
- unitOfWork)
+ progressRepository)
{
[Function(nameof(Brs023CalculationStepStartActivityV1))]
public async Task Run(
@@ -38,7 +36,7 @@ public async Task Run(
var step = orchestrationInstance.Steps.Single(x => x.Sequence == NotifyAggregatedMeasureDataOrchestrationV1.CalculationStepSequence);
step.Lifecycle.TransitionToRunning(Clock);
- await UnitOfWork.CommitAsync().ConfigureAwait(false);
+ await ProgressRepository.UnitOfWork.CommitAsync().ConfigureAwait(false);
// TODO: For demo purposes; remove when done
await Task.Delay(TimeSpan.FromSeconds(3)).ConfigureAwait(false);
diff --git a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023CalculationStepTerminateActivityV1.cs b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023CalculationStepTerminateActivityV1.cs
index 46c8978fca..06e0cc70bd 100644
--- a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023CalculationStepTerminateActivityV1.cs
+++ b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023CalculationStepTerminateActivityV1.cs
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using Microsoft.Azure.Functions.Worker;
using NodaTime;
@@ -21,12 +21,10 @@ namespace Energinet.DataHub.ProcessManager.Orchestrations.Processes.BRS_023_027.
internal class Brs023CalculationStepTerminateActivityV1(
IClock clock,
- IOrchestrationInstanceProgressRepository progressRepository,
- IUnitOfWork unitOfWork)
+ IOrchestrationInstanceProgressRepository progressRepository)
: ProgressActivityBase(
clock,
- progressRepository,
- unitOfWork)
+ progressRepository)
{
[Function(nameof(Brs023CalculationStepTerminateActivityV1))]
public async Task Run(
@@ -38,7 +36,7 @@ public async Task Run(
var step = orchestrationInstance.Steps.Single(x => x.Sequence == NotifyAggregatedMeasureDataOrchestrationV1.CalculationStepSequence);
step.Lifecycle.TransitionToTerminated(Clock, OrchestrationStepTerminationStates.Succeeded);
- await UnitOfWork.CommitAsync().ConfigureAwait(false);
+ await ProgressRepository.UnitOfWork.CommitAsync().ConfigureAwait(false);
// TODO: For demo purposes; remove when done
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
diff --git a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023EnqueueMessagesStepStartActivityV1.cs b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023EnqueueMessagesStepStartActivityV1.cs
index eff37e15d2..c627b6c131 100644
--- a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023EnqueueMessagesStepStartActivityV1.cs
+++ b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023EnqueueMessagesStepStartActivityV1.cs
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using Microsoft.Azure.Functions.Worker;
using NodaTime;
@@ -21,12 +21,10 @@ namespace Energinet.DataHub.ProcessManager.Orchestrations.Processes.BRS_023_027.
internal class Brs023EnqueueMessagesStepStartActivityV1(
IClock clock,
- IOrchestrationInstanceProgressRepository progressRepository,
- IUnitOfWork unitOfWork)
+ IOrchestrationInstanceProgressRepository progressRepository)
: ProgressActivityBase(
clock,
- progressRepository,
- unitOfWork)
+ progressRepository)
{
[Function(nameof(Brs023EnqueueMessagesStepStartActivityV1))]
public async Task Run(
@@ -40,7 +38,7 @@ public async Task Run(
if (!step.IsSkipped())
{
step.Lifecycle.TransitionToRunning(Clock);
- await UnitOfWork.CommitAsync().ConfigureAwait(false);
+ await ProgressRepository.UnitOfWork.CommitAsync().ConfigureAwait(false);
// TODO: For demo purposes; remove when done
await Task.Delay(TimeSpan.FromSeconds(3)).ConfigureAwait(false);
diff --git a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023EnqueueMessagesStepTerminateActivityV1.cs b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023EnqueueMessagesStepTerminateActivityV1.cs
index b338f7e9b0..92d922358a 100644
--- a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023EnqueueMessagesStepTerminateActivityV1.cs
+++ b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023EnqueueMessagesStepTerminateActivityV1.cs
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using Microsoft.Azure.Functions.Worker;
using NodaTime;
@@ -21,12 +21,10 @@ namespace Energinet.DataHub.ProcessManager.Orchestrations.Processes.BRS_023_027.
internal class Brs023EnqueueMessagesStepTerminateActivityV1(
IClock clock,
- IOrchestrationInstanceProgressRepository progressRepository,
- IUnitOfWork unitOfWork)
+ IOrchestrationInstanceProgressRepository progressRepository)
: ProgressActivityBase(
clock,
- progressRepository,
- unitOfWork)
+ progressRepository)
{
[Function(nameof(Brs023EnqueueMessagesStepTerminateActivityV1))]
public async Task Run(
@@ -40,7 +38,7 @@ public async Task Run(
if (!step.IsSkipped())
{
step.Lifecycle.TransitionToTerminated(Clock, OrchestrationStepTerminationStates.Succeeded);
- await UnitOfWork.CommitAsync().ConfigureAwait(false);
+ await ProgressRepository.UnitOfWork.CommitAsync().ConfigureAwait(false);
// TODO: For demo purposes; remove when done
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
diff --git a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023OrchestrationInitializeActivityV1.cs b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023OrchestrationInitializeActivityV1.cs
index 27b99d42bc..914e5bfffd 100644
--- a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023OrchestrationInitializeActivityV1.cs
+++ b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023OrchestrationInitializeActivityV1.cs
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using Microsoft.Azure.Functions.Worker;
using NodaTime;
@@ -25,12 +25,10 @@ namespace Energinet.DataHub.ProcessManager.Orchestrations.Processes.BRS_023_027.
///
internal class Brs023OrchestrationInitializeActivityV1(
IClock clock,
- IOrchestrationInstanceProgressRepository progressRepository,
- IUnitOfWork unitOfWork)
+ IOrchestrationInstanceProgressRepository progressRepository)
: ProgressActivityBase(
clock,
- progressRepository,
- unitOfWork)
+ progressRepository)
{
[Function(nameof(Brs023OrchestrationInitializeActivityV1))]
public async Task Run(
@@ -41,7 +39,7 @@ public async Task Run(
.ConfigureAwait(false);
orchestrationInstance.Lifecycle.TransitionToRunning(Clock);
- await UnitOfWork.CommitAsync().ConfigureAwait(false);
+ await ProgressRepository.UnitOfWork.CommitAsync().ConfigureAwait(false);
// TODO: For demo purposes; remove when done
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
diff --git a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023OrchestrationTerminateActivityV1.cs b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023OrchestrationTerminateActivityV1.cs
index c10402765c..43560cd96f 100644
--- a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023OrchestrationTerminateActivityV1.cs
+++ b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/Brs023OrchestrationTerminateActivityV1.cs
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using Microsoft.Azure.Functions.Worker;
using NodaTime;
@@ -25,12 +25,10 @@ namespace Energinet.DataHub.ProcessManager.Orchestrations.Processes.BRS_023_027.
///
internal class Brs023OrchestrationTerminateActivityV1(
IClock clock,
- IOrchestrationInstanceProgressRepository progressRepository,
- IUnitOfWork unitOfWork)
+ IOrchestrationInstanceProgressRepository progressRepository)
: ProgressActivityBase(
clock,
- progressRepository,
- unitOfWork)
+ progressRepository)
{
[Function(nameof(Brs023OrchestrationTerminateActivityV1))]
public async Task Run(
@@ -41,7 +39,7 @@ public async Task Run(
.ConfigureAwait(false);
orchestrationInstance.Lifecycle.TransitionToTerminated(Clock, OrchestrationInstanceTerminationStates.Succeeded);
- await UnitOfWork.CommitAsync().ConfigureAwait(false);
+ await ProgressRepository.UnitOfWork.CommitAsync().ConfigureAwait(false);
// TODO: For demo purposes; remove when done
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
diff --git a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/ProgressActivityBase.cs b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/ProgressActivityBase.cs
index 1ac19e0c35..cbec8cd11e 100644
--- a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/ProgressActivityBase.cs
+++ b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/Activities/ProgressActivityBase.cs
@@ -12,19 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
using NodaTime;
namespace Energinet.DataHub.ProcessManager.Orchestrations.Processes.BRS_023_027.V1.Activities;
internal abstract class ProgressActivityBase(
IClock clock,
- IOrchestrationInstanceProgressRepository progressRepository,
- IUnitOfWork unitOfWork)
+ IOrchestrationInstanceProgressRepository progressRepository)
{
protected IClock Clock { get; } = clock;
protected IOrchestrationInstanceProgressRepository ProgressRepository { get; } = progressRepository;
-
- protected IUnitOfWork UnitOfWork { get; } = unitOfWork;
}
diff --git a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/NotifyAggregatedMeasureDataHandler.cs b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/NotifyAggregatedMeasureDataHandler.cs
index 98f770f4df..a97a18161e 100644
--- a/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/NotifyAggregatedMeasureDataHandler.cs
+++ b/source/ProcessManager.Orchestrations/Processes/BRS_023_027/V1/NotifyAggregatedMeasureDataHandler.cs
@@ -12,28 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using Energinet.DataHub.ProcessManager.Api.Model;
using Energinet.DataHub.ProcessManager.Orchestrations.Processes.BRS_023_027.V1.Model;
-using Microsoft.Extensions.Logging;
-using NodaTime;
using NodaTime.Extensions;
namespace Energinet.DataHub.ProcessManager.Orchestrations.Processes.BRS_023_027.V1;
-public class NotifyAggregatedMeasureDataHandler(
- ILogger logger,
- IClock clock,
- IOrchestrationInstanceRepository repository,
- IUnitOfWork unitOfWork,
- IOrchestrationInstanceManager manager)
+internal class NotifyAggregatedMeasureDataHandler(
+ IStartOrchestrationInstanceCommands manager)
{
- private readonly ILogger _logger = logger;
- private readonly IClock _clock = clock;
- private readonly IOrchestrationInstanceRepository _repository = repository;
- private readonly IUnitOfWork _unitOfWork = unitOfWork;
- private readonly IOrchestrationInstanceManager _manager = manager;
+ private readonly IStartOrchestrationInstanceCommands _manager = manager;
public async Task ScheduleNewCalculationAsync(
ScheduleOrchestrationInstanceDto dto)
diff --git a/source/ProcessManager.Orchestrations/Program.cs b/source/ProcessManager.Orchestrations/Program.cs
index f784ced92c..f32116b0a3 100644
--- a/source/ProcessManager.Orchestrations/Program.cs
+++ b/source/ProcessManager.Orchestrations/Program.cs
@@ -80,5 +80,5 @@
})
.Build();
-await host.SynchronizeWithOrchestrationRegisterAsync().ConfigureAwait(false);
+await host.SynchronizeWithOrchestrationRegisterAsync("ProcessManager.Orchestrations").ConfigureAwait(false);
await host.RunAsync().ConfigureAwait(false);
diff --git a/source/ProcessManager/Api/CancelScheduledOrchestrationInstanceTrigger.cs b/source/ProcessManager/Api/CancelScheduledOrchestrationInstanceTrigger.cs
index 6f306e7b5c..6e8f465888 100644
--- a/source/ProcessManager/Api/CancelScheduledOrchestrationInstanceTrigger.cs
+++ b/source/ProcessManager/Api/CancelScheduledOrchestrationInstanceTrigger.cs
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@@ -23,10 +23,10 @@ namespace Energinet.DataHub.ProcessManager.Api;
internal class CancelScheduledOrchestrationInstanceTrigger(
ILogger logger,
- IOrchestrationInstanceManager manager)
+ ICancelScheduledOrchestrationInstanceCommand command)
{
private readonly ILogger _logger = logger;
- private readonly IOrchestrationInstanceManager _manager = manager;
+ private readonly ICancelScheduledOrchestrationInstanceCommand _command = command;
///
/// Cancel a scheduled orchestration instance.
@@ -41,7 +41,7 @@ public async Task Run(
Guid id,
FunctionContext executionContext)
{
- await _manager
+ await _command
.CancelScheduledOrchestrationInstanceAsync(new OrchestrationInstanceId(id))
.ConfigureAwait(false);
diff --git a/source/ProcessManager/Api/GetOrchestrationInstanceTrigger.cs b/source/ProcessManager/Api/GetOrchestrationInstanceTrigger.cs
index f0850b2adc..baeff84f5b 100644
--- a/source/ProcessManager/Api/GetOrchestrationInstanceTrigger.cs
+++ b/source/ProcessManager/Api/GetOrchestrationInstanceTrigger.cs
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using Energinet.DataHub.ProcessManager.Api.Mappers;
using Microsoft.AspNetCore.Http;
@@ -24,10 +24,10 @@ namespace Energinet.DataHub.ProcessManager.Api;
internal class GetOrchestrationInstanceTrigger(
ILogger logger,
- IOrchestrationInstanceRepository repository)
+ IOrchestrationInstanceQueries queries)
{
private readonly ILogger _logger = logger;
- private readonly IOrchestrationInstanceRepository _repository = repository;
+ private readonly IOrchestrationInstanceQueries _queries = queries;
///
/// Get orchestration instance.
@@ -42,7 +42,7 @@ public async Task Run(
Guid id,
FunctionContext executionContext)
{
- var orchestrationInstance = await _repository
+ var orchestrationInstance = await _queries
.GetAsync(new OrchestrationInstanceId(id))
.ConfigureAwait(false);
diff --git a/source/ProcessManager/Api/SearchOrchestrationInstancesTrigger.cs b/source/ProcessManager/Api/SearchOrchestrationInstancesTrigger.cs
index 329fc634f2..90cb81137e 100644
--- a/source/ProcessManager/Api/SearchOrchestrationInstancesTrigger.cs
+++ b/source/ProcessManager/Api/SearchOrchestrationInstancesTrigger.cs
@@ -13,7 +13,7 @@
// limitations under the License.
using System.Globalization;
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Orchestration;
using Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;
using Energinet.DataHub.ProcessManager.Api.Mappers;
using Microsoft.AspNetCore.Http;
@@ -26,10 +26,10 @@ namespace Energinet.DataHub.ProcessManager.Api;
internal class SearchOrchestrationInstancesTrigger(
ILogger logger,
- IOrchestrationInstanceRepository repository)
+ IOrchestrationInstanceQueries queries)
{
private readonly ILogger _logger = logger;
- private readonly IOrchestrationInstanceRepository _repository = repository;
+ private readonly IOrchestrationInstanceQueries _queries = queries;
[Function(nameof(SearchOrchestrationInstancesTrigger))]
public async Task Run(
@@ -62,7 +62,7 @@ public async Task Run(
? Instant.FromDateTimeOffset(terminatedAtOrEarlierResult)
: (Instant?)null;
- var orchestrationInstances = await _repository
+ var orchestrationInstances = await _queries
.SearchAsync(name, version, lifecycleState, terminationState, startedAtOrLater, terminatedAtOrEarlier)
.ConfigureAwait(false);
diff --git a/source/ProcessManager/Scheduler/SchedulerHandler.cs b/source/ProcessManager/Scheduler/SchedulerHandler.cs
index 1a7d94e130..c5daaab23e 100644
--- a/source/ProcessManager/Scheduler/SchedulerHandler.cs
+++ b/source/ProcessManager/Scheduler/SchedulerHandler.cs
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-using Energinet.DataHub.ProcessManagement.Core.Application;
+using Energinet.DataHub.ProcessManagement.Core.Application.Scheduling;
using Microsoft.Extensions.Logging;
using NodaTime;
@@ -21,13 +21,13 @@ namespace Energinet.DataHub.ProcessManager.Scheduler;
public class SchedulerHandler(
ILogger logger,
IClock clock,
- IQueryScheduledOrchestrationInstancesByInstant query,
- IOrchestrationInstanceScheduleManager manager)
+ IScheduledOrchestrationInstancesByInstantQuery query,
+ IStartScheduledOrchestrationInstanceCommand command)
{
private readonly ILogger _logger = logger;
private readonly IClock _clock = clock;
- private readonly IQueryScheduledOrchestrationInstancesByInstant _query = query;
- private readonly IOrchestrationInstanceScheduleManager _manager = manager;
+ private readonly IScheduledOrchestrationInstancesByInstantQuery _query = query;
+ private readonly IStartScheduledOrchestrationInstanceCommand _command = command;
public async Task StartScheduledOrchestrationInstancesAsync()
{
@@ -40,7 +40,7 @@ public async Task StartScheduledOrchestrationInstancesAsync()
{
try
{
- await _manager
+ await _command
.StartScheduledOrchestrationInstanceAsync(orchestrationInstance.Id)
.ConfigureAwait(false);
}
diff --git a/source/SubsystemTests/Drivers/EdiDatabaseDriver.cs b/source/SubsystemTests/Drivers/EdiDatabaseDriver.cs
index 4de47f7c7b..89c62b73ac 100644
--- a/source/SubsystemTests/Drivers/EdiDatabaseDriver.cs
+++ b/source/SubsystemTests/Drivers/EdiDatabaseDriver.cs
@@ -274,6 +274,21 @@ WHERE B.DequeuedAt IS NOT NULL
return dequeuedMessagesCount;
}
+ internal async Task CountEnqueuedMessagesForCalculationAsync(Guid calculationId)
+ {
+ await using var connection = new SqlConnection(_connectionString);
+
+ await connection.OpenAsync();
+
+ var enqueuedMessagesCount = await connection.ExecuteScalarAsync(
+ sql: @"SELECT COUNT(B.[Id]) FROM [Bundles] B
+ INNER JOIN [OutgoingMessages] OM ON B.[Id] = OM.[AssignedBundleId]
+ WHERE OM.[CalculationId] = @CalculationId",
+ param: new { CalculationId = calculationId, });
+
+ return enqueuedMessagesCount;
+ }
+
private async Task GetProcessIdAsync(SqlCommand command, CancellationToken cancellationToken)
{
await using var connection = new SqlConnection(_connectionString);
diff --git a/source/SubsystemTests/LoadTest/LoadTestFixture.cs b/source/SubsystemTests/LoadTest/LoadTestFixture.cs
index 54c3a08f40..7a5edf40d8 100644
--- a/source/SubsystemTests/LoadTest/LoadTestFixture.cs
+++ b/source/SubsystemTests/LoadTest/LoadTestFixture.cs
@@ -18,6 +18,8 @@
using Energinet.DataHub.Core.FunctionApp.TestCommon.Configuration;
using Energinet.DataHub.EDI.B2BApi.AppTests.DurableTask;
using Energinet.DataHub.EDI.SubsystemTests.Drivers;
+using Microsoft.ApplicationInsights;
+using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Extensions.Configuration;
@@ -61,6 +63,11 @@ public LoadTestFixture()
configuration,
"LOAD_TEST_CALCULATION_ID");
+ MinimumEnqueuedMessagesCount = GetConfigurationValue(
+ configuration,
+ "MINIMUM_ENQUEUED_MESSAGES_COUNT",
+ defaultValue: 0);
+
MinimumDequeuedMessagesCount = GetConfigurationValue(
configuration,
"MINIMUM_DEQUEUED_MESSAGES_COUNT",
@@ -73,18 +80,27 @@ public LoadTestFixture()
_durableTaskManager = new DurableTaskManager(
"OrchestrationsStorageConnectionString",
GetConfigurationValue(configuration, "func-edi-api-taskhub-storage-connection-string"));
+
+ var credential = new DefaultAzureCredential();
+ var telemetryConfiguration = TelemetryConfiguration.CreateDefault();
+ telemetryConfiguration.SetAzureTokenCredential(credential);
+ TelemetryClient = new TelemetryClient(telemetryConfiguration);
}
internal EdiInboxClient EdiInboxClient { get; }
internal Guid LoadTestCalculationId { get; }
+ internal int MinimumEnqueuedMessagesCount { get; }
+
internal int MinimumDequeuedMessagesCount { get; }
internal IntegrationEventPublisher IntegrationEventPublisher { get; }
internal string DatabaseConnectionString { get; }
+ internal TelemetryClient TelemetryClient { get; }
+
[NotNull]
internal IDurableClient? DurableClient { get; private set; }
diff --git a/source/SubsystemTests/LoadTest/LoadTestHelper.cs b/source/SubsystemTests/LoadTest/LoadTestHelper.cs
index 08e7f7e6ec..9a488154d9 100644
--- a/source/SubsystemTests/LoadTest/LoadTestHelper.cs
+++ b/source/SubsystemTests/LoadTest/LoadTestHelper.cs
@@ -16,6 +16,7 @@
using Energinet.DataHub.EDI.SubsystemTests.Drivers;
using Energinet.DataHub.EDI.SubsystemTests.Dsl;
using FluentAssertions;
+using FluentAssertions.Execution;
using Nito.AsyncEx;
using NodaTime;
using Xunit.Abstractions;
@@ -35,6 +36,8 @@ namespace Energinet.DataHub.EDI.SubsystemTests.LoadTest;
[SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "Test class")]
public sealed class LoadTestHelper : IClassFixture
{
+ private const string EnqueuedAmountMetric = "EnqueuedAmount";
+ private const string DequeuedAmountMetric = "DequeuedAmount";
private readonly LoadTestFixture _fixture;
private readonly ITestOutputHelper _logger;
private readonly EdiDriver _ediDriver;
@@ -69,13 +72,20 @@ await CalculationCompletedDsl.StartEnqueueMessagesOrchestration(
[Fact]
public async Task After_load_test()
{
- await _ediDriver.StopOrchestrationForCalculationAsync(
- calculationId: _fixture.LoadTestCalculationId,
- createdAfter: SystemClock.Instance.GetCurrentInstant().Minus(Duration.FromHours(1)));
+ var enqueuedMessagesCount = await _ediDatabaseDriver.CountEnqueuedMessagesForCalculationAsync(_fixture.LoadTestCalculationId);
+ _logger.WriteLine($"Enqueued messages count: {enqueuedMessagesCount} (CalculationId={_fixture.LoadTestCalculationId})");
var dequeuedMessagesCount = await _ediDatabaseDriver.CountDequeuedMessagesForCalculationAsync(_fixture.LoadTestCalculationId);
_logger.WriteLine($"Dequeued messages count: {dequeuedMessagesCount} (CalculationId={_fixture.LoadTestCalculationId})");
+ _fixture.TelemetryClient.GetMetric(EnqueuedAmountMetric).TrackValue(enqueuedMessagesCount);
+ _fixture.TelemetryClient.GetMetric(DequeuedAmountMetric).TrackValue(dequeuedMessagesCount);
+
+ using var scope = new AssertionScope();
+ enqueuedMessagesCount.Should().BeGreaterThanOrEqualTo(
+ _fixture.MinimumEnqueuedMessagesCount,
+ $"because the system should be performant enough to enqueue at least {_fixture.MinimumEnqueuedMessagesCount} messages during the load test");
+
dequeuedMessagesCount.Should().BeGreaterThanOrEqualTo(
_fixture.MinimumDequeuedMessagesCount,
$"because the system should be performant enough to dequeue at least {_fixture.MinimumDequeuedMessagesCount} messages during the load test");
diff --git a/source/SubsystemTests/SubsystemTests.csproj b/source/SubsystemTests/SubsystemTests.csproj
index 830157e114..81894bbeb2 100644
--- a/source/SubsystemTests/SubsystemTests.csproj
+++ b/source/SubsystemTests/SubsystemTests.csproj
@@ -74,7 +74,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -83,13 +83,13 @@
-
+
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/SystemTests/SystemTests.csproj b/source/SystemTests/SystemTests.csproj
index 4a0cbdafe6..ecdfe75ffe 100644
--- a/source/SystemTests/SystemTests.csproj
+++ b/source/SystemTests/SystemTests.csproj
@@ -14,12 +14,12 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/source/Tests/CimMessageAdapter/Messages/MeteredDataForMeasurementPointEbixMessageParserTests/MessageParserTests.cs b/source/Tests/CimMessageAdapter/Messages/MeteredDataForMeasurementPointMessageParserTests/MessageParserTests.cs
similarity index 89%
rename from source/Tests/CimMessageAdapter/Messages/MeteredDataForMeasurementPointEbixMessageParserTests/MessageParserTests.cs
rename to source/Tests/CimMessageAdapter/Messages/MeteredDataForMeasurementPointMessageParserTests/MessageParserTests.cs
index 8926c8ce51..eefc14d39a 100644
--- a/source/Tests/CimMessageAdapter/Messages/MeteredDataForMeasurementPointEbixMessageParserTests/MessageParserTests.cs
+++ b/source/Tests/CimMessageAdapter/Messages/MeteredDataForMeasurementPointMessageParserTests/MessageParserTests.cs
@@ -17,15 +17,14 @@
using Energinet.DataHub.EDI.IncomingMessages.Domain;
using Energinet.DataHub.EDI.IncomingMessages.Domain.Validation.ValidationErrors;
using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers;
-using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.MeteredDateForMeasurementPointParsers.Ebix;
+using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.MessageParsers.MeteredDateForMeasurementPointParsers;
using Energinet.DataHub.EDI.IncomingMessages.Infrastructure.Schemas.Ebix;
using Energinet.DataHub.EDI.IncomingMessages.Interfaces.Models;
using FluentAssertions;
using FluentAssertions.Execution;
-using Microsoft.Extensions.Logging;
using Xunit;
-namespace Energinet.DataHub.EDI.Tests.CimMessageAdapter.Messages.MeteredDataForMeasurementPointEbixMessageParserTests;
+namespace Energinet.DataHub.EDI.Tests.CimMessageAdapter.Messages.MeteredDataForMeasurementPointMessageParserTests;
public sealed class MessageParserTests
{
@@ -35,10 +34,10 @@ public sealed class MessageParserTests
private static readonly string SubPath =
$"{Path.DirectorySeparatorChar}MeteredDataForMeasurementPoint{Path.DirectorySeparatorChar}";
- private readonly MarketMessageParser _marketMessageParser = new(
- [
- new MeteredDataForMeasurementPointEbixMessageParser(new EbixSchemaProvider(), new Logger(new LoggerFactory())),
- ]);
+ private readonly Dictionary _marketMessageParser = new()
+ {
+ { DocumentFormat.Ebix, new EbixMessageParser(new EbixSchemaProvider()) },
+ };
public static TheoryData CreateMessagesWithSingleAndMultipleTransactions()
{
@@ -67,10 +66,8 @@ public static TheoryData CreateBadMessages()
[MemberData(nameof(CreateMessagesWithSingleAndMultipleTransactions))]
public async Task Successfully_parsed(DocumentFormat format, Stream message)
{
- var result = await _marketMessageParser.ParseAsync(
+ var result = await _marketMessageParser.GetValueOrDefault(format)!.ParseAsync(
new IncomingMarketMessageStream(message),
- format,
- IncomingDocumentType.MeteredDataForMeasurementPoint,
CancellationToken.None);
using var assertionScope = new AssertionScope();
@@ -122,10 +119,8 @@ public async Task Successfully_parsed(DocumentFormat format, Stream message)
[MemberData(nameof(CreateBadMessages))]
public async Task Messages_with_errors(DocumentFormat format, Stream message, string expectedError)
{
- var result = await _marketMessageParser.ParseAsync(
+ var result = await _marketMessageParser.GetValueOrDefault(format)!.ParseAsync(
new IncomingMarketMessageStream(message),
- format,
- IncomingDocumentType.MeteredDataForMeasurementPoint,
CancellationToken.None);
result.Success.Should().BeFalse();
diff --git a/source/Tests/Tests.csproj b/source/Tests/Tests.csproj
index a5b5a517fb..8824e4ce63 100644
--- a/source/Tests/Tests.csproj
+++ b/source/Tests/Tests.csproj
@@ -22,14 +22,14 @@ limitations under the License.
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive