From 2c67d6f80f93c46215c90653d09bc296a17c4ca3 Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Thu, 2 Jul 2020 11:58:01 -0400 Subject: [PATCH 01/14] Update AttributesUtil.java --- .../healthcare/imaging/dicomadapter/AttributesUtil.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java b/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java index 91928961..94cfdab7 100644 --- a/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java +++ b/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java @@ -42,6 +42,8 @@ public class AttributesUtil { private static final int INSTANCES_LIMIT = 50000; private static final int STUDIES_SERIES_LIMIT = 5000; + + private static final String FUZZY_MATCHING = "true"; public static String getTagValue(JSONObject json, String tag) throws JSONException { JSONObject jsonTag = json.getJSONObject(tag); @@ -139,6 +141,10 @@ public static String attributesToQidoPath(Attributes attrs, String... includeFie qidoPath.append("includefield=" + includeField + "&"); } } + + if (FUZZY_MATCHING == "true") { + qidoPath.append("fuzzymatching=true" + "&"); + } for (int keyTag : nonEmptyKeys) { // non-string type search keys don't seem to exist From 2a12abeca8f059cba25f524ef50fa8a98963b18c Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Thu, 2 Jul 2020 12:33:51 -0400 Subject: [PATCH 02/14] Update AttributesUtil.java --- .../imaging/dicomadapter/AttributesUtil.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java b/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java index 94cfdab7..7335313d 100644 --- a/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java +++ b/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java @@ -120,9 +120,19 @@ public static String attributesToQidoPath(Attributes attrs, String... includeFie switch (attrs.getString(Tag.QueryRetrieveLevel)) { case "STUDY": qidoPath.append("studies?limit=" + STUDIES_SERIES_LIMIT + "&"); + + if (FUZZY_MATCHING == "true") { + qidoPath.append("fuzzymatching=true" + "&"); + } + break; case "SERIES": qidoPath.append("series?limit=" + STUDIES_SERIES_LIMIT + "&"); + + if (FUZZY_MATCHING == "true") { + qidoPath.append("fuzzymatching=true" + "&"); + } + break; case "IMAGE": qidoPath.append("instances?limit=" + INSTANCES_LIMIT + "&"); @@ -141,10 +151,6 @@ public static String attributesToQidoPath(Attributes attrs, String... includeFie qidoPath.append("includefield=" + includeField + "&"); } } - - if (FUZZY_MATCHING == "true") { - qidoPath.append("fuzzymatching=true" + "&"); - } for (int keyTag : nonEmptyKeys) { // non-string type search keys don't seem to exist From 7e72202eae56d738db65c34ab1e63c8f5c4afbf7 Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Mon, 6 Jul 2020 13:20:43 -0400 Subject: [PATCH 03/14] Revoked changes as it is not required here. --- .../imaging/dicomadapter/AttributesUtil.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java b/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java index 7335313d..3c7b1f3b 100644 --- a/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java +++ b/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java @@ -120,19 +120,9 @@ public static String attributesToQidoPath(Attributes attrs, String... includeFie switch (attrs.getString(Tag.QueryRetrieveLevel)) { case "STUDY": qidoPath.append("studies?limit=" + STUDIES_SERIES_LIMIT + "&"); - - if (FUZZY_MATCHING == "true") { - qidoPath.append("fuzzymatching=true" + "&"); - } - break; case "SERIES": qidoPath.append("series?limit=" + STUDIES_SERIES_LIMIT + "&"); - - if (FUZZY_MATCHING == "true") { - qidoPath.append("fuzzymatching=true" + "&"); - } - break; case "IMAGE": qidoPath.append("instances?limit=" + INSTANCES_LIMIT + "&"); From 6f40a19091383a21ea23dcf319a9b13ca42feb1f Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Mon, 6 Jul 2020 13:26:52 -0400 Subject: [PATCH 04/14] Update CFindService.java Added changes to receive CFIND flags from ImportAdapter.java to construct RESTful URL with fuzzymatching --- .../healthcare/imaging/dicomadapter/CFindService.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindService.java b/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindService.java index 1fdf5bb9..a56247df 100644 --- a/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindService.java +++ b/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindService.java @@ -45,10 +45,12 @@ public class CFindService extends BasicCFindSCP { private static Logger log = LoggerFactory.getLogger(CFindService.class); private final IDicomWebClient dicomWebClient; + private final Flags cFINDFlags; - CFindService(IDicomWebClient dicomWebClient) { + CFindService(IDicomWebClient dicomWebClient, Flags flags) { super(UID.StudyRootQueryRetrieveInformationModelFIND); this.dicomWebClient = dicomWebClient; + this.cFINDFlags = flags; } private static HashMap uniqueResults(List responses) { @@ -115,6 +117,9 @@ public void run() { if (canceled) { throw new CancellationException(); } + if (cFINDFlags.fuzzyMatching) { + qidoPath += "fuzzymatching=true" + "&"; + } log.info("CFind QidoPath: " + qidoPath); MonitoringService.addEvent(Event.CFIND_QIDORS_REQUEST); JSONArray qidoResult = dicomWebClient.qidoRs(qidoPath); @@ -157,4 +162,4 @@ private void sendErrorResponse(int status, String message) { as.tryWriteDimseRSP(pc, cmdAttr); } } -} \ No newline at end of file +} From 095b2104d60b2c8a5ae8d9f7d5f80342d28da4d2 Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Mon, 6 Jul 2020 13:28:35 -0400 Subject: [PATCH 05/14] Update CFindService.java Code alignment --- .../cloud/healthcare/imaging/dicomadapter/CFindService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindService.java b/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindService.java index a56247df..446ef449 100644 --- a/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindService.java +++ b/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindService.java @@ -118,8 +118,8 @@ public void run() { throw new CancellationException(); } if (cFINDFlags.fuzzyMatching) { - qidoPath += "fuzzymatching=true" + "&"; - } + qidoPath += "fuzzymatching=true" + "&"; + } log.info("CFind QidoPath: " + qidoPath); MonitoringService.addEvent(Event.CFIND_QIDORS_REQUEST); JSONArray qidoResult = dicomWebClient.qidoRs(qidoPath); From a7816fc6fd8986323a978182f837122e6c61d8d6 Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Mon, 6 Jul 2020 13:30:26 -0400 Subject: [PATCH 06/14] Update ImportAdapter.java Added changes to send CFIND flags to CFindService.java to construct RESTful URL with fuzzymatching --- .../cloud/healthcare/imaging/dicomadapter/ImportAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/ImportAdapter.java b/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/ImportAdapter.java index ff767da5..c1b604af 100644 --- a/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/ImportAdapter.java +++ b/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/ImportAdapter.java @@ -111,7 +111,7 @@ public static void main(String[] args) throws IOException, GeneralSecurityExcept // Handle C-FIND IDicomWebClient dicomWebClient = new DicomWebClient(requestFactory, flags.dicomwebAddress, STUDIES); - CFindService cFindService = new CFindService(dicomWebClient); + CFindService cFindService = new CFindService(dicomWebClient, flags); serviceRegistry.addDicomService(cFindService); // Handle C-MOVE From 3e9a940af0a92b5b0ba267582d93ebbb9d9aebb8 Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Mon, 6 Jul 2020 13:33:42 -0400 Subject: [PATCH 07/14] Update Flags.java Added fuzzymatching attribute to perform wildcard search on patient names. --- .../google/cloud/healthcare/imaging/dicomadapter/Flags.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/Flags.java b/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/Flags.java index 818df926..825caa75 100644 --- a/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/Flags.java +++ b/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/Flags.java @@ -142,6 +142,12 @@ public class Flags { description = "Transfer Syntax to convert instances to during C-STORE upload. See Readme for list of supported syntaxes." ) String transcodeToSyntax = ""; + + @Parameter( + names = {"--fuzzy_matching"}, + description = "negotiate fuzzy semantic person name attribute matching. False by default." + ) + Boolean fuzzyMatching = false; public Flags() { } From 9e0a97dfc4651ebceed81f913ed0980599f6abb0 Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Mon, 6 Jul 2020 13:36:36 -0400 Subject: [PATCH 08/14] Update AttributesUtil.java --- .../cloud/healthcare/imaging/dicomadapter/AttributesUtil.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java b/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java index 3c7b1f3b..91928961 100644 --- a/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java +++ b/util/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/AttributesUtil.java @@ -42,8 +42,6 @@ public class AttributesUtil { private static final int INSTANCES_LIMIT = 50000; private static final int STUDIES_SERIES_LIMIT = 5000; - - private static final String FUZZY_MATCHING = "true"; public static String getTagValue(JSONObject json, String tag) throws JSONException { JSONObject jsonTag = json.getJSONObject(tag); From 411efa0361e82b81d0348383a3c01b448ba9e4a2 Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Mon, 6 Jul 2020 13:51:56 -0400 Subject: [PATCH 09/14] Update CFindServiceTest.java Sending null flag to CFindService upon testing --- .../cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java b/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java index 13250af7..d346ac4c 100644 --- a/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java +++ b/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java @@ -167,7 +167,7 @@ private int createDicomServer(IDicomWebClient dicomWebClient) throws Exception { DicomServiceRegistry serviceRegistry = new DicomServiceRegistry(); serviceRegistry.addDicomService(new BasicCEchoSCP()); - CFindService cFindService = new CFindService(dicomWebClient); + CFindService cFindService = new CFindService(dicomWebClient, null); serviceRegistry.addDicomService(cFindService); Device serverDevice = DeviceUtil.createServerDevice(serverAET, serverPort, serviceRegistry); serverDevice.bindConnections(); From 2e881f869686f150ffc2e768fcfa6bb37f07aa50 Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Mon, 6 Jul 2020 13:53:17 -0400 Subject: [PATCH 10/14] Update CFindService.java added null check on flags --- .../cloud/healthcare/imaging/dicomadapter/CFindService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindService.java b/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindService.java index 446ef449..262a990e 100644 --- a/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindService.java +++ b/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindService.java @@ -117,7 +117,7 @@ public void run() { if (canceled) { throw new CancellationException(); } - if (cFINDFlags.fuzzyMatching) { + if (cFINDFlags != null && cFINDFlags.fuzzyMatching) { qidoPath += "fuzzymatching=true" + "&"; } log.info("CFind QidoPath: " + qidoPath); From 5ccd1a39c43d3d78e6b0e8ec0a16d9d9fa78be9d Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Mon, 6 Jul 2020 14:38:52 -0400 Subject: [PATCH 11/14] Update CFindServiceTest.java Added empty flag for CFIND test case. --- .../healthcare/imaging/dicomadapter/CFindServiceTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java b/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java index d346ac4c..bad6344a 100644 --- a/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java +++ b/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java @@ -166,8 +166,8 @@ private int createDicomServer(IDicomWebClient dicomWebClient) throws Exception { int serverPort = PortUtil.getFreePort(); DicomServiceRegistry serviceRegistry = new DicomServiceRegistry(); serviceRegistry.addDicomService(new BasicCEchoSCP()); - - CFindService cFindService = new CFindService(dicomWebClient, null); + Flags flags = new Flags(); + CFindService cFindService = new CFindService(dicomWebClient, flags); serviceRegistry.addDicomService(cFindService); Device serverDevice = DeviceUtil.createServerDevice(serverAET, serverPort, serviceRegistry); serverDevice.bindConnections(); From 567129d7a11d0ecadcaf5bd6d92c612b4724bfd2 Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Thu, 9 Jul 2020 11:16:27 -0400 Subject: [PATCH 12/14] Update CFindServiceTest.java Added Unit test for fuzzy matching. --- .../dicomadapter/CFindServiceTest.java | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java b/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java index bad6344a..9d01e1cb 100644 --- a/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java +++ b/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java @@ -47,6 +47,9 @@ public final class CFindServiceTest { final static String serverHostname = "localhost"; final static String clientAET = "CLIENT"; + + // Flags + Flags cFINDFlags = new Flags(); // Client properties. ApplicationEntity clientAE; @@ -117,6 +120,28 @@ public JSONArray qidoRs(String path) throws DicomWebException { } }, Status.NotAuthorized); } + + @Test + public void testCFindService_withFuzzyMatching() throws Exception { + cFINDFlags.fuzzyMatching = true; + basicCFindServiceTest(new TestUtils.DicomWebClientTestBase() { + @Override + public JSONArray qidoRs(String path) throws DicomWebException { + throw new DicomWebException("test-generated exception", Status.InvalidAttributeValue); + } + }, Status.InvalidAttributeValue); + } + + @Test + public void testCFindService_withoutFuzzyMatching() throws Exception { + cFINDFlags.fuzzyMatching = false; + basicCFindServiceTest(new TestUtils.DicomWebClientTestBase() { + @Override + public JSONArray qidoRs(String path) throws DicomWebException { + throw new DicomWebException("test-generated exception", Status.InvalidAttributeValue); + } + }, Status.InvalidAttributeValue); + } public void basicCFindServiceTest(IDicomWebClient serverDicomWebClient, int expectedStatus) throws Exception { @@ -166,8 +191,7 @@ private int createDicomServer(IDicomWebClient dicomWebClient) throws Exception { int serverPort = PortUtil.getFreePort(); DicomServiceRegistry serviceRegistry = new DicomServiceRegistry(); serviceRegistry.addDicomService(new BasicCEchoSCP()); - Flags flags = new Flags(); - CFindService cFindService = new CFindService(dicomWebClient, flags); + CFindService cFindService = new CFindService(dicomWebClient, cFINDFlags); serviceRegistry.addDicomService(cFindService); Device serverDevice = DeviceUtil.createServerDevice(serverAET, serverPort, serviceRegistry); serverDevice.bindConnections(); From bc47573534be6372652b9bf5e67376707b10fe46 Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Thu, 9 Jul 2020 15:31:31 -0400 Subject: [PATCH 13/14] Update CFindServiceTest.java added assertThat for with and without fuzzymatching --- .../imaging/dicomadapter/CFindServiceTest.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java b/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java index 9d01e1cb..52c79a5a 100644 --- a/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java +++ b/import/src/test/java/com/google/cloud/healthcare/imaging/dicomadapter/CFindServiceTest.java @@ -14,6 +14,8 @@ package com.google.cloud.healthcare.imaging.dicomadapter; +import static com.google.common.truth.Truth.assertThat; + import com.google.cloud.healthcare.IDicomWebClient; import com.google.cloud.healthcare.LogUtil; import com.google.cloud.healthcare.imaging.dicomadapter.util.DimseRSPAssert; @@ -127,9 +129,12 @@ public void testCFindService_withFuzzyMatching() throws Exception { basicCFindServiceTest(new TestUtils.DicomWebClientTestBase() { @Override public JSONArray qidoRs(String path) throws DicomWebException { - throw new DicomWebException("test-generated exception", Status.InvalidAttributeValue); + assertThat(path).contains("fuzzymatching=true"); + JSONArray instances = new JSONArray(); + instances.put(TestUtils.dummyQidorsInstance()); + return instances; } - }, Status.InvalidAttributeValue); + }, Status.Success); } @Test @@ -138,9 +143,12 @@ public void testCFindService_withoutFuzzyMatching() throws Exception { basicCFindServiceTest(new TestUtils.DicomWebClientTestBase() { @Override public JSONArray qidoRs(String path) throws DicomWebException { - throw new DicomWebException("test-generated exception", Status.InvalidAttributeValue); + assertThat(path).doesNotContain("fuzzymatching"); + JSONArray instances = new JSONArray(); + instances.put(TestUtils.dummyQidorsInstance()); + return instances; } - }, Status.InvalidAttributeValue); + }, Status.Success); } public void basicCFindServiceTest(IDicomWebClient serverDicomWebClient, From fb205759fe02ee0851204dee178244e9ca023292 Mon Sep 17 00:00:00 2001 From: satheesh09 <67746047+satheesh09@users.noreply.github.com> Date: Thu, 9 Jul 2020 17:18:56 -0400 Subject: [PATCH 14/14] Update ImportAdapter.java --- .../cloud/healthcare/imaging/dicomadapter/ImportAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/ImportAdapter.java b/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/ImportAdapter.java index 6bc6a006..53bf9454 100644 --- a/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/ImportAdapter.java +++ b/import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/ImportAdapter.java @@ -112,7 +112,7 @@ public static void main(String[] args) throws IOException, GeneralSecurityExcept // Handle C-FIND IDicomWebClient dicomWebClient = - new DicomWebClient(requestFactory, flags.dicomwebAddress, STUDIES); + new DicomWebClient(requestFactory, dicomwebAddress, STUDIES); CFindService cFindService = new CFindService(dicomWebClient, flags); serviceRegistry.addDicomService(cFindService);