diff --git a/src/Benchmarks/Benchmarks.csproj b/src/Benchmarks/Benchmarks.csproj
index dc2edd46f8..a2f51ff164 100644
--- a/src/Benchmarks/Benchmarks.csproj
+++ b/src/Benchmarks/Benchmarks.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/src/Hl7.Fhir.Base/Rest/BaseFhirClient.cs b/src/Hl7.Fhir.Base/Rest/BaseFhirClient.cs
index edc7e14fa6..d072424c3c 100644
--- a/src/Hl7.Fhir.Base/Rest/BaseFhirClient.cs
+++ b/src/Hl7.Fhir.Base/Rest/BaseFhirClient.cs
@@ -938,6 +938,21 @@ public virtual void Delete(string resourceType, SearchParams condition)
return OperationAsync(operation, parameters, useGet).WaitResult();
}
+ public virtual Task ProcessMessageAsync(Bundle bundle, bool async = false, string? responseUrl = null, CancellationToken? ct = null)
+ {
+ if (bundle == null) throw new ArgumentNullException(nameof(bundle));
+
+ var tx = new TransactionBuilder(Endpoint).ProcessMessage(bundle, async, responseUrl).ToBundle();
+
+ return executeAsync(tx, new [] {HttpStatusCode.OK, HttpStatusCode.Accepted, HttpStatusCode.NoContent}, ct);
+ }
+
+ [Obsolete("Synchronous use of the FhirClient is strongly discouraged, use the asynchronous call instead.")]
+ public virtual Resource? ProcessMessage(Bundle messageBundle, bool async = false, string? responseUrl = null)
+ {
+ return ProcessMessageAsync(messageBundle, async, responseUrl).WaitResult();
+ }
+
private Task internalOperationAsync(string operationName, string? type = null, string? id = null, string? vid = null,
Parameters? parameters = null, bool useGet = false, CancellationToken? ct = null)
{
diff --git a/src/Hl7.Fhir.Base/Rest/TransactionBuilder.cs b/src/Hl7.Fhir.Base/Rest/TransactionBuilder.cs
index 4ec4d75ed3..2718572896 100644
--- a/src/Hl7.Fhir.Base/Rest/TransactionBuilder.cs
+++ b/src/Hl7.Fhir.Base/Rest/TransactionBuilder.cs
@@ -498,6 +498,18 @@ public TransactionBuilder ResourceOperation(string resourceType, string id, stri
return EndpointOperation(path, parameters, useGet, bundleEntryFullUrl);
}
+ public TransactionBuilder ProcessMessage(Bundle messageBundle, bool async = false, string? responseUrl = null, string? bundleEntryFullUrl = null)
+ {
+ var entry = newEntry(Bundle.HTTPVerb.POST, InteractionType.Operation, bundleEntryFullUrl);
+ var path = newRestUrl().AddPath(OPERATIONPREFIX + "process-message");
+ if (async) path.AddParam("async", "true");
+ if (responseUrl != null) path.AddParam("response-url", responseUrl);
+ entry.Resource = messageBundle;
+ addEntry(entry, path);
+
+ return this;
+ }
+
///
/// Add a "search" entry to the transaction/batch
///
diff --git a/src/Hl7.Fhir.Conformance/Specification/Source/SnapshotSource.cs b/src/Hl7.Fhir.Conformance/Specification/Source/SnapshotSource.cs
index 8700f8db37..f9680ccc95 100644
--- a/src/Hl7.Fhir.Conformance/Specification/Source/SnapshotSource.cs
+++ b/src/Hl7.Fhir.Conformance/Specification/Source/SnapshotSource.cs
@@ -3,7 +3,7 @@
using Hl7.Fhir.Utility;
using System;
using System.Diagnostics;
-using T=System.Threading.Tasks;
+using T = System.Threading.Tasks;
namespace Hl7.Fhir.Specification.Source
{
@@ -34,7 +34,9 @@ public SnapshotSource(SnapshotGenerator generator)
/// Creates a new instance of the for the specified internal resolver.
/// An internal instance. The implementation should be idempotent (i.e. cached), so the generated snapshots are persisted in memory.
/// Configuration settings for the snapshot generator.
- public SnapshotSource(IResourceResolver source, SnapshotGeneratorSettings settings)
+#pragma warning disable CS0618 // Type or member is obsolete
+ public SnapshotSource(ISyncOrAsyncResourceResolver source, SnapshotGeneratorSettings settings)
+#pragma warning restore CS0618 // Type or member is obsolete
{
// SnapshotGenerator ctor will throw if source or settings are null
Generator = new SnapshotGenerator(source, settings);
@@ -43,11 +45,13 @@ public SnapshotSource(IResourceResolver source, SnapshotGeneratorSettings settin
/// Creates a new instance of the for the specified internal resolver.
/// An internal instance. The implementation should be idempotent (i.e. cached), so the generated snapshots are persisted in memory.
/// Determines if the source should always discard any existing snapshot components provided by the internal source and force re-generation.
- public SnapshotSource(IResourceResolver source, bool regenerate)
+#pragma warning disable CS0618 // Type or member is obsolete
+ public SnapshotSource(ISyncOrAsyncResourceResolver source, bool regenerate)
+#pragma warning restore CS0618 // Type or member is obsolete
: this(source, createSettings(regenerate)) { }
// Create default SnapshotGeneratorSettings, apply the specified regenerate flag
- static SnapshotGeneratorSettings createSettings(bool regenerate)
+ private static SnapshotGeneratorSettings createSettings(bool regenerate)
{
var settings = SnapshotGeneratorSettings.CreateDefault();
settings.ForceRegenerateSnapshots = regenerate;
@@ -56,7 +60,9 @@ static SnapshotGeneratorSettings createSettings(bool regenerate)
/// Creates a new instance of the for the specified internal resolver.
/// An internal instance. The implementation should be idempotent (i.e. cached), so the generated snapshots are persisted in memory.
- public SnapshotSource(IResourceResolver source)
+#pragma warning disable CS0618 // Type or member is obsolete
+ public SnapshotSource(ISyncOrAsyncResourceResolver source)
+#pragma warning restore CS0618 // Type or member is obsolete
: this(source, SnapshotGeneratorSettings.CreateDefault()) { }
/// Returns the internal instance used by the source.
diff --git a/src/Hl7.Fhir.Support.Poco.Tests/Rest/FhirClientMockTests.cs b/src/Hl7.Fhir.Support.Poco.Tests/Rest/FhirClientMockTests.cs
index 26f97fec2a..945d77833d 100644
--- a/src/Hl7.Fhir.Support.Poco.Tests/Rest/FhirClientMockTests.cs
+++ b/src/Hl7.Fhir.Support.Poco.Tests/Rest/FhirClientMockTests.cs
@@ -248,6 +248,48 @@ public async T.Task TestOperationWithEmptyBody()
parameters!.Parameter.FirstOrDefault()!.Value.Should().BeOfType().Which.Value.Should().Be("connected");
}
+ [TestMethod]
+ public async T.Task TestProcessMessage()
+ {
+ var response = new HttpResponseMessage
+ {
+ StatusCode = HttpStatusCode.OK,
+ Content = new StringContent(@"{""resourceType"": ""Bundle"" }", Encoding.UTF8, "application/json"),
+ RequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://example.com/$process-message")
+ };
+
+ using var client = new MoqBuilder()
+ .Send(response, h => h.RequestUri == new Uri("http://example.com/$process-message"))
+ .AsClient();
+
+ var message = new TransactionBuilder("http://example.com/", Bundle.BundleType.Message).ToBundle();
+
+ var bundle = await client.ProcessMessageAsync(message);
+
+ bundle.Should().NotBeNull();
+ }
+
+ [TestMethod]
+ public async T.Task TestProcessMessageParameters()
+ {
+ var response = new HttpResponseMessage
+ {
+ StatusCode = HttpStatusCode.OK,
+ Content = new StringContent(@"{""resourceType"": ""Bundle"" }", Encoding.UTF8, "application/json"),
+ RequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://example.com/$process-message")
+ };
+
+ using var client = new MoqBuilder()
+ .Send(response, h => h.RequestUri == new Uri("http://example.com/$process-message?async=true&response-url=http%3A%2F%2Fresponseurl.com"))
+ .AsClient();
+
+ var message = new TransactionBuilder("http://example.com/", Bundle.BundleType.Message).ToBundle();
+
+ var bundle = await client.ProcessMessageAsync(message, true, "http://responseurl.com");
+
+ bundle.Should().NotBeNull();
+ }
+
[TestMethod]
public async Task WillFetchFullRepresentation()
{