|
| 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 | +``` |
0 commit comments