Skip to content

Commit

Permalink
New APIs to get a list of input/output data plug-ins (#437)
Browse files Browse the repository at this point in the history
* gh-434 New APIs to get a list of input/output data plug-ins 
   New PluginAttribute to provide names for the plug-ins
* gh-434 Update documentation
* gh-434 Update documentation
* gh-434 Update CLI with aet plugins and dst plugins commands
* Add AttributeUsage to PluginNameAttribute
* Update user guide
* Fix typo in setup guide
* Add unit test for Plug-ins client


Signed-off-by: Victor Chang <vicchang@nvidia.com>
  • Loading branch information
mocsharp authored Aug 10, 2023
1 parent 0ff1963 commit f45656b
Show file tree
Hide file tree
Showing 33 changed files with 992 additions and 46 deletions.
72 changes: 71 additions & 1 deletion docs/api/rest/config.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--
~ Copyright 2021-2022 MONAI Consortium
~ Copyright 2021-2023 MONAI Consortium
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -285,6 +285,41 @@ curl --location --request DELETE 'http://localhost:5000/config/ae/breast-tumor'

---

## GET /config/ae/plug-ins

Returns a list of data input plug-ins that can be used with SCP Application Entity.

### Parameters

N/A

### Responses

Response Content Type: JSON - An object containing zero or more key-value pairs where the key is the name of the plug-in and the value is the fully qualified assembly type name of the plug-in.

| Code | Description |
| ---- | --------------------------------------------------------------------------------------------------------------------------------------- |
| 200 | Plug-ins retrieved successfully. |
| 500 | Server error. The response will be a [Problem details](https://datatracker.ietf.org/doc/html/rfc7807) object with server error details. |

### Example Request

```bash
curl --location --request GET 'http://localhost:5000/config/ae/plug-ins'
```

### Example Response

```json
{
"testInputDataPluginAddWorkflow": "Monai.Deploy.InformaticsGateway.Test.Plugins.TestInputDataPluginAddWorkflow, Monai.Deploy.InformaticsGateway.Test.Plugins, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"testInputDataPluginResumeWorkflow": "Monai.Deploy.InformaticsGateway.Test.Plugins.TestInputDataPluginResumeWorkflow, Monai.Deploy.InformaticsGateway.Test.Plugins, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"testInputDataPluginModifyDicomFile": "Monai.Deploy.InformaticsGateway.Test.Plugins.TestInputDataPluginModifyDicomFile, Monai.Deploy.InformaticsGateway.Test.Plugins, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
}
```

---

## GET /config/source

Returns a list of calling (source) AE Titles configured on the Informatics Gateway.
Expand Down Expand Up @@ -768,3 +803,38 @@ curl --location --request DELETE 'http://localhost:5000/config/destination/USEAS
"hostIp": "10.20.3.4"
}
```
---

## GET /config/destination/plug-ins

Returns a list of data output plug-ins that can be used with SCP Application Entity.

### Parameters

N/A

### Responses

Response Content Type: JSON - An object containing zero or more key-value pairs where the key is the name of the plug-in and the value is the fully qualified assembly type name of the plug-in.

| Code | Description |
| ---- | --------------------------------------------------------------------------------------------------------------------------------------- |
| 200 | Plug-ins retrieved successfully. |
| 500 | Server error. The response will be a [Problem details](https://datatracker.ietf.org/doc/html/rfc7807) object with server error details. |

### Example Request

```bash
curl --location --request GET 'http://localhost:5000/config/destination/plug-ins'
```

### Example Response

```json
{
"testOutputDataPluginAddMessage": "Monai.Deploy.InformaticsGateway.Test.Plugins.TestOutputDataPluginAddMessage, Monai.Deploy.InformaticsGateway.Test.Plugins, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"testOutputDataPluginModifyDicomFile": "Monai.Deploy.InformaticsGateway.Test.Plugins.TestOutputDataPluginModifyDicomFile, Monai.Deploy.InformaticsGateway.Test.Plugins, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
}
```

---
18 changes: 9 additions & 9 deletions docs/docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
"src": [
{
"files": [
"Api/bin/Release/net6.0/Monai.Deploy.InformaticsGateway.Api.dll",
"Client/bin/Release/net6.0/Monai.Deploy.InformaticsGateway.Client.dll",
"Client.Common/bin/Release/net6.0/Monai.Deploy.InformaticsGateway.Client.Common.dll",
"Common/bin/Release/net6.0/Monai.Deploy.InformaticsGateway.Common.dll",
"Configuration/bin/Release/net6.0/Monai.Deploy.InformaticsGateway.Configuration.dll",
"Database/bin/Release/net6.0/Monai.Deploy.InformaticsGateway.Database.dll",
"Database/Api/bin/Release/net6.0/Monai.Deploy.InformaticsGateway.Database.Api.dll",
"DicomWebClient/bin/Release/net6.0/Monai.Deploy.InformaticsGateway.DicomWeb.Client.dll"
"Api/Monai.Deploy.InformaticsGateway.Api.csproj",
"Client/Monai.Deploy.InformaticsGateway.Client.csproj",
"Client.Common/Monai.Deploy.InformaticsGateway.Client.Common.csproj",
"Common/Monai.Deploy.InformaticsGateway.Common.csproj",
"Configuration/Monai.Deploy.InformaticsGateway.Configuration.csproj",
"Database/Monai.Deploy.InformaticsGateway.Database.csproj",
"Database/Api/Monai.Deploy.InformaticsGateway.Database.Api.csproj",
"DicomWebClient/Monai.Deploy.InformaticsGateway.DicomWeb.Client.csproj"
],
"exclude": [
"**/obj/**",
Expand Down Expand Up @@ -61,7 +61,7 @@
"_enableSearch": true,
"_appFaviconPath": "images/favicon.ico",
"_appLogoPath": "images/MONAI-logo-color.svg",
"_appFooter": "Copyright © 2022 <a href=\"https://monai.io/\">Project MONAI</a><br>Generated by <strong>DocFX</strong>",
"_appFooter": "Copyright © 2022-2023 <a href=\"https://monai.io/\">Project MONAI</a><br>Generated by <strong>DocFX</strong>",
"_gitContribute": {
"repo": "https://github.com/Project-MONAI/monai-deploy-informatics-gateway.git",
"branch": "main",
Expand Down
6 changes: 3 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--
~ Copyright 2021-2022 MONAI Consortium
~ Copyright 2021-2023 MONAI Consortium
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -38,8 +38,8 @@ MIG contains the following standard protocols for communicating with medical dev
* **DICOMweb client**: QIDO-RS, WADO-RS, STOW-RS
* **FHIR client**: GET

[!Note]
The ACR DSI API uses the DICOMweb client and FHIR client.
> [!Note]
> The ACR DSI API uses the DICOMweb client and FHIR client.
### DICOM SCP

Expand Down
9 changes: 7 additions & 2 deletions docs/setup/cli.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--
~ Copyright 2021-2022 MONAI Consortium
~ Copyright 2021-2023 MONAI Consortium
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -127,8 +127,10 @@ Options:

Commands:
add Add a new SCP Application Entity
update Update a SCP Application Entities
del, rm Remove a SCP Application Entity
list, ls List all SCP Application Entities
plugins List all available plug-ins for SCP Application Entities
```

### Source AE Titles
Expand All @@ -148,6 +150,7 @@ Options:

Commands:
add Add a new DICOM source
update Update a new DICOM source
del, rm Remove a DICOM source
list, ls List all DICOM sources

Expand All @@ -170,7 +173,9 @@ Options:

Commands:
add Add a new DICOM destination
cecho C-ECHO a DICOM destination
update Update a new DICOM destination
del, rm Remove a DICOM destination
list, ls List all DICOM destinations
cecho C-ECHO a DICOM destination
plugins List all available plug-ins for DICOM destinations
```
53 changes: 50 additions & 3 deletions docs/setup/setup.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--
~ Copyright 2021-2022 MONAI Consortium
~ Copyright 2021-2023 MONAI Consortium
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
Expand All @@ -20,16 +20,30 @@ This section outlines the steps to download and install the Informatics Gateway
## Runtime Requirements

* Docker 20.10.12 or higher
* [Database service](#database-configuration)
* [Message Broker service](#message-broker)
* [Storage service](#storage-service)

For development requirements, refer to the [Informatics Gateway README.md](https://github.com/Project-MONAI/monai-deploy-informatics-gateway).

> [!Note]
> Use [MONAI Deploy Express](https://github.com/Project-MONAI/monai-deploy/tree/main/deploy/monai-deploy-express) to quickly
> bring up all required services, including the Informatics Gateway.
>
> Skip to [Configure Informatics Gateway](#configure-informatics-gateway) if you are using MONAI Deploy Express.


## Installation

### Informatics Gateway CLI

Download and install the Informatics Gateway CLI from the [Releases](https://github.com/Project-MONAI/monai-deploy-informatics-gateway/releases) section of
the repository and install it.

> [!Note]
> We use `v0.2.0` release as an example here, always download the latest from the [Releases](https://github.com/Project-MONAI/monai-deploy-informatics-gateway/releases) section.
#### On Linux

```bash
Expand Down Expand Up @@ -80,6 +94,9 @@ mig-cli.exe config init
mig-cli.exe config endpoint http://localhost:5000 #skip if running locally
```

> [!Note]
> For [MONAI Deploy Express](https://github.com/Project-MONAI/monai-deploy/tree/main/deploy/monai-deploy-express), use `http://localhost:5003`.
The first command extracts the default `appsettings.json` file into the home directory:

* Linux: `~/.mig/appsettings.json`
Expand Down Expand Up @@ -144,6 +161,27 @@ If the database system is supported by [Microsoft Entity Framework](https://lear
For other database systems that are not listed in the link above, simply implement the [Repository APIs](xref:Monai.Deploy.InformaticsGateway.Database.Api.Repositories), update the [Database Manager](xref:Monai.Deploy.InformaticsGateway.Database.DatabaseManager) to support the new database type and optionally, implement the [IDabaseMigrationManager](xref:Monai.Deploy.InformaticsGateway.Database.Api.IDatabaseMigrationManager).


## Authentication

Authentication is disabled by default. To enable authentication using OpenID, edit the `appsettings.json` file and set `bypassAuthentication` to `true`:

```json
{
"MonaiDeployAuthentication": {
"bypassAuthentication": true,
"openId": {
"realm": "{realm}",
"realmKey": "{realm-secret-key}",
"clientId": "{client-id}",
"audiences": [ "{audiences}" ],
"roleClaimType": "{roles}",
...
}
```

Refer to [Authentication Setup Using Keycloak](https://github.com/Project-MONAI/monai-deploy-workflow-manager/blob/develop/guidelines/mwm-auth.md) for additional details.


## Storage Consideration & Configuration

The Informatics Gateway operates on two storage locations. In the first location, the incoming data for data grouping is temporarily stored. In the second location, the Informatics Gateway uploads grouped datasets to final storage shared by other MONAI Deploy sub-systems.
Expand Down Expand Up @@ -314,7 +352,7 @@ will group instances by the Series Instance UID (0020,000E) with a timeout value

### Optional: Input Data Plug-ins

Each listening AE Title may be configured with zero or more plug-ins to maniulate incoming DICOM files before saving to the storage
Each listening AE Title may be configured with zero or more plug-ins to manipulate incoming DICOM files before saving to the storage
service and dispatching a workflow request. To include input data plug-ins, first create your plug-ins by implementing the
[IInputDataPlugin](xref:Monai.Deploy.InformaticsGateway.Api.IInputDataPlugin) interface and then use `-p` argument with the fully
qualified type name with the `mig-cli aet add` command. For example, the following command adds `MyNamespace.AnonymizePlugin`
Expand All @@ -327,7 +365,7 @@ mig-cli aet add -a BrainAET -grouping 0020,000E, -t 30 -p "MyNamespace.Anonymize
> [!Note]
> `-grouping` is optional, with a default value of 0020,000D.
> `-t` is optional, with a default value of 5 seconds.
> For complete reference, refer to the [Config API](../api/rest/config.md).
> For complete reference, refer to the [Configuration API](../api/rest/config.md).

2. Enable the receiving of DICOM instances from external DICOM devices:

Expand Down Expand Up @@ -358,3 +396,12 @@ The command adds a DICOM export destination with AE Title `WORKSTATION1` at IP `
## Logging

See [schema](./schema.md#logging) page for additional information on logging.

## Data Plug-ins

You may write your own data plug-ins to manipulate incoming data before they are saved to the storage service or outgoing data right before they are exported.

To write an input data plug-in, implement the [IInputDataPlugin](xref:Monai.Deploy.InformaticsGateway.Api.IInputDataPlugin) interface and put the [dynamic link library](https://learn.microsoft.com/en-us/troubleshoot/windows-client/deployment/dynamic-link-library) (DLL) in the
plug-ins directories. Similarly for output data plug-ins, implement the [IOutputDataPlugin](xref:Monai.Deploy.InformaticsGateway.Api.IOutputDataPlugin) interface.

Refer to [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.
34 changes: 34 additions & 0 deletions src/Api/PluginNameAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2023 MONAI Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using System;
using Ardalis.GuardClauses;

namespace Monai.Deploy.InformaticsGateway.Api
{
[AttributeUsage(AttributeTargets.Class)]
public class PluginNameAttribute : Attribute
{
public string Name { get; set; }

public PluginNameAttribute(string name)
{
Guard.Against.NullOrWhiteSpace(name, nameof(name));

Name = name;
}
}
}
4 changes: 2 additions & 2 deletions src/Api/Storage/DicomFileStorageMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021-2022 MONAI Consortium
* Copyright 2021-2023 MONAI Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -34,7 +34,7 @@ public sealed record DicomFileStorageMetadata : FileStorageMetadata
/// <summary>
/// The calling AE title of the DICOM instance.
/// For ACR, this is the Transaction ID of the original request.
/// Note: this value is same as <seealso cref="Source"></c>
/// Note: this value is same as <see cref="FileStorageMetadata.Source"/>
/// </summary>
[JsonIgnore]
public string CallingAeTitle { get => Source; }
Expand Down
4 changes: 2 additions & 2 deletions src/Api/Storage/FhirFileStorageMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021-2022 MONAI Consortium
* Copyright 2021-2023 MONAI Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -32,7 +32,7 @@ public sealed record FhirFileStorageMetadata : FileStorageMetadata

/// <summary>
/// The transaction ID of the original ACR request.
/// Note: this value is same as <seealso cref="Source"></c>
/// Note: this value is same as <see cref="FileStorageMetadata.Source"/>
/// </summary>
[JsonIgnore]
public string TransactionId { get => Source; }
Expand Down
Loading

0 comments on commit f45656b

Please sign in to comment.