Skip to content

Commit de8f922

Browse files
committed
gh-235 Add support for mongodb
Signed-off-by: Victor Chang <[email protected]>
1 parent 6a7d274 commit de8f922

File tree

94 files changed

+1658
-821
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+1658
-821
lines changed

src/Api/BaseApplicationEntity.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ namespace Monai.Deploy.InformaticsGateway.Api
2323
/// <remarks>
2424
/// * [Application Entity](http://www.otpedia.com/entryDetails.cfm?id=137)
2525
/// </remarks>
26-
public class BaseApplicationEntity
26+
public class BaseApplicationEntity : DatabaseEntityBase
2727
{
28+
/// <inheritdoc/>
29+
public override string Id { get => Name; set => Name = value; }
30+
2831
/// <summary>
2932
/// Gets or sets the unique name used to identify a DICOM application entity.
3033
/// This value must be unique.

src/Api/IDatabaseEntity.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2022 MONAI Consortium
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
using System;
18+
using MongoDB.Bson.Serialization.Attributes;
19+
20+
namespace Monai.Deploy.InformaticsGateway.Api
21+
{
22+
public interface IDatabaseEntity
23+
{
24+
/// <summary>
25+
/// Gets or sets the internal object identifier.
26+
/// </summary>
27+
[BsonId]
28+
string Id { get; set; }
29+
30+
/// <summary>
31+
/// Gets or sets the date time object created.
32+
/// </summary>
33+
DateTimeOffset DateTimeCreated { get; }
34+
}
35+
36+
public abstract class DatabaseEntityBase : IDatabaseEntity
37+
{
38+
public abstract string Id { get; set; }
39+
40+
public DateTimeOffset DateTimeCreated { get; set; } = DateTimeOffset.UtcNow;
41+
}
42+
}

src/Api/Monai.Deploy.InformaticsGateway.Api.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,15 @@
3232
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="6.0.10" />
3333
<PackageReference Include="Monai.Deploy.Messaging" Version="0.1.9" />
3434
<PackageReference Include="Monai.Deploy.Storage" Version="0.2.10" />
35+
<PackageReference Include="MongoDB.Bson" Version="2.18.0" />
3536
</ItemGroup>
3637

3738
<ItemGroup>
39+
<Compile Remove="MessageBroker\**" />
3840
<Compile Remove="Test\**" />
41+
<EmbeddedResource Remove="MessageBroker\**" />
3942
<EmbeddedResource Remove="Test\**" />
43+
<None Remove="MessageBroker\**" />
4044
<None Remove="Test\**" />
4145
</ItemGroup>
4246

@@ -47,8 +51,4 @@
4751
<ItemGroup>
4852
<ProjectReference Include="..\Common\Monai.Deploy.InformaticsGateway.Common.csproj" />
4953
</ItemGroup>
50-
51-
<ItemGroup>
52-
<Folder Include="MessageBroker\" />
53-
</ItemGroup>
5454
</Project>

src/Api/MonaiApplicationEntity.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,11 @@ namespace Monai.Deploy.InformaticsGateway.Api
4444
/// }
4545
/// </code>
4646
/// </example>
47-
public class MonaiApplicationEntity
47+
public class MonaiApplicationEntity : DatabaseEntityBase
4848
{
49+
/// <inheritdoc/>
50+
public override string Id { get => Name; set => Name = value; }
51+
4952
/// <summary>
5053
/// Gets or sets the name of a MONAI DICOM application entity.
5154
/// This value must be unique.

src/Api/Rest/InferenceRequest.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,11 @@ public enum InferenceRequestState
7676
/// <para><c>inputMetadata></c> is required.</para>
7777
/// <para><c>inputResources></c> is required.</para>
7878
/// </remarks>
79-
public class InferenceRequest
79+
public class InferenceRequest : DatabaseEntityBase
8080
{
81+
/// <inheritdoc/>
82+
public override string Id { get => InferenceRequestId; set => InferenceRequestId = value; }
83+
8184
/// <summary>
8285
/// Gets or set the transaction ID of a request.
8386
/// </summary>
@@ -124,7 +127,7 @@ public class InferenceRequest
124127
/// <summary>
125128
/// Unique identity for the request.
126129
/// </summary>
127-
public Guid InferenceRequestId { get; set; } = Guid.NewGuid();
130+
public string InferenceRequestId { get; set; } = Guid.NewGuid().ToString();
128131

129132
/// <summary>
130133
/// Internal use only - get or sets the state of a inference request.

src/Api/Storage/Payload.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
namespace Monai.Deploy.InformaticsGateway.Api.Storage
2424
{
25-
public class Payload : IDisposable
25+
public class Payload : DatabaseEntityBase, IDisposable
2626
{
2727
public enum PayloadState
2828
{
@@ -46,14 +46,15 @@ public enum PayloadState
4646
private readonly Stopwatch _lastReceived;
4747
private bool _disposedValue;
4848

49-
public Guid Id { get; }
49+
/// <inheritdoc/>
50+
public override string Id { get => PayloadId.ToString(); set => PayloadId = Guid.Parse(value); }
51+
52+
public Guid PayloadId { get; set; }
5053

5154
public uint Timeout { get; init; }
5255

5356
public string Key { get; init; }
5457

55-
public DateTime DateTimeCreated { get; private set; }
56-
5758
public int RetryCount { get; set; }
5859

5960
public PayloadState State { get; set; }
@@ -66,7 +67,10 @@ public enum PayloadState
6667

6768
public bool HasTimedOut { get => ElapsedTime().TotalSeconds >= Timeout; }
6869

69-
public TimeSpan Elapsed { get { return DateTime.UtcNow.Subtract(DateTimeCreated); } }
70+
public TimeSpan Elapsed
71+
{
72+
get { return DateTimeOffset.UtcNow.Subtract(DateTimeCreated); }
73+
}
7074

7175
public string CallingAeTitle { get => Files.OfType<DicomFileStorageMetadata>().Select(p => p.CallingAeTitle).FirstOrDefault(); }
7276

@@ -81,7 +85,7 @@ public Payload(string key, string correlationId, uint timeout)
8185

8286
CorrelationId = correlationId;
8387
DateTimeCreated = DateTime.UtcNow;
84-
Id = Guid.NewGuid();
88+
Id = Guid.NewGuid().ToString();
8589
Key = key;
8690
State = PayloadState.Created;
8791
RetryCount = 0;

src/CLI/Commands/SourceCommand.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ public SourceCommand() : base("src", "Configure DICOM sources")
4545
SetupListSourceCommand();
4646
}
4747

48-
4948
private void SetupListSourceCommand()
5049
{
5150
var listCommand = new Command("ls", "List all DICOM sources");
@@ -81,6 +80,7 @@ private void SetupAddSourceCommand()
8180

8281
addCommand.Handler = CommandHandler.Create<SourceApplicationEntity, IHost, bool, CancellationToken>(AddSourceHandlerAsync);
8382
}
83+
8484
private void SetupUpdateSourceCommand()
8585
{
8686
var addCommand = new Command("update", "Update a new DICOM source");
@@ -233,6 +233,7 @@ private async Task<int> AddSourceHandlerAsync(SourceApplicationEntity entity, IH
233233
}
234234
return ExitCodes.Success;
235235
}
236+
236237
private async Task<int> UpdateSourceHandlerAsync(SourceApplicationEntity entity, IHost host, bool verbose, CancellationToken cancellationTokena)
237238
{
238239
Guard.Against.Null(entity, nameof(entity));

src/CLI/Test/DestinationCommandTest.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,6 @@ public async Task DstCEcho_Command_ConfigurationException()
339339
_logger.VerifyLoggingMessageBeginsWith("Please execute `testhost config init` to intialize Informatics Gateway.", LogLevel.Critical, Times.Once());
340340
}
341341

342-
343342
[Fact(DisplayName = "dst update command")]
344343
public async Task DstUpdate_Command()
345344
{

src/CLI/Test/SourceCommandTest.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,5 @@ public async Task SrcUpdate_Command_ConfigurationException()
346346

347347
_logger.VerifyLoggingMessageBeginsWith("Please execute `testhost config init` to intialize Informatics Gateway.", LogLevel.Critical, Times.Once());
348348
}
349-
350349
}
351350
}

src/Client/Test/AeTitleServiceTest.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,6 @@ public async Task CEcho()
422422

423423
var exception = await Record.ExceptionAsync(async () => await service.CEcho(aet.Name, CancellationToken.None));
424424
Assert.Null(exception);
425-
426425
}
427426

428427
[Fact(DisplayName = "Destination - C-ECHO returns a problem")]

src/Configuration/StorageConfiguration.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ public class StorageConfiguration : StorageServiceConfiguration
4343
[ConfigurationKeyName("bufferSize")]
4444
public int BufferSize { get; set; } = 128000;
4545

46-
4746
/// <summary>
4847
/// Gets or set the maximum memory buffer size in bytes with default to 30MiB.
4948
/// </summary>

src/Database/Api/IInformaticsGatewayRepository.cs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,29 @@
1414
* limitations under the License.
1515
*/
1616

17-
using Microsoft.EntityFrameworkCore.ChangeTracking;
17+
using System.Linq.Expressions;
18+
using Monai.Deploy.InformaticsGateway.Api;
1819

1920
namespace Monai.Deploy.InformaticsGateway.Database.Api
2021
{
21-
public interface IInformaticsGatewayRepository<T> where T : class
22+
public interface IInformaticsGatewayRepository<T> where T : IDatabaseEntity
2223
{
2324
IQueryable<T> AsQueryable();
2425

25-
Task<T> FindAsync(params object[] keyValues);
26+
Task<bool> AnyAsync(Expression<Func<T, bool>> filterExpression, CancellationToken cancellationToken = default);
2627

27-
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
28+
Task<T?> FindByIdAsync(string key, CancellationToken cancellationToken = default);
2829

29-
Task<List<T>> ToListAsync();
30+
Task<T?> FirstOrDefaultAsync(Expression<Func<T, bool>> filterExpression, CancellationToken cancellationToken = default);
3031

31-
EntityEntry<T> Update(T entity);
32+
Task<List<T>> ToListAsync(CancellationToken cancellationToken = default);
3233

33-
EntityEntry<T> Remove(T entity);
34+
Task<T> AddAsync(T entity, CancellationToken cancellationToken = default);
3435

35-
void RemoveRange(params T[] entities);
36+
Task<T> UpdateAsync(T entity, CancellationToken cancellationToken = default);
3637

37-
Task<EntityEntry<T>> AddAsync(T item, CancellationToken cancellationToken = default);
38+
Task<T> RemoveAsync(T entity, CancellationToken cancellationToken = default);
3839

39-
T FirstOrDefault(Func<T, bool> p);
40-
41-
void Detach(T job);
42-
43-
bool Any(Func<T, bool> p);
40+
Task RemoveRangeAsync(CancellationToken cancellationToken = default, params T[] entities);
4441
}
4542
}

src/Database/Api/Log.9000.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2022 MONAI Consortium
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
using Microsoft.Extensions.Logging;
18+
19+
namespace Monai.Deploy.InformaticsGateway.Database.Api
20+
{
21+
public static partial class Log
22+
{
23+
[LoggerMessage(EventId = 9000, Level = LogLevel.Error, Message = "Error adding item {type} to the database.")]
24+
public static partial void ErrorAddItem(this ILogger logger, string @type, Exception ex);
25+
26+
[LoggerMessage(EventId = 9001, Level = LogLevel.Error, Message = "Error updating item {type} in the database.")]
27+
public static partial void ErrorUpdateItem(this ILogger logger, string @type, Exception ex);
28+
29+
[LoggerMessage(EventId = 9002, Level = LogLevel.Error, Message = "Error deleting item {type} from the database.")]
30+
public static partial void ErrorDeleteItem(this ILogger logger, string @type, Exception ex);
31+
}
32+
}

src/Database/EntityFramework/Configuration/SR.cs renamed to src/Database/Api/SR.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@
1515
* limitations under the License.
1616
*/
1717

18-
namespace Monai.Deploy.InformaticsGateway.Database.EntityFramework.Configurations
18+
namespace Monai.Deploy.InformaticsGateway.Database.Api
1919
{
2020
public static class SR
2121
{
2222
/// <summary>
2323
/// Name of the key for retrieve database connection string.
2424
/// </summary>
2525
public const string DatabaseConnectionStringKey = "InformaticsGatewayDatabase";
26-
2726
}
2827
}

src/Database/Api/StorageMetadataWrapper.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,27 @@
1717
using System.Text.Json;
1818
using System.Text.Json.Serialization;
1919
using Ardalis.GuardClauses;
20+
using Monai.Deploy.InformaticsGateway.Api;
2021
using Monai.Deploy.InformaticsGateway.Api.Storage;
2122

2223
namespace Monai.Deploy.InformaticsGateway.Database.Api
2324
{
24-
public class StorageMetadataWrapper
25+
public class StorageMetadataWrapper : DatabaseEntityBase
2526
{
27+
/// <inheritdoc/>
28+
public override string Id { get => Identity; set => Identity = value; }
29+
2630
[JsonPropertyName("correlationId")]
27-
public string CorrelationId { get; set; }
31+
public string CorrelationId { get; set; } = string.Empty;
2832

2933
[JsonPropertyName("identity")]
30-
public string Identity { get; set; }
34+
public string Identity { get; set; } = string.Empty;
3135

3236
[JsonPropertyName("value")]
33-
public string Value { get; set; }
37+
public string Value { get; set; } = string.Empty;
3438

3539
[JsonPropertyName("typeName")]
36-
public string TypeName { get; set; }
40+
public string TypeName { get; set; } = string.Empty;
3741

3842
[JsonPropertyName("isUploaded")]
3943
public bool IsUploaded { get; set; }
@@ -43,7 +47,7 @@ private StorageMetadataWrapper()
4347

4448
public StorageMetadataWrapper(FileStorageMetadata metadata)
4549
{
46-
Guard.Against.Null(metadata, nameof(metadata));
50+
Guard.Against.Null(metadata);
4751

4852
CorrelationId = metadata.CorrelationId;
4953
Identity = metadata.Id;
@@ -52,14 +56,14 @@ public StorageMetadataWrapper(FileStorageMetadata metadata)
5256

5357
public void Update(FileStorageMetadata metadata)
5458
{
55-
Guard.Against.Null(metadata, nameof(metadata));
59+
Guard.Against.Null(metadata);
5660

5761
IsUploaded = metadata.IsUploaded;
5862
Value = JsonSerializer.Serialize<object>(metadata);
59-
TypeName = metadata.GetType().AssemblyQualifiedName;
63+
TypeName = metadata.GetType().AssemblyQualifiedName!;
6064
}
6165

62-
public FileStorageMetadata GetObject()
66+
public FileStorageMetadata? GetObject()
6367
{
6468
var type = Type.GetType(TypeName, true);
6569
return JsonSerializer.Deserialize(Value, type) as FileStorageMetadata;

0 commit comments

Comments
 (0)