Skip to content

Commit 2eacbce

Browse files
authored
Merge pull request #429 from Project-MONAI/nds/#422
Nds/#422
2 parents b9a2c37 + 9ab118b commit 2eacbce

File tree

182 files changed

+6430
-733
lines changed

Some content is hidden

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

182 files changed

+6430
-733
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ jobs:
255255
timeout-minutes: 30
256256
strategy:
257257
matrix:
258-
feature: [AcrApi, DicomDimseScp, DicomDimseScu, DicomWebExport, DicomWebStow, HealthLevel7, Fhir]
258+
feature: [AcrApi, DicomDimseScp, DicomDimseScu, DicomWebExport, DicomWebStow, HealthLevel7, Fhir, RemoteAppExecutionPlugIn]
259259
database: [ef, mongodb]
260260
fail-fast: false
261261
env:

.licenserc.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ header:
3131
- 'src/coverlet.runsettings'
3232
- 'src/Monai.Deploy.InformaticsGateway.sln'
3333
- 'src/Database/EntityFramework/Migrations/**'
34+
- 'src/Plug-ins/RemoteAppExecution/Migrations/**'
3435
- 'demos/**/.env/**'
3536
- 'demos/**/*.txt'
3637
- 'doc/dependency_decisions.yml'

doc/dependency_decisions.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@
868868
- - :approve
869869
- Polly
870870
- :who: mocsharp
871-
:why: New BSD License (https://github.com/App-vNext/Polly/raw/main/LICENSE.txt)
871+
:why: New BSD License (https://raw.githubusercontent.com/App-vNext/Polly/main/LICENSE)
872872
:versions:
873873
- 7.2.4
874874
:when: 2022-08-16 23:06:27.913122244 Z
@@ -2324,28 +2324,28 @@
23242324
- - :approve
23252325
- MongoDB.Bson
23262326
- :who: mocsharp
2327-
:why: Apache-2.0 (https://github.com/mongodb/mongo-csharp-driver/raw/master/License.txt)
2327+
:why: Apache-2.0 (https://raw.githubusercontent.com/mongodb/mongo-csharp-driver/master/LICENSE.md)
23282328
:versions:
23292329
- 2.21.0
23302330
:when: 2022-11-16 23:38:53.891380809 Z
23312331
- - :approve
23322332
- MongoDB.Driver
23332333
- :who: mocsharp
2334-
:why: Apache-2.0 (https://github.com/mongodb/mongo-csharp-driver/raw/master/License.txt)
2334+
:why: Apache-2.0 (https://raw.githubusercontent.com/mongodb/mongo-csharp-driver/master/LICENSE.md)
23352335
:versions:
23362336
- 2.21.0
23372337
:when: 2022-11-16 23:38:54.213853364 Z
23382338
- - :approve
23392339
- MongoDB.Driver.Core
23402340
- :who: mocsharp
2341-
:why: Apache-2.0 (https://github.com/mongodb/mongo-csharp-driver/raw/master/License.txt)
2341+
:why: Apache-2.0 (https://raw.githubusercontent.com/mongodb/mongo-csharp-driver/master/LICENSE.md)
23422342
:versions:
23432343
- 2.21.0
23442344
:when: 2022-11-16 23:38:54.553730219 Z
23452345
- - :approve
23462346
- MongoDB.Libmongocrypt
23472347
- :who: mocsharp
2348-
:why: Apache-2.0 (https://github.com/mongodb/mongo-csharp-driver/raw/master/License.txt)
2348+
:why: Apache-2.0 (https://raw.githubusercontent.com/mongodb/mongo-csharp-driver/master/LICENSE.md)
23492349
:versions:
23502350
- 1.8.0
23512351
:when: 2022-11-16 23:38:54.863359236 Z

docs/changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
- gh-435 Fix CLI to read log dir path from NLog config file.
2525
- New Virtual Application Entity support for DICOMWeb STOW-RS APIs to enable dynamic endpoints.
26+
- New data [plug-ins](./plug-ins/overview.md) feature to manipulate incoming outgoing data.
2627

2728

2829
## 0.3.21

docs/compliance/third-party-licenses.md

-1
Original file line numberDiff line numberDiff line change
@@ -41669,4 +41669,3 @@ Data pulled from spdx/license-list-data on February 9, 2023.
4166941669
```
4167041670

4167141671
</details>
41672-

docs/plug-ins/overview.md

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<!--
2+
~ Copyright 2023 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+
# Data Plug-ins
18+
19+
Data plug-ins enable manipulation of incoming data before they are saved to the storage service or outgoing data right before they are exported.
20+
21+
## Using Data Plug-ins
22+
23+
The Informatics Gateway allows you to configure data plug-ins in the following services:
24+
25+
- (DIMSE) MONAI Deploy DICOM Listener: configure each listening AE Title with zero or more data plug-ins via the [CLI](../setup/cli.md) or via the [Configuration API](../api/rest/config.md).
26+
- (DIMSE) DICOM Export: configure the `PluginAssemblies` with one or more data plug-ins in the [ExportRequestEvent](https://github.com/Project-MONAI/monai-deploy-messaging/blob/main/src/Messaging/Events/ExportRequestEvent.cs#L85).
27+
- (DICOMWeb) STOW-RS:
28+
- The Virtual AE endpoints (`/dicomweb/vae/...`) can be configured similarly to the DICOM listener by using the [DICOMWeb STOW API](../api/rest/dicomweb-stow.md##post-dicomwebvaeaetworkflow-idstudiesstudy-instance-uid).
29+
- For the default `/dicomweb/...` endpoints, set zero or more plug-ins under `InformaticsGateway>dicomWeb>plug-ins` in the `appsettings.json` [configuration](../setup/schema.md) file.
30+
- (DICOMWeb) Export: configure the `PluginAssemblies` with one or more data plug-ins in the [ExportRequestEvent](https://github.com/Project-MONAI/monai-deploy-messaging/blob/main/src/Messaging/Events/ExportRequestEvent.cs#L85).
31+
32+
> [!Note]
33+
> When one or more plug-ins are defined, the plug-ins are executed in the order as they are listed.
34+
35+
## Available Plug-ins
36+
37+
The following plug-ins are available:
38+
39+
| Name | Description | Fully Qualified Assembly Name |
40+
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
41+
| [DicomDeidentifier](./remote-app.md) | A plug-in that de-identifies a set of configurable DICOM tags with random data before DICOM data is exported. | `Monai.Deploy.InformaticsGateway.PlugIns.RemoteAppExecution.DicomDeidentifier, Monai.Deploy.InformaticsGateway.PlugIns.RemoteAppExecution` |
42+
| [DicomReidentifier](./remote-app.md) | A plug-in to be used together with the `DicomDeidentifier` plug-in to restore the original DICOM metadata. | `Monai.Deploy.InformaticsGateway.PlugIns.RemoteAppExecution.DicomReidentifier, Monai.Deploy.InformaticsGateway.PlugIns.RemoteAppExecution` |
43+
44+
45+
## Writing Your Plug-ins
46+
47+
To write an input data plug-in, implement the [IInputDataPlugin](xref:Monai.Deploy.InformaticsGateway.Api.PlugIns.IInputDataPlugIn) interface and
48+
put the [dynamic link library](https://learn.microsoft.com/en-us/troubleshoot/windows-client/deployment/dynamic-link-library) (DLL) in
49+
the `plug-ins/` directories. Similarly, for output data plug-ins, implement the [IOutputDataPlugin](xref:Monai.Deploy.InformaticsGateway.Api.PlugIns.IOutputDataPlugIn) interface.
50+
51+
Refer to the [Configuration API](../api/rest/config.md) page to retrieve available [input](../api/rest/config.md#get-configaeplug-ins) and [output](../api/rest/config.md#get-configdestinationplug-ins) data plug-ins.
52+
53+
54+
### Database Extensions
55+
56+
If a plug-in requires to persist data to the database, extend the [DatabaseRegistrationBase](xref:Monai.Deploy.InformaticsGateway.Database.Api.DatabaseRegistrationBase) class to register your database context and repositories.
57+
58+
Refer to the _Monai.Deploy.InformaticsGateway.PlugIns.RemoteAppExecution_ plug-in as a reference.
59+
60+
> [!Important]
61+
> The Informatics Gateway requires all plug-ins to extend both Entity Framework (sqlite) and MongoDB databases.
62+
63+
#### Entity Framework
64+
65+
Implement the [IDatabaseMigrationManagerForPlugIns](xref:Monai.Deploy.InformaticsGateway.Database.Api.IDatabaseMigrationManagerForPlugIns) interface to register your Entity Framework (EF) database context. A `connectionString` is provided to the `Configure(...)`
66+
function when you extend the [DatabaseRegistrationBase](xref:Monai.Deploy.InformaticsGateway.Database.Api.DatabaseRegistrationBase) class and allows you to create your [code-first](https://learn.microsoft.com/en-us/ef/ef6/modeling/code-first/workflows/new-database)
67+
EF database context and generate your migration code using [dotnet ef](https://learn.microsoft.com/en-us/ef/core/cli/dotnet) CLI tool.
68+
69+
In the following example, we extend [DatabaseRegistrationBase](xref:Monai.Deploy.InformaticsGateway.Database.Api.DatabaseRegistrationBase) class to register a new EF database context named `RemoteAppExecutionDbContext`.
70+
71+
In the method, we first register the database context, then register our Migration Manager by implementing the [IDatabaseMigrationManagerForPlugIns](xref:Monai.Deploy.InformaticsGateway.Database.Api.IDatabaseMigrationManagerForPlugIns) interface.
72+
Lastly, we register our repository for the `RemoteAppExecutions` table.
73+
74+
```csharp
75+
public class DatabaseRegistrar : DatabaseRegistrationBase
76+
{
77+
public override IServiceCollection Configure(IServiceCollection services, DatabaseType databaseType, string? connectionString)
78+
{
79+
Guard.Against.Null(services, nameof(services));
80+
81+
switch (databaseType)
82+
{
83+
case DatabaseType.EntityFramework:
84+
Guard.Against.Null(connectionString, nameof(connectionString));
85+
services.AddDbContext<EntityFramework.RemoteAppExecutionDbContext>(options => options.UseSqlite(connectionString), ServiceLifetime.Transient);
86+
services.AddScoped<IDatabaseMigrationManagerForPlugIns, EntityFramework.MigrationManager>();
87+
88+
services.AddScoped(typeof(IRemoteAppExecutionRepository), typeof(EntityFramework.RemoteAppExecutionRepository));
89+
break;
90+
...
91+
}
92+
93+
return services;
94+
}
95+
}
96+
```
97+
98+
#### MongoDB
99+
100+
Similar to the [Entity Framework](#entity-framework) section above, For MongoDB, we first register our Migration Manager by implementing the [IDatabaseMigrationManagerForPlugIns](xref:Monai.Deploy.InformaticsGateway.Database.Api.IDatabaseMigrationManagerForPlugIns) interface,
101+
and then we register our repository for the `RemoteAppExecutions` collection.
102+
103+
```csharp
104+
public class DatabaseRegistrar : DatabaseRegistrationBase
105+
{
106+
public override IServiceCollection Configure(IServiceCollection services, DatabaseType databaseType, string? connectionString)
107+
{
108+
Guard.Against.Null(services, nameof(services));
109+
110+
switch (databaseType)
111+
{
112+
case DatabaseType.MongoDb:
113+
services.AddScoped<IDatabaseMigrationManagerForPlugIns, MongoDb.MigrationManager>();
114+
115+
services.AddScoped(typeof(IRemoteAppExecutionRepository), typeof(MongoDb.RemoteAppExecutionRepository));
116+
break;
117+
...
118+
}
119+
120+
return services;
121+
}
122+
}
123+
```
124+
125+
In the `MigrationManager`, we configure the `RemoteAppExecutions` collection.
126+
127+
```csharp
128+
public class MigrationManager : IDatabaseMigrationManagerForPlugIns
129+
{
130+
public IHost Migrate(IHost host)
131+
{
132+
RemoteAppExecutionConfiguration.Configure();
133+
return host;
134+
}
135+
}
136+
```

docs/plug-ins/remote-app.md

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!--
2+
~ Copyright 2023 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+
# Remote App Execution Plug-ins
18+
19+
The **Remote App Execution Plug-ins** allow the users to configure a set of DICOM metadata to be replaced with dummy data before
20+
being exported using the `DicomDeidentifier` plug-in. The original data is stored in the database so when the data returns
21+
via DICOM DIMSE or DICOMWeb, the data can be restored using the `DicomReidentifier` plug-in.
22+
23+
## Supported Data Types
24+
25+
- DICOM
26+
27+
## Configuration
28+
29+
One or more DICOM tags may be configured in the `appsettings.json` file. For example, the following snippet will replace
30+
`AccessionNumber`, `StudyDescription`, and `SeriesDescription`.
31+
32+
```json
33+
{
34+
"InformaticsGateway": {
35+
"plugins": {
36+
"remoteApp": {
37+
"ReplaceTags": "AccessionNumber, StudyDescription, SeriesDescription"
38+
}
39+
}
40+
}
41+
}
42+
```
43+
44+
Refer to [NEMA](https://dicom.nema.org/medical/dicom/current/output/chtml/part06/chapter_6.html) for a complete list of DICOM tags
45+
and use the value from the **Keyword** column.
46+
47+
> [!Note]
48+
> `StudyInstanceUID`, `SeriesInstanceUID` and `SOPInstanceUID` are always replaced and tracked to ensure the same
49+
> studies and series get the same UIDs.
50+
51+
> [!Important]
52+
> Only top-level DICOM metadata can be replaced at this time.
53+
54+
## Fully Qualified Assembly Names
55+
56+
The following plug-ins are available:
57+
58+
| Name | Fully Qualified Assembly Name |
59+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
60+
| `DicomDeidentifier` | `Monai.Deploy.InformaticsGateway.PlugIns.RemoteAppExecution.DicomDeidentifier, Monai.Deploy.InformaticsGateway.PlugIns.RemoteAppExecution` |
61+
| `DicomReidentifier` | `Monai.Deploy.InformaticsGateway.PlugIns.RemoteAppExecution.DicomReidentifier, Monai.Deploy.InformaticsGateway.PlugIns.RemoteAppExecution` |

docs/plug-ins/toc.yml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright 2021-2022 MONAI Consortium
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
- name: Data Plug-ins
16+
href: overview.md
17+
- name: Remote App Execution Plug-ins
18+
href: remote-app.md

0 commit comments

Comments
 (0)