Fix to code delta CSV encoding

This commit is contained in:
James Agnew 2020-02-03 20:56:10 -05:00
parent 2575dd815b
commit 4229645602
4 changed files with 117 additions and 8 deletions

View File

@ -608,7 +608,7 @@
<scope>compile</scope>
</dependency>
</dependencies>
</dependencies>
<properties>

View File

@ -53,9 +53,14 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.trim;
public class TerminologyUploaderProvider extends BaseJpaProvider {
@ -226,9 +231,9 @@ public class TerminologyUploaderProvider extends BaseJpaProvider {
b.append(ConceptHandler.DISPLAY);
b.append("\n");
for (Map.Entry<String, String> nextEntry : codes.entrySet()) {
b.append(nextEntry.getKey());
b.append(csvEscape(nextEntry.getKey()));
b.append(",");
b.append(defaultString(nextEntry.getValue()));
b.append(csvEscape(nextEntry.getValue()));
b.append("\n");
}
byte[] bytes = b.toString().getBytes(Charsets.UTF_8);
@ -245,9 +250,9 @@ public class TerminologyUploaderProvider extends BaseJpaProvider {
b.append(HierarchyHandler.PARENT);
b.append("\n");
for (Map.Entry<String, String> nextEntry : codeToParentCodes.entries()) {
b.append(nextEntry.getKey());
b.append(csvEscape(nextEntry.getKey()));
b.append(",");
b.append(defaultString(nextEntry.getValue()));
b.append(csvEscape(nextEntry.getValue()));
b.append("\n");
}
byte[] bytes = b.toString().getBytes(Charsets.UTF_8);
@ -354,7 +359,6 @@ public class TerminologyUploaderProvider extends BaseJpaProvider {
return retVal;
}
private static class FileBackedFileDescriptor implements ITermLoaderSvc.FileDescriptor {
private final File myNextFile;
@ -376,4 +380,13 @@ public class TerminologyUploaderProvider extends BaseJpaProvider {
}
}
}
private static String csvEscape(String theValue) {
return '"' +
theValue
.replace("\"", "\"\"")
.replace("\n", "\\n")
.replace("\r", "") +
'"';
}
}

View File

@ -1,8 +1,12 @@
package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.TestUtil;
@ -21,6 +25,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@ -253,6 +258,67 @@ public class TerminologyUploaderProviderR4Test extends BaseResourceProviderR4Tes
);
}
@Test
public void testApplyDeltaAdd_UsingCodeSystemWithComma() throws IOException {
// Create initial codesystem
{
CodeSystem codeSystem = new CodeSystem();
codeSystem.setContent(CodeSystem.CodeSystemContentMode.NOTPRESENT);
codeSystem.setUrl("https://good.health");
LoggingInterceptor interceptor = new LoggingInterceptor(true);
ourClient.registerInterceptor(interceptor);
ourClient
.create()
.resource(codeSystem)
.execute();
ourClient.unregisterInterceptor(interceptor);
}
// Add a child with a really long description
Parameters outcome;
{
Parameters inputBundle = loadResourceFromClasspath(Parameters.class, "/term-delta-json.json");
LoggingInterceptor interceptor = new LoggingInterceptor(true);
ourClient.registerInterceptor(interceptor);
outcome = ourClient
.operation()
.onType(CodeSystem.class)
.named(JpaConstants.OPERATION_APPLY_CODESYSTEM_DELTA_ADD)
.withParameters(inputBundle)
.execute();
ourClient.unregisterInterceptor(interceptor);
}
String encoded = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome);
ourLog.info(encoded);
assertThat(encoded, stringContainsInOrder(
"\"name\": \"conceptCount\"",
"\"valueInteger\": 2",
"\"name\": \"target\"",
"\"reference\": \"CodeSystem/"
));
assertHierarchyContains(
"1111222233 seq=0",
" 1111222234 seq=0"
);
runInTransaction(()->{
TermCodeSystem codeSystem = myTermCodeSystemDao.findByCodeSystemUri("https://good.health");
TermCodeSystemVersion version = codeSystem.getCurrentVersion();
TermConcept code = myTermConceptDao.findByCodeSystemAndCode(version, "1111222233").get();
assertEquals("Some label for the parent - with a dash too", code.getDisplay());
code = myTermConceptDao.findByCodeSystemAndCode(version, "1111222234").get();
assertEquals("Some very very very very very looooooong child label with a coma, another one, one more, more and final one", code.getDisplay());
});
}
@Test
public void testApplyDeltaAdd_UsingCodeSystemWithVeryLongDescription() {

View File

@ -0,0 +1,30 @@
{
"resourceType": "Parameters",
"parameter": [
{
"name": "system",
"valueUri": "https://good.health"
},
{
"name": "codeSystem",
"resource": {
"resourceType": "CodeSystem",
"status": "active",
"content": "not-present",
"url": "https://good.health",
"concept": [
{
"code": "1111222233",
"display": "Some label for the parent - with a dash too",
"concept": [
{
"code": "1111222234",
"display": "Some very very very very very looooooong child label with a coma, another one, one more, more and final one"
}
]
}
]
}
}
]
}