From ae8d8c2ce108d9eadad506f5f57f2cc36dcba6b1 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Mon, 6 Jul 2020 16:15:11 +0100 Subject: [PATCH 01/28] * Fix most LGTM warnings --- Rdmp.Dicom.UI/CreateNewImagingDatasetUI.cs | 55 ++++++++++--------- Rdmp.Dicom.UI/TagElevationXmlUI.cs | 2 +- .../Pipeline/Dicom/DicomRequestSender.cs | 2 +- .../Pipeline/Ordering/HierarchyBasedOrder.cs | 5 +- ...cuteCommandCreateNewImagingDatasetSuite.cs | 8 ++- Rdmp.Dicom/Extraction/MappingRepository.cs | 48 ++++++++-------- .../DicomSources/DicomFileCollectionSource.cs | 2 +- .../TagPromotionSchema/TagColumnAdder.cs | 2 +- 8 files changed, 65 insertions(+), 59 deletions(-) diff --git a/Rdmp.Dicom.UI/CreateNewImagingDatasetUI.cs b/Rdmp.Dicom.UI/CreateNewImagingDatasetUI.cs index 3944fedd..bec0968b 100644 --- a/Rdmp.Dicom.UI/CreateNewImagingDatasetUI.cs +++ b/Rdmp.Dicom.UI/CreateNewImagingDatasetUI.cs @@ -51,23 +51,26 @@ private bool CreateDatabaseIfNotExists(DiscoveredDatabase db) private void btnCreateSuiteWithTemplate_Click(object sender, EventArgs e) { - OpenFileDialog ofd = new OpenFileDialog(); - ofd.Filter = "Imaging Template|*.it"; + string filename; + using (OpenFileDialog ofd = new OpenFileDialog() + { + Filter = "Imaging Template|*.it" + }) + { + if (ofd.ShowDialog() != DialogResult.OK) + return; + filename = ofd.FileName; + } - if (ofd.ShowDialog() == DialogResult.OK) + try + { + var yaml = File.ReadAllText(filename); + var template = ImageTableTemplateCollection.LoadFrom(yaml); + CreateSuite(template); + } + catch (Exception exception) { - try - { - var yaml = File.ReadAllText(ofd.FileName); - - var template = ImageTableTemplateCollection.LoadFrom(yaml); - - CreateSuite(template); - } - catch (Exception exception) - { - ExceptionViewer.Show(exception); - } + ExceptionViewer.Show(exception); } } @@ -78,17 +81,19 @@ private void CreateSuite(ImageTableTemplateCollection template) if (!CreateDatabaseIfNotExists(db)) return; - - FolderBrowserDialog dialog = new FolderBrowserDialog(); - DirectoryInfo dir = null; - dialog.Description = "Select Project Directory (For Sql scripts/Executables etc)"; - //if we are creating a load we need to know where to store load scripts etc - if(cbCreateLoad.Checked) - if (dialog.ShowDialog() == DialogResult.OK) - dir = new DirectoryInfo(dialog.SelectedPath); - else - return; + DirectoryInfo dir = null; + using (FolderBrowserDialog dialog = new FolderBrowserDialog() { + Description = "Select Project Directory (For Sql scripts/Executables etc)" + }) + { + //if we are creating a load we need to know where to store load scripts etc + if (cbCreateLoad.Checked) + if (dialog.ShowDialog() == DialogResult.OK) + dir = new DirectoryInfo(dialog.SelectedPath); + else + return; + } var cmd = new ExecuteCommandCreateNewImagingDatasetSuite(_activator.RepositoryLocator, db,dir); cmd.DicomSourceType = rbJsonSources.Checked ? typeof(DicomDatasetCollectionSource) : typeof(DicomFileCollectionSource); diff --git a/Rdmp.Dicom.UI/TagElevationXmlUI.cs b/Rdmp.Dicom.UI/TagElevationXmlUI.cs index c1d7dbc8..78dc168e 100644 --- a/Rdmp.Dicom.UI/TagElevationXmlUI.cs +++ b/Rdmp.Dicom.UI/TagElevationXmlUI.cs @@ -84,7 +84,7 @@ private void RunChecks() try { - var collection = new TagElevationRequestCollection(queryEditor.Text); + new TagElevationRequestCollection(queryEditor.Text); RagSmiley1.OnCheckPerformed(new CheckEventArgs("Succesfully created elevator",CheckResult.Success)); } catch(Exception ex) diff --git a/Rdmp.Dicom/Cache/Pipeline/Dicom/DicomRequestSender.cs b/Rdmp.Dicom/Cache/Pipeline/Dicom/DicomRequestSender.cs index 13a96f96..5330efa4 100644 --- a/Rdmp.Dicom/Cache/Pipeline/Dicom/DicomRequestSender.cs +++ b/Rdmp.Dicom/Cache/Pipeline/Dicom/DicomRequestSender.cs @@ -70,7 +70,7 @@ public void ThrottleRequest(DicomClient client, CancellationToken cancellationTo SendRequest(client,cancellationToken); transferTimer.Stop(); //valuein mills - var delay = ((int)(_dicomConfiguration.RequestDelayFactor * (1000 * transferTimer.Elapsed.Seconds)) + _dicomConfiguration.RequestCooldownInMilliseconds); + var delay = ((int)(_dicomConfiguration.RequestDelayFactor * (1000f * transferTimer.Elapsed.Seconds)) + _dicomConfiguration.RequestCooldownInMilliseconds); if (delay > 0) { _listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Requests sleeping for " + delay / 1000 + "seconds")); diff --git a/Rdmp.Dicom/Cache/Pipeline/Ordering/HierarchyBasedOrder.cs b/Rdmp.Dicom/Cache/Pipeline/Ordering/HierarchyBasedOrder.cs index af521321..6b0d562e 100644 --- a/Rdmp.Dicom/Cache/Pipeline/Ordering/HierarchyBasedOrder.cs +++ b/Rdmp.Dicom/Cache/Pipeline/Ordering/HierarchyBasedOrder.cs @@ -397,10 +397,7 @@ public int Total() { foreach (var series in study.Series.Values) { - foreach (var image in series.Images.Values) - { - count++; - } + count += series.Images.Values.Count; } } } diff --git a/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs b/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs index 31db50ba..aaf36fbc 100644 --- a/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs +++ b/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs @@ -113,9 +113,11 @@ bool createLoad public override void Execute() { if (DicomSourceType == null) + { SetImpossible("You must specify a Type for DicomSourceType"); + return; + } - base.Execute(); List tablesCreated = new List(); @@ -261,9 +263,9 @@ private void SetArgument(IArgument[] args, string property, object value) var arg = args.Single(a => a.Name.Equals(property)); var mef = ((CatalogueRepository) arg.Repository).MEF; - var found = mef.GetType(value.GetType().FullName); + mef.GetType(value.GetType().FullName); - //if this fails, look to see if found is null (indicates that your Type is not loaded by MEF). Look at mef.DescribeBadAssembliesIfAny() to investigate this issue + //if this fails, look to see if GetType returned null (indicates that your Type is not loaded by MEF). Look at mef.DescribeBadAssembliesIfAny() to investigate this issue arg.SetValue(value); arg.SaveToDatabase(); } diff --git a/Rdmp.Dicom/Extraction/MappingRepository.cs b/Rdmp.Dicom/Extraction/MappingRepository.cs index ae29b662..acdc3999 100644 --- a/Rdmp.Dicom/Extraction/MappingRepository.cs +++ b/Rdmp.Dicom/Extraction/MappingRepository.cs @@ -98,32 +98,34 @@ public void InsertMappings(UIDMapping[] newMappings) var table = _database.ExpectTable(_tableName); // Create data table - var dt = new DataTable(_tableName); - using (var conn = (SqlConnection) _server.GetConnection()) + using (var dt = new DataTable(_tableName)) { - conn.Open(); - var da = new SqlDataAdapter(table.GetTopXSql(0), conn); - da.Fill(dt); - } + using (var conn = (SqlConnection)_server.GetConnection()) + { + conn.Open(); + using (var da = new SqlDataAdapter(table.GetTopXSql(0), conn)) + da.Fill(dt); + } - // Fill up the data table - foreach (var mapping in newMappings) - { - var row = dt.NewRow(); - row["PrivateUID"] = mapping.PrivateUID; - row["ReleaseUID"] = mapping.ReleaseUID; - row["ProjectNumber"] = mapping.ProjectNumber; - row["UIDType"] = mapping.UIDType; - row["IsExternalReference"] = mapping.IsExternalReference; - dt.Rows.Add(row); - } + // Fill up the data table + foreach (var mapping in newMappings) + { + var row = dt.NewRow(); + row["PrivateUID"] = mapping.PrivateUID; + row["ReleaseUID"] = mapping.ReleaseUID; + row["ProjectNumber"] = mapping.ProjectNumber; + row["UIDType"] = mapping.UIDType; + row["IsExternalReference"] = mapping.IsExternalReference; + dt.Rows.Add(row); + } - // Perform the bulk copy - using (var conn = (SqlConnection) _server.GetConnection()) - { - conn.Open(); - using (var bulkCopy = table.BeginBulkInsert()) - bulkCopy.Upload(dt); + // Perform the bulk copy + using (var conn = (SqlConnection)_server.GetConnection()) + { + conn.Open(); + using (var bulkCopy = table.BeginBulkInsert()) + bulkCopy.Upload(dt); + } } } diff --git a/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs b/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs index a2e5c7af..d82c8488 100644 --- a/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs +++ b/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs @@ -76,7 +76,7 @@ public override DataTable GetChunk(IDataLoadEventListener listener, GracefulCanc ProcessDirectoryAsync(dt, directory, listener); Task.WaitAll(tasks.ToArray()); } - else + else if (file != null) //Input is a single zip file if (file.FullPath.EndsWith(".zip")) { diff --git a/Rdmp.Dicom/TagPromotionSchema/TagColumnAdder.cs b/Rdmp.Dicom/TagPromotionSchema/TagColumnAdder.cs index 8ee231e0..7f7ef240 100644 --- a/Rdmp.Dicom/TagPromotionSchema/TagColumnAdder.cs +++ b/Rdmp.Dicom/TagPromotionSchema/TagColumnAdder.cs @@ -82,7 +82,7 @@ public void Check(ICheckNotifier notifier) var db = GetDatabase(); try { - var cSharpType = db.Server.GetQuerySyntaxHelper().TypeTranslater.GetCSharpTypeForSQLDBType(_datatype); + db.Server.GetQuerySyntaxHelper().TypeTranslater.GetCSharpTypeForSQLDBType(_datatype); notifier.OnCheckPerformed(new CheckEventArgs("Datatype is compatible with TypeTranslater",CheckResult.Success)); } catch (Exception ex) From 6f142bcf69f0d30caae018f96938bbc4b1ca9e48 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2020 09:44:44 +0100 Subject: [PATCH 02/28] Bump HIC.RDMP.Plugin from 4.1.4 to 4.1.5 (#43) * Bump HIC.RDMP.Plugin from 4.1.4 to 4.1.5 --- Packages.md | 2 +- Rdmp.Dicom.Library.nuspec | 2 +- Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs | 3 +-- Rdmp.Dicom/Rdmp.Dicom.csproj | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Packages.md b/Packages.md index 916ed39f..8c732502 100644 --- a/Packages.md +++ b/Packages.md @@ -10,4 +10,4 @@ | Package | Source Code | Version | License | Purpose | Additional Risk Assessment | | ------- | ------------| --------| ------- | ------- | -------------------------- | | HIC.DicomTypeTranslation | [GitHub](https://github.com/HicServices/DicomTypeTranslation) | [2.3.0](https://www.nuget.org/packages/HIC.DicomTypeTranslation/2.3.0) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Translate dicom types into C# / database types | | -| HIC.RDMP.Plugin | [GitHub](https://github.com/HicServices/RDMP) | [4.1.4](https://www.nuget.org/packages/HIC.RDMP.Plugin/4.1.4) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Interact with RDMP objects, base classes for plugin components etc | | +| HIC.RDMP.Plugin | [GitHub](https://github.com/HicServices/RDMP) | [4.1.5](https://www.nuget.org/packages/HIC.RDMP.Plugin/4.1.5) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Interact with RDMP objects, base classes for plugin components etc | | diff --git a/Rdmp.Dicom.Library.nuspec b/Rdmp.Dicom.Library.nuspec index 00a39d1a..2bfae677 100644 --- a/Rdmp.Dicom.Library.nuspec +++ b/Rdmp.Dicom.Library.nuspec @@ -14,7 +14,7 @@ Copyright 2018-2019 - + diff --git a/Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs b/Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs index d31036bd..375b21e6 100644 --- a/Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs +++ b/Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Text.RegularExpressions; using FAnsi.Implementations.MySql; -using MySql.Data.MySqlClient; using Rdmp.Core.Curation.Data; using Rdmp.Core.Curation.Data.DataLoad; using Rdmp.Core.Curation.Data.Pipelines; @@ -173,7 +172,7 @@ public DataTable ProcessPipelineData(DataTable toProcess, IDataLoadEventListener { //todo: This really shouldn't be needed surely - MySqlConnection.ClearAllPools(); + MySql.Data.MySqlClient.MySqlConnection.ClearAllPools(); MySqlBulkCopy.BulkInsertBatchTimeoutInSeconds = int.MaxValue; //forever _sw.Start(); diff --git a/Rdmp.Dicom/Rdmp.Dicom.csproj b/Rdmp.Dicom/Rdmp.Dicom.csproj index e9a44202..f1491275 100644 --- a/Rdmp.Dicom/Rdmp.Dicom.csproj +++ b/Rdmp.Dicom/Rdmp.Dicom.csproj @@ -26,6 +26,6 @@ - + From daf50cdc50e86ab210925c4261e2c302d0eb38bf Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Thu, 16 Jul 2020 10:33:26 +0100 Subject: [PATCH 03/28] Adjust LGTM fixes per TN feedback --- ...cuteCommandCreateNewImagingDatasetSuite.cs | 8 +++- .../DicomSources/DicomFileCollectionSource.cs | 41 ++++++++++--------- .../TagPromotionSchema/TagColumnAdder.cs | 4 +- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs b/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs index aaf36fbc..7f92850d 100644 --- a/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs +++ b/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs @@ -115,7 +115,7 @@ public override void Execute() if (DicomSourceType == null) { SetImpossible("You must specify a Type for DicomSourceType"); - return; + throw new ImpossibleCommandException(this, ReasonCommandImpossible); } base.Execute(); @@ -260,10 +260,14 @@ private string GetNameWithPrefix(string name) private void SetArgument(IArgument[] args, string property, object value) { + if (value == null) + throw new ArgumentException(); + var arg = args.Single(a => a.Name.Equals(property)); var mef = ((CatalogueRepository) arg.Repository).MEF; - mef.GetType(value.GetType().FullName); + if (mef.GetType(value.GetType().FullName) == null) + throw new ArgumentException($"No type found for { value.GetType().FullName }"); //if this fails, look to see if GetType returned null (indicates that your Type is not loaded by MEF). Look at mef.DescribeBadAssembliesIfAny() to investigate this issue arg.SetValue(value); diff --git a/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs b/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs index d82c8488..39b2a907 100644 --- a/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs +++ b/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs @@ -64,30 +64,33 @@ public override DataTable GetChunk(IDataLoadEventListener listener, GracefulCanc if (!_fileWorklist.GetNextFileOrDirectoryToProcess(out directory, out file)) return null; - if(file != null && directory == null) - dt.TableName = QuerySyntaxHelper.MakeHeaderNameSensible(Path.GetFileNameWithoutExtension(file.FullPath)); - else if (directory != null) - dt.TableName = QuerySyntaxHelper.MakeHeaderNameSensible(Path.GetFileNameWithoutExtension(directory.Name)); - else + // Exactly one of file/directory must be null: + if ((file!=null) != (directory!=null)) throw new Exception("Expected IDicomProcessListProvider to return either a DirectoryInfo or a FileInfo not both/neither"); - - if(directory != null) - { - ProcessDirectoryAsync(dt, directory, listener); - Task.WaitAll(tasks.ToArray()); - } - else if (file != null) - //Input is a single zip file - if (file.FullPath.EndsWith(".zip")) + + if (file != null) { - ProcessZipArchive(dt, listener, file.FullPath); + dt.TableName = QuerySyntaxHelper.MakeHeaderNameSensible(Path.GetFileNameWithoutExtension(file.FullPath)); + if (file.FullPath.EndsWith(".zip")) + { + //Input is a single zip file + ProcessZipArchive(dt, listener, file.FullPath); + } + else + { + var df = file.GetDataset(_zipPool); + ProcessDataset(file.FullPath, df.Dataset, dt, listener); + } } - else + + if (directory!=null) { - var df = file.GetDataset(_zipPool); - ProcessDataset(file.FullPath, df.Dataset, dt, listener); + // Processing a directory + dt.TableName = QuerySyntaxHelper.MakeHeaderNameSensible(Path.GetFileNameWithoutExtension(directory.Name)); + ProcessDirectoryAsync(dt, directory, listener); + Task.WaitAll(tasks.ToArray()); } - + } finally { diff --git a/Rdmp.Dicom/TagPromotionSchema/TagColumnAdder.cs b/Rdmp.Dicom/TagPromotionSchema/TagColumnAdder.cs index 7f7ef240..b5563482 100644 --- a/Rdmp.Dicom/TagPromotionSchema/TagColumnAdder.cs +++ b/Rdmp.Dicom/TagPromotionSchema/TagColumnAdder.cs @@ -82,8 +82,8 @@ public void Check(ICheckNotifier notifier) var db = GetDatabase(); try { - db.Server.GetQuerySyntaxHelper().TypeTranslater.GetCSharpTypeForSQLDBType(_datatype); - notifier.OnCheckPerformed(new CheckEventArgs("Datatype is compatible with TypeTranslater",CheckResult.Success)); + var cSharpType = db.Server.GetQuerySyntaxHelper().TypeTranslater.GetCSharpTypeForSQLDBType(_datatype); + notifier.OnCheckPerformed(new CheckEventArgs($"Datatype { _datatype } is compatible with TypeTranslater as { cSharpType }",CheckResult.Success)); } catch (Exception ex) { From 1a0503cb45fa1488a1a18b44639fb05d00a2f730 Mon Sep 17 00:00:00 2001 From: Thomas Nind Date: Thu, 16 Jul 2020 10:40:56 +0100 Subject: [PATCH 04/28] fixed Exception Type --- .../ExecuteCommandCreateNewImagingDatasetSuite.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs b/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs index 7f92850d..4f811faf 100644 --- a/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs +++ b/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs @@ -261,7 +261,7 @@ private string GetNameWithPrefix(string name) private void SetArgument(IArgument[] args, string property, object value) { if (value == null) - throw new ArgumentException(); + throw new ArgumentNullException(nameof(value)); var arg = args.Single(a => a.Name.Equals(property)); From 5bfab8fd780b002f8707738bb286940d623e99c9 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Thu, 16 Jul 2020 10:51:44 +0100 Subject: [PATCH 05/28] Fix XOR logic in DicomFileCollectionSource.cs --- .../DicomSources/DicomFileCollectionSource.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs b/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs index 39b2a907..3ff63eba 100644 --- a/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs +++ b/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs @@ -65,7 +65,7 @@ public override DataTable GetChunk(IDataLoadEventListener listener, GracefulCanc return null; // Exactly one of file/directory must be null: - if ((file!=null) != (directory!=null)) + if ((file!=null) == (directory!=null)) throw new Exception("Expected IDicomProcessListProvider to return either a DirectoryInfo or a FileInfo not both/neither"); if (file != null) From e3fe8657ca7193b93398a342e719859e46aa35c6 Mon Sep 17 00:00:00 2001 From: tznind Date: Wed, 22 Jul 2020 09:29:33 +0100 Subject: [PATCH 06/28] Added source that calls a process --- .../Cache/Pipeline/ProcessBasedCacheSource.cs | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs diff --git a/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs b/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs new file mode 100644 index 00000000..40cc8e12 --- /dev/null +++ b/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs @@ -0,0 +1,91 @@ +using Rdmp.Core.Caching.Pipeline.Sources; +using Rdmp.Core.Caching.Requests; +using Rdmp.Core.Curation; +using Rdmp.Core.Curation.Data; +using Rdmp.Core.DataFlowPipeline; +using ReusableLibraryCode.Checks; +using ReusableLibraryCode.Progress; +using System; +using System.Diagnostics; + +namespace Rdmp.Dicom.Cache.Pipeline +{ + public class ProcessBasedCacheSource : CacheSource + { + [DemandsInitialization(@"Process to start. Template with +%s start time +%e end time time to fetch +%d directory to put files fetched +Example:. './GetImages.exe ""%s"" ""%e%""'",Mandatory = true)] + public string Command {get;set;} + + [DemandsInitialization("The datetime format for %s and %e.",Mandatory = true,DefaultValue = "yyyy-MM-dd HH:mm:ss")] + public string TimeFormat {get;set;} + + [DemandsInitialization("True to throw an Exception if the process run returns a nonzero exit code", DefaultValue = true)] + public bool ThrowOnNonZeroExitCode {get;set;} + + public override void Abort(IDataLoadEventListener listener) + { + + } + + public override void Check(ICheckNotifier notifier) + { + + } + + public override void Dispose(IDataLoadEventListener listener, Exception pipelineFailureExceptionIfAny) + { + + } + + public override SMIDataChunk DoGetChunk(ICacheFetchRequest request, IDataLoadEventListener listener, GracefulCancellationToken cancellationToken) + { + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,$"ProcessBasedCacheSource version is {typeof(ProcessBasedCacheSource).Assembly.GetName().Version}. Assembly is {typeof(ProcessBasedCacheSource).Assembly} " )); + + // Where we are putting the files + var cacheDir = new LoadDirectory(Request.CacheProgress.LoadProgress.LoadMetadata.LocationOfFlatFiles).Cache; + var cacheLayout = new SMICacheLayout(cacheDir, new SMICachePathResolver("ALL")); + + Chunk = new SMIDataChunk(Request) + { + FetchDate = Request.Start, + Modality = "ALL", + Layout = cacheLayout + }; + + var workingDirectory = cacheLayout.GetLoadCacheDirectory(listener); + + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Working directory is:" + workingDirectory)); + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Fetch Start is:" + request.Start)); + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Fetch End is:" + request.End)); + + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Command template is:" + Command)); + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Datetime format is:" + TimeFormat)); + + + string toRun = Command + .Replace("%s",request.Start.ToString(TimeFormat)) + .Replace("%e",request.End.ToString(TimeFormat)) + .Replace("%d",workingDirectory.FullName); + + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Running Process:" + toRun)); + + var p = Process.Start(toRun); + p.WaitForExit(); + + listener.OnNotify(this,new NotifyEventArgs( p.ExitCode == 0 ? ProgressEventType.Information : ProgressEventType.Warning , "Process exited with code " + p.ExitCode); + + if(p.ExitCode != 0 && ThrowOnNonZeroExitCode) + throw new Exception("Process exited with code " + p.ExitCode); + + return Chunk; + } + + public override SMIDataChunk TryGetPreview() + { + return null; + } + } +} From df6f2ec2b247faab26c037e0d1d8074884b49fd8 Mon Sep 17 00:00:00 2001 From: tznind Date: Wed, 22 Jul 2020 09:30:03 +0100 Subject: [PATCH 07/28] Fixed typo --- Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs b/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs index 40cc8e12..97dc2ba8 100644 --- a/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs +++ b/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs @@ -75,7 +75,7 @@ public override SMIDataChunk DoGetChunk(ICacheFetchRequest request, IDataLoadEve var p = Process.Start(toRun); p.WaitForExit(); - listener.OnNotify(this,new NotifyEventArgs( p.ExitCode == 0 ? ProgressEventType.Information : ProgressEventType.Warning , "Process exited with code " + p.ExitCode); + listener.OnNotify(this,new NotifyEventArgs( p.ExitCode == 0 ? ProgressEventType.Information : ProgressEventType.Warning , "Process exited with code " + p.ExitCode)); if(p.ExitCode != 0 && ThrowOnNonZeroExitCode) throw new Exception("Process exited with code " + p.ExitCode); From 70dcc8d32321a747283ea82e5042852a3119ab1f Mon Sep 17 00:00:00 2001 From: tznind Date: Wed, 22 Jul 2020 10:00:07 +0100 Subject: [PATCH 08/28] Added tests and captured process output --- .../TestProcessBasedCacheSource.cs | 60 +++++++++++++++++++ .../Cache/Pipeline/ProcessBasedCacheSource.cs | 29 ++++++--- 2 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs diff --git a/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs b/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs new file mode 100644 index 00000000..5d3f7f6f --- /dev/null +++ b/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs @@ -0,0 +1,60 @@ +using MapsDirectlyToDatabaseTable; +using NUnit.Framework; +using Rdmp.Core.Caching.Requests; +using Rdmp.Core.Caching.Requests.FetchRequestProvider; +using Rdmp.Core.Curation; +using Rdmp.Core.Curation.Data; +using Rdmp.Core.Curation.Data.Cache; +using Rdmp.Core.DataFlowPipeline; +using Rdmp.Dicom.Cache.Pipeline; +using ReusableLibraryCode.Checks; +using ReusableLibraryCode.Progress; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using Tests.Common; + +namespace Rdmp.Dicom.Tests +{ + class TestProcessBasedCacheSource : UnitTests + { + [Test] + public void TestWithEcho() + { + var source = new ProcessBasedCacheSource(); + + source.Command = "cmd.exe"; + source.Args = "/c echo Hey Thomas go get %s"; + source.TimeFormat = "dd/MM/yy"; + source.ThrowOnNonZeroExitCode = true; + + // What dates to load + var cp = WhenIHaveA(); + cp.CacheFillProgress = new DateTime(2001,12,24); + cp.SaveToDatabase(); + + // Where to put files + var lmd = cp.LoadProgress.LoadMetadata; + + var dir = new DirectoryInfo(TestContext.CurrentContext.WorkDirectory); + var loadDir = LoadDirectory.CreateDirectoryStructure(dir,"blah",true); + + lmd.LocationOfFlatFiles = loadDir.RootPath.FullName; + lmd.SaveToDatabase(); + + source.PreInitialize(new CacheFetchRequestProvider(cp), new ThrowImmediatelyDataLoadEventListener()); + source.PreInitialize(cp.CatalogueRepository,new ThrowImmediatelyDataLoadEventListener()); + source.PreInitialize(new PermissionWindow(cp.CatalogueRepository),new ThrowImmediatelyDataLoadEventListener()); + + var toMem = new ToMemoryDataLoadEventListener(true); + source.GetChunk(toMem,new GracefulCancellationToken()); + + Assert.Contains("Hey Thomas go get 24/12/01",toMem.GetAllMessagesByProgressEventType()[ProgressEventType.Information].Select(v=>v.Message).ToArray()); + + + + } + } +} diff --git a/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs b/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs index 97dc2ba8..f9e2afae 100644 --- a/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs +++ b/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs @@ -12,12 +12,15 @@ namespace Rdmp.Dicom.Cache.Pipeline { public class ProcessBasedCacheSource : CacheSource { - [DemandsInitialization(@"Process to start. Template with + [DemandsInitialization(@"Process to start (path only)",Mandatory = true)] + public string Command {get;set;} + + [DemandsInitialization(@"Arguments to provide to the Process. Template with %s start time %e end time time to fetch %d directory to put files fetched -Example:. './GetImages.exe ""%s"" ""%e%""'",Mandatory = true)] - public string Command {get;set;} +Example:. './GetImages.exe ""%s"" ""%e%""'")] + public string Args {get;set;} [DemandsInitialization("The datetime format for %s and %e.",Mandatory = true,DefaultValue = "yyyy-MM-dd HH:mm:ss")] public string TimeFormat {get;set;} @@ -61,18 +64,28 @@ public override SMIDataChunk DoGetChunk(ICacheFetchRequest request, IDataLoadEve listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Fetch Start is:" + request.Start)); listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Fetch End is:" + request.End)); - listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Command template is:" + Command)); + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Command is:" + Command)); + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Args template is:" + Args)); listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Datetime format is:" + TimeFormat)); - string toRun = Command + string args = Args .Replace("%s",request.Start.ToString(TimeFormat)) .Replace("%e",request.End.ToString(TimeFormat)) .Replace("%d",workingDirectory.FullName); - listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Running Process:" + toRun)); - - var p = Process.Start(toRun); + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Args resolved is:" + args)); + + var p = new Process(); + p.StartInfo.FileName = Command; + p.StartInfo.Arguments = args; + p.StartInfo.UseShellExecute = false; + p.StartInfo.RedirectStandardOutput = true; + p.OutputDataReceived += (sender, a) => listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,a.Data)); + + p.Start(); + p.BeginOutputReadLine(); + p.WaitForExit(); listener.OnNotify(this,new NotifyEventArgs( p.ExitCode == 0 ? ProgressEventType.Information : ProgressEventType.Warning , "Process exited with code " + p.ExitCode)); From 04f8a53f7ba4660e035c737633e1a143debabd2b Mon Sep 17 00:00:00 2001 From: tznind Date: Wed, 22 Jul 2020 10:03:39 +0100 Subject: [PATCH 09/28] Added linux test case --- .../TestProcessBasedCacheSource.cs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs b/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs index 5d3f7f6f..5cfbc7f9 100644 --- a/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs +++ b/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs @@ -6,6 +6,7 @@ using Rdmp.Core.Curation.Data; using Rdmp.Core.Curation.Data.Cache; using Rdmp.Core.DataFlowPipeline; +using Rdmp.Core.Startup; using Rdmp.Dicom.Cache.Pipeline; using ReusableLibraryCode.Checks; using ReusableLibraryCode.Progress; @@ -25,8 +26,15 @@ public void TestWithEcho() { var source = new ProcessBasedCacheSource(); - source.Command = "cmd.exe"; - source.Args = "/c echo Hey Thomas go get %s"; + if(IsLinux) + { + // TODO + } + else + { + source.Command = "cmd.exe"; + source.Args = "/c echo Hey Thomas go get %s"; + } source.TimeFormat = "dd/MM/yy"; source.ThrowOnNonZeroExitCode = true; @@ -56,5 +64,14 @@ public void TestWithEcho() } + + public static bool IsLinux + { + get + { + int p = (int) Environment.OSVersion.Platform; + return (p == 4) || (p == 6) || (p == 128); + } + } } } From 6077764c4ef4bd969e28729ae7ddb23b57e90b5d Mon Sep 17 00:00:00 2001 From: tznind Date: Wed, 22 Jul 2020 10:07:20 +0100 Subject: [PATCH 10/28] Updated changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8abd1b66..0aabed91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Added new cache source `ProcessBasedCacheSource` that calls out to a remote process + ## [2.1.6] 2020-06-17 ### Fixed From e307076f182a05dd8326d9e073e4295314f3eda1 Mon Sep 17 00:00:00 2001 From: tznind Date: Wed, 22 Jul 2020 10:42:42 +0100 Subject: [PATCH 11/28] Moved into using block --- .../Cache/Pipeline/ProcessBasedCacheSource.cs | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs b/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs index f9e2afae..29e8b8c8 100644 --- a/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs +++ b/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs @@ -76,22 +76,24 @@ public override SMIDataChunk DoGetChunk(ICacheFetchRequest request, IDataLoadEve listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Args resolved is:" + args)); - var p = new Process(); - p.StartInfo.FileName = Command; - p.StartInfo.Arguments = args; - p.StartInfo.UseShellExecute = false; - p.StartInfo.RedirectStandardOutput = true; - p.OutputDataReceived += (sender, a) => listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,a.Data)); + using(var p = new Process()) + { + p.StartInfo.FileName = Command; + p.StartInfo.Arguments = args; + p.StartInfo.UseShellExecute = false; + p.StartInfo.RedirectStandardOutput = true; + p.OutputDataReceived += (sender, a) => listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,a.Data)); - p.Start(); - p.BeginOutputReadLine(); + p.Start(); + p.BeginOutputReadLine(); - p.WaitForExit(); + p.WaitForExit(); - listener.OnNotify(this,new NotifyEventArgs( p.ExitCode == 0 ? ProgressEventType.Information : ProgressEventType.Warning , "Process exited with code " + p.ExitCode)); + listener.OnNotify(this,new NotifyEventArgs( p.ExitCode == 0 ? ProgressEventType.Information : ProgressEventType.Warning , "Process exited with code " + p.ExitCode)); - if(p.ExitCode != 0 && ThrowOnNonZeroExitCode) - throw new Exception("Process exited with code " + p.ExitCode); + if(p.ExitCode != 0 && ThrowOnNonZeroExitCode) + throw new Exception("Process exited with code " + p.ExitCode); + } return Chunk; } From 2958a395473550a1dee4a87806833491ac35cac5 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Wed, 22 Jul 2020 12:40:52 +0100 Subject: [PATCH 12/28] Set dummy command for Linux unit testing --- Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs b/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs index 5cfbc7f9..6410684d 100644 --- a/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs +++ b/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs @@ -27,8 +27,9 @@ public void TestWithEcho() var source = new ProcessBasedCacheSource(); if(IsLinux) - { - // TODO + { + source.Command = "/bin/echo"; + source.Args = "Hey Thomas go get %s"; } else { From c21ac2621567450a7968a460fcf303e915b4ab86 Mon Sep 17 00:00:00 2001 From: tznind Date: Fri, 24 Jul 2020 09:05:50 +0100 Subject: [PATCH 13/28] Changed test to use fork for easier debugging --- Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs b/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs index 6410684d..1e35daea 100644 --- a/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs +++ b/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs @@ -58,7 +58,9 @@ public void TestWithEcho() source.PreInitialize(new PermissionWindow(cp.CatalogueRepository),new ThrowImmediatelyDataLoadEventListener()); var toMem = new ToMemoryDataLoadEventListener(true); - source.GetChunk(toMem,new GracefulCancellationToken()); + var fork = new ForkDataLoadEventListener(toMem,new ThrowImmediatelyDataLoadEventListener(){WriteToConsole = true}); + + source.GetChunk(fork,new GracefulCancellationToken()); Assert.Contains("Hey Thomas go get 24/12/01",toMem.GetAllMessagesByProgressEventType()[ProgressEventType.Information].Select(v=>v.Message).ToArray()); From 514c20fd0e0ec62da54e8d9e8d56e4ceffd3f953 Mon Sep 17 00:00:00 2001 From: Thomas Nind Date: Fri, 24 Jul 2020 10:34:02 +0100 Subject: [PATCH 14/28] added dir to test --- Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs b/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs index 1e35daea..231834b5 100644 --- a/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs +++ b/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs @@ -29,12 +29,12 @@ public void TestWithEcho() if(IsLinux) { source.Command = "/bin/echo"; - source.Args = "Hey Thomas go get %s"; + source.Args = "Hey Thomas go get %s and store in %d"; } else { source.Command = "cmd.exe"; - source.Args = "/c echo Hey Thomas go get %s"; + source.Args = "/c echo Hey Thomas go get %s and store in %d"; } source.TimeFormat = "dd/MM/yy"; source.ThrowOnNonZeroExitCode = true; @@ -62,7 +62,7 @@ public void TestWithEcho() source.GetChunk(fork,new GracefulCancellationToken()); - Assert.Contains("Hey Thomas go get 24/12/01",toMem.GetAllMessagesByProgressEventType()[ProgressEventType.Information].Select(v=>v.Message).ToArray()); + Assert.Contains($"Hey Thomas go get 24/12/01 and store in {Path.Combine(loadDir.Cache.FullName,"ALL")}",toMem.GetAllMessagesByProgressEventType()[ProgressEventType.Information].Select(v=>v.Message).ToArray()); From 964617c6f33b0ff5cbc3291ed302c11b8da77573 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:33:47 +0000 Subject: [PATCH 15/28] Bump Google.Protobuf from 3.12.3 to 3.12.4 Bumps [Google.Protobuf](https://github.com/protocolbuffers/protobuf) from 3.12.3 to 3.12.4. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/master/generate_changelog.py) - [Commits](https://github.com/protocolbuffers/protobuf/commits) Signed-off-by: dependabot-preview[bot] --- Plugin/netcoreapp2.2/netcoreapp2.2.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugin/netcoreapp2.2/netcoreapp2.2.csproj b/Plugin/netcoreapp2.2/netcoreapp2.2.csproj index ce0afd5b..a01f5276 100644 --- a/Plugin/netcoreapp2.2/netcoreapp2.2.csproj +++ b/Plugin/netcoreapp2.2/netcoreapp2.2.csproj @@ -17,7 +17,7 @@ - + From 5e9887d9445d5a79230b3e29f138c11b86ac8870 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 4 Aug 2020 11:45:41 +0000 Subject: [PATCH 16/28] Bump HIC.RDMP.Plugin.Test from 4.1.5 to 4.1.6 (#49) --- Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj b/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj index da694188..d8a8307f 100644 --- a/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj +++ b/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj @@ -37,7 +37,7 @@ - + From 4bd6f3967e6e2da73e9187725e213df7d6323a89 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 4 Aug 2020 12:08:42 +0000 Subject: [PATCH 17/28] Bump HIC.RDMP.Plugin.UI from 4.1.5 to 4.1.6 (#51) --- Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj b/Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj index 9d8670be..d86607b0 100644 --- a/Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj +++ b/Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj @@ -12,7 +12,7 @@ - + From d5f843a9ae479bb591a2c13bccb2f800618919ed Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 4 Aug 2020 12:15:40 +0000 Subject: [PATCH 18/28] Bump HIC.RDMP.Plugin from 4.1.5 to 4.1.6 (#50) --- Packages.md | 2 +- Rdmp.Dicom.Library.nuspec | 2 +- Rdmp.Dicom/Rdmp.Dicom.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Packages.md b/Packages.md index 8c732502..fb93e340 100644 --- a/Packages.md +++ b/Packages.md @@ -10,4 +10,4 @@ | Package | Source Code | Version | License | Purpose | Additional Risk Assessment | | ------- | ------------| --------| ------- | ------- | -------------------------- | | HIC.DicomTypeTranslation | [GitHub](https://github.com/HicServices/DicomTypeTranslation) | [2.3.0](https://www.nuget.org/packages/HIC.DicomTypeTranslation/2.3.0) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Translate dicom types into C# / database types | | -| HIC.RDMP.Plugin | [GitHub](https://github.com/HicServices/RDMP) | [4.1.5](https://www.nuget.org/packages/HIC.RDMP.Plugin/4.1.5) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Interact with RDMP objects, base classes for plugin components etc | | +| HIC.RDMP.Plugin | [GitHub](https://github.com/HicServices/RDMP) | [4.1.6](https://www.nuget.org/packages/HIC.RDMP.Plugin/4.1.6) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Interact with RDMP objects, base classes for plugin components etc | | diff --git a/Rdmp.Dicom.Library.nuspec b/Rdmp.Dicom.Library.nuspec index 2bfae677..a2ddb411 100644 --- a/Rdmp.Dicom.Library.nuspec +++ b/Rdmp.Dicom.Library.nuspec @@ -14,7 +14,7 @@ Copyright 2018-2019 - + diff --git a/Rdmp.Dicom/Rdmp.Dicom.csproj b/Rdmp.Dicom/Rdmp.Dicom.csproj index f1491275..fc53bd56 100644 --- a/Rdmp.Dicom/Rdmp.Dicom.csproj +++ b/Rdmp.Dicom/Rdmp.Dicom.csproj @@ -26,6 +26,6 @@ - + From b06adcb5b7ddfcf8116e96fa93b2054625dbd2e8 Mon Sep 17 00:00:00 2001 From: Thomas Nind Date: Wed, 5 Aug 2020 16:29:21 +0100 Subject: [PATCH 19/28] fix for #52 --- .../PrimaryKeyCollisionIsolationMutilation.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Rdmp.Dicom/PipelineComponents/PrimaryKeyCollisionIsolationMutilation.cs b/Rdmp.Dicom/PipelineComponents/PrimaryKeyCollisionIsolationMutilation.cs index 8c942b16..39fba540 100644 --- a/Rdmp.Dicom/PipelineComponents/PrimaryKeyCollisionIsolationMutilation.cs +++ b/Rdmp.Dicom/PipelineComponents/PrimaryKeyCollisionIsolationMutilation.cs @@ -60,10 +60,11 @@ public void Check(ICheckNotifier notifier) //if there are multiple tables then we must know how to join them if (TablesToIsolate.Length >1 && TablesToIsolate.Count(t => t.IsPrimaryExtractionTable) != 1) { + var primaryTables = TablesToIsolate.Where(t => t.IsPrimaryExtractionTable).ToArray(); + notifier.OnCheckPerformed( new CheckEventArgs( - "There are " + TablesToIsolate.Length + - " tables to operate on but none are marked IsPrimaryExtractionTable. This should be set on the top level table e.g. Study", + $"There are {TablesToIsolate.Length} tables to operate on but {primaryTables.Length} are marked IsPrimaryExtractionTable ({string.Join(",",primaryTables.Select(t=>t.Name))}). This should be set on a single top level table only e.g. Study", CheckResult.Fail)); } From 7652297ce7f9c09711b98c79f0a038025d377e58 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 7 Aug 2020 07:52:00 +0000 Subject: [PATCH 20/28] Bump Microsoft.NET.Test.Sdk from 16.6.1 to 16.7.0 Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 16.6.1 to 16.7.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Commits](https://github.com/microsoft/vstest/compare/v16.6.1...v16.7.0) Signed-off-by: dependabot-preview[bot] --- Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj b/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj index d8a8307f..3a1614d2 100644 --- a/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj +++ b/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj @@ -38,7 +38,7 @@ - + From 79c089931981e5c38eeaa1e781af4f9c4136b6be Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2020 14:26:40 +0000 Subject: [PATCH 21/28] Bump System.Data.SqlClient from 4.8.1 to 4.8.2 Bumps [System.Data.SqlClient](https://github.com/dotnet/corefx) from 4.8.1 to 4.8.2. - [Release notes](https://github.com/dotnet/corefx/releases) - [Commits](https://github.com/dotnet/corefx/commits) Signed-off-by: dependabot-preview[bot] --- Plugin/netcoreapp2.2/netcoreapp2.2.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugin/netcoreapp2.2/netcoreapp2.2.csproj b/Plugin/netcoreapp2.2/netcoreapp2.2.csproj index a01f5276..06bfc722 100644 --- a/Plugin/netcoreapp2.2/netcoreapp2.2.csproj +++ b/Plugin/netcoreapp2.2/netcoreapp2.2.csproj @@ -22,7 +22,7 @@ - + From 7acb15f4dd2348a820367731ecb74923bda566c3 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Fri, 14 Aug 2020 09:47:18 +0100 Subject: [PATCH 22/28] Allow the PACS to send us lossy-compressed images if it has them, rather than fail the transfer --- CHANGELOG.md | 2 ++ Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0aabed91..96aa51dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Allow the PACS to send us lossy compressed versions if it wants, otherwise we won't be able to receive anything it has in that format + ### Added - Added new cache source `ProcessBasedCacheSource` that calls out to a remote process diff --git a/Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs b/Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs index a049e66e..8d41157f 100644 --- a/Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs +++ b/Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs @@ -27,6 +27,12 @@ public class CachingSCP : DicomService, IDicomServiceProvider, IDicomCStoreProvi DicomTransferSyntax.JPEGProcess14SV1, DicomTransferSyntax.JPEGProcess14, DicomTransferSyntax.RLELossless, + + // Lossy - if that's all the PACS has, that's all it can give us + DicomTransferSyntax.JPEGLSNearLossless, + DicomTransferSyntax.JPEG2000Lossy, + DicomTransferSyntax.JPEGProcess1, + DicomTransferSyntax.JPEGProcess2_4, // Uncompressed DicomTransferSyntax.ExplicitVRLittleEndian, From 424cdbf2f6408ea398d2815f59964f0cc4b12873 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Fri, 14 Aug 2020 09:54:29 +0100 Subject: [PATCH 23/28] Also allow video (MPEG, HEVC) formats in case the PACS gets really ambitious --- Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs b/Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs index 8d41157f..931c72d4 100644 --- a/Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs +++ b/Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs @@ -33,6 +33,17 @@ public class CachingSCP : DicomService, IDicomServiceProvider, IDicomCStoreProvi DicomTransferSyntax.JPEG2000Lossy, DicomTransferSyntax.JPEGProcess1, DicomTransferSyntax.JPEGProcess2_4, + + // Also allow video files, just in case + DicomTransferSyntax.HEVCH265Main10ProfileLevel51, + DicomTransferSyntax.HEVCH265MainProfileLevel51, + DicomTransferSyntax.MPEG2, + DicomTransferSyntax.MPEG2MainProfileHighLevel, + DicomTransferSyntax.MPEG4AVCH264BDCompatibleHighProfileLevel41, + DicomTransferSyntax.MPEG4AVCH264HighProfileLevel41, + DicomTransferSyntax.MPEG4AVCH264HighProfileLevel42For2DVideo, + DicomTransferSyntax.MPEG4AVCH264HighProfileLevel42For3DVideo, + DicomTransferSyntax.MPEG4AVCH264StereoHighProfileLevel42, // Uncompressed DicomTransferSyntax.ExplicitVRLittleEndian, From 905ab61fe1af9a576c8680dc1846529bee98fe18 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2020 09:35:25 +0000 Subject: [PATCH 24/28] Bump HIC.RDMP.Plugin.UI from 4.1.6 to 4.1.7 Bumps [HIC.RDMP.Plugin.UI](https://github.com/HicServices/RDMP) from 4.1.6 to 4.1.7. - [Release notes](https://github.com/HicServices/RDMP/releases) - [Changelog](https://github.com/HicServices/RDMP/blob/develop/CHANGELOG.md) - [Commits](https://github.com/HicServices/RDMP/compare/v4.1.6...v4.1.7) Signed-off-by: dependabot-preview[bot] --- Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj b/Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj index d86607b0..174c5f80 100644 --- a/Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj +++ b/Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj @@ -12,7 +12,7 @@ - + From 6308db26f59c73554337264d6a50f3fd2ab8919f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2020 09:35:31 +0000 Subject: [PATCH 25/28] Bump HIC.RDMP.Plugin.Test from 4.1.6 to 4.1.7 Bumps [HIC.RDMP.Plugin.Test](https://github.com/HicServices/RDMP) from 4.1.6 to 4.1.7. - [Release notes](https://github.com/HicServices/RDMP/releases) - [Changelog](https://github.com/HicServices/RDMP/blob/develop/CHANGELOG.md) - [Commits](https://github.com/HicServices/RDMP/compare/v4.1.6...v4.1.7) Signed-off-by: dependabot-preview[bot] --- Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj b/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj index 3a1614d2..dbd93a9b 100644 --- a/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj +++ b/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj @@ -37,7 +37,7 @@ - + From baa9b394eb62e84ae93ea765553de7c04818f820 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2020 15:27:35 +0000 Subject: [PATCH 26/28] Bump HIC.RDMP.Plugin from 4.1.6 to 4.1.7 (#57) --- Packages.md | 2 +- Rdmp.Dicom.Library.nuspec | 2 +- Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs | 3 --- Rdmp.Dicom/Rdmp.Dicom.csproj | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Packages.md b/Packages.md index fb93e340..425b02d5 100644 --- a/Packages.md +++ b/Packages.md @@ -10,4 +10,4 @@ | Package | Source Code | Version | License | Purpose | Additional Risk Assessment | | ------- | ------------| --------| ------- | ------- | -------------------------- | | HIC.DicomTypeTranslation | [GitHub](https://github.com/HicServices/DicomTypeTranslation) | [2.3.0](https://www.nuget.org/packages/HIC.DicomTypeTranslation/2.3.0) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Translate dicom types into C# / database types | | -| HIC.RDMP.Plugin | [GitHub](https://github.com/HicServices/RDMP) | [4.1.6](https://www.nuget.org/packages/HIC.RDMP.Plugin/4.1.6) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Interact with RDMP objects, base classes for plugin components etc | | +| HIC.RDMP.Plugin | [GitHub](https://github.com/HicServices/RDMP) | [4.1.7](https://www.nuget.org/packages/HIC.RDMP.Plugin/4.1.7) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Interact with RDMP objects, base classes for plugin components etc | | diff --git a/Rdmp.Dicom.Library.nuspec b/Rdmp.Dicom.Library.nuspec index a2ddb411..a7ed2a4e 100644 --- a/Rdmp.Dicom.Library.nuspec +++ b/Rdmp.Dicom.Library.nuspec @@ -14,7 +14,7 @@ Copyright 2018-2019 - + diff --git a/Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs b/Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs index 375b21e6..787c4770 100644 --- a/Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs +++ b/Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs @@ -170,9 +170,6 @@ public IPipelineUseCase GetDesignTimePipelineUseCase(RequiredPropertyInfo proper #region Process Results Of Pipeline Read public DataTable ProcessPipelineData(DataTable toProcess, IDataLoadEventListener listener,GracefulCancellationToken cancellationToken) { - - //todo: This really shouldn't be needed surely - MySql.Data.MySqlClient.MySqlConnection.ClearAllPools(); MySqlBulkCopy.BulkInsertBatchTimeoutInSeconds = int.MaxValue; //forever _sw.Start(); diff --git a/Rdmp.Dicom/Rdmp.Dicom.csproj b/Rdmp.Dicom/Rdmp.Dicom.csproj index fc53bd56..63ef5a5f 100644 --- a/Rdmp.Dicom/Rdmp.Dicom.csproj +++ b/Rdmp.Dicom/Rdmp.Dicom.csproj @@ -26,6 +26,6 @@ - + From c313c8b860a07153ff75e06036186b217998394e Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Mon, 17 Aug 2020 09:16:48 +0100 Subject: [PATCH 27/28] Update CHANGELOG, SharedAssemblyInfo for 2.1.7 release --- CHANGELOG.md | 5 +++++ SharedAssemblyInfo.cs | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96aa51dd..41507201 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.1.7] 2020-08-17 + +### Fixed + - Allow the PACS to send us lossy compressed versions if it wants, otherwise we won't be able to receive anything it has in that format ### Added +- Accept video (MPEG/HEVC) content if the PACS offers it - Added new cache source `ProcessBasedCacheSource` that calls out to a remote process ## [2.1.6] 2020-06-17 diff --git a/SharedAssemblyInfo.cs b/SharedAssemblyInfo.cs index b0952eb9..15c35b7e 100644 --- a/SharedAssemblyInfo.cs +++ b/SharedAssemblyInfo.cs @@ -7,6 +7,6 @@ [assembly: AssemblyCulture("")] // These should be replaced with correct values by the release process -[assembly: AssemblyVersion("2.1.6")] -[assembly: AssemblyFileVersion("2.1.6")] -[assembly: AssemblyInformationalVersion("2.1.6")] +[assembly: AssemblyVersion("2.1.7")] +[assembly: AssemblyFileVersion("2.1.7")] +[assembly: AssemblyInformationalVersion("2.1.7")] From 7cd096914ba2137799afd5d2c8de63d373b73ac2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 08:19:38 +0000 Subject: [PATCH 28/28] Bump Google.Protobuf from 3.12.4 to 3.13.0 Bumps [Google.Protobuf](https://github.com/protocolbuffers/protobuf) from 3.12.4 to 3.13.0. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/master/generate_changelog.py) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.12.4...v3.13.0) Signed-off-by: dependabot-preview[bot] --- Plugin/netcoreapp2.2/netcoreapp2.2.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugin/netcoreapp2.2/netcoreapp2.2.csproj b/Plugin/netcoreapp2.2/netcoreapp2.2.csproj index 06bfc722..dc7d84b5 100644 --- a/Plugin/netcoreapp2.2/netcoreapp2.2.csproj +++ b/Plugin/netcoreapp2.2/netcoreapp2.2.csproj @@ -17,7 +17,7 @@ - +